private int maxDropDownItems;
private bool sorted;
private string valueMember;
+ private DataGridViewComboBoxColumn owningColumnTemlate;
public DataGridViewComboBoxCell () : base() {
autoComplete = true;
items = new ObjectCollection(this);
maxDropDownItems = 8;
sorted = false;
+ owningColumnTemlate = null;
}
[DefaultValue (true)]
get {
if (DataGridView != null && DataGridView.BindingContext != null
&& DataSource != null && !String.IsNullOrEmpty (ValueMember)) {
- items.Clear ();
+ items.ClearInternal ();
CurrencyManager dataManager = (CurrencyManager) DataGridView.BindingContext[DataSource];
if (dataManager != null && dataManager.Count > 0) {
foreach (object item in dataManager.List)
- items.Add (item);
+ items.AddInternal (item);
}
}
get { return typeof(string); }
}
+ // Valid only for template Cells and used as a bridge to push items
+ internal DataGridViewComboBoxColumn OwningColumnTemplate {
+ get { return owningColumnTemlate; }
+ set { owningColumnTemlate = value; }
+ }
+
public override object Clone () {
DataGridViewComboBoxCell cell = (DataGridViewComboBoxCell) base.Clone();
cell.autoComplete = this.autoComplete;
cell.displayStyleForCurrentCellOnly = this.displayStyleForCurrentCellOnly;
cell.dropDownWidth = this.dropDownWidth;
cell.flatStyle = this.flatStyle;
- cell.items.AddRange(this.items);
+ cell.items.AddRangeInternal(this.items);
cell.maxDropDownItems = this.maxDropDownItems;
cell.sorted = this.sorted;
return cell;
editingControl.DisplayMember = DisplayMember;
} else {
editingControl.Items.AddRange (this.Items);
+ if (FormattedValue != null && editingControl.Items.IndexOf (FormattedValue) != -1)
+ editingControl.SelectedItem = FormattedValue;
}
}
+ internal void SyncItems ()
+ {
+ if (DataSource != null || OwningColumnTemplate == null)
+ return;
+
+ if (OwningColumnTemplate.DataGridView != null) {
+ DataGridViewComboBoxEditingControl editor = OwningColumnTemplate.DataGridView.EditingControl
+ as DataGridViewComboBoxEditingControl;
+ if (editor != null) {
+ object selectedItem = editor.SelectedItem;
+ editor.Items.Clear ();
+ editor.Items.AddRange (items);
+ if (editor.Items.IndexOf (selectedItem) != -1)
+ editor.SelectedItem = selectedItem;
+ }
+ }
+
+ // Push the new items to the column
+ OwningColumnTemplate.SyncItems (Items);
+ }
+
public override bool KeyEntersEditMode (KeyEventArgs e)
{
if (e.KeyCode == Keys.Space)
return button_area;
}
+ // IMPORTANT: Only call the internal methods from within DataGridViewComboBoxCell
+ // for adding/removing/clearing because the other methods invoke an update of the
+ // column items collection and you might end up in an endless loop.
+ //
[ListBindable (false)]
public class ObjectCollection : IList, ICollection, IEnumerable {
private ArrayList list;
+ private DataGridViewComboBoxCell owner;
- //private DataGridViewComboBoxCell owner;
-
- public ObjectCollection (DataGridViewComboBoxCell owner) {
- //this.owner = owner;
+ public ObjectCollection (DataGridViewComboBoxCell owner)
+ {
+ this.owner = owner;
list = new ArrayList();
}
public virtual object this [int index] {
get { return list[index]; }
- set { list[index] = value; }
+ set {
+ ThrowIfOwnerIsDataBound ();
+ list[index] = value;
+ }
+ }
+
+ public int Add (object item)
+ {
+ ThrowIfOwnerIsDataBound ();
+ int index = AddInternal (item);
+ SyncOwnerItems ();
+ return index;
+ }
+
+ internal int AddInternal (object item)
+ {
+ return list.Add (item);
+ }
+
+ internal void AddRangeInternal (ICollection items)
+ {
+ list.AddRange (items);
+ }
+
+ public void AddRange (ObjectCollection value)
+ {
+ ThrowIfOwnerIsDataBound ();
+ AddRangeInternal (value);
+ SyncOwnerItems ();
}
- public int Add (object item) {
- return list.Add(item);
+ private void SyncOwnerItems ()
+ {
+ ThrowIfOwnerIsDataBound ();
+ if (owner != null)
+ owner.SyncItems ();
}
- public void AddRange (ObjectCollection value) {
- list.AddRange(value.list);
+ public void ThrowIfOwnerIsDataBound ()
+ {
+ if (owner != null && owner.DataGridView != null && owner.DataSource != null)
+ throw new ArgumentException ("Cannot modify collection if the cell is data bound.");
}
- public void AddRange (params object[] items) {
- list.AddRange(items);
+ public void AddRange (params object[] items)
+ {
+ ThrowIfOwnerIsDataBound ();
+ AddRangeInternal (items);
+ SyncOwnerItems ();
}
- public void Clear () {
- list.Clear();
+ public void Clear ()
+ {
+ ThrowIfOwnerIsDataBound ();
+ ClearInternal ();
+ SyncOwnerItems ();
}
- public bool Contains (object value) {
+ internal void ClearInternal ()
+ {
+ list.Clear ();
+ }
+
+ public bool Contains (object value)
+ {
return list.Contains(value);
}
list.CopyTo (destination, arrayIndex);
}
- public IEnumerator GetEnumerator () {
+ public IEnumerator GetEnumerator ()
+ {
return list.GetEnumerator();
}
- public int IndexOf (object value) {
+ public int IndexOf (object value)
+ {
return list.IndexOf(value);
}
- public void Insert (int index, object item) {
- list.Insert(index, item);
+ public void Insert (int index, object item)
+ {
+ ThrowIfOwnerIsDataBound ();
+ InsertInternal (index, item);
+ SyncOwnerItems ();
+ }
+
+ internal void InsertInternal (int index, object item)
+ {
+ list.Insert (index, item);
}
- public void Remove (object value) {
- list.Remove(value);
+ public void Remove (object value)
+ {
+ ThrowIfOwnerIsDataBound ();
+ RemoveInternal (value);
+ SyncOwnerItems ();
}
- public void RemoveAt (int index) {
- list.RemoveAt(index);
+ internal void RemoveInternal (object value)
+ {
+ list.Remove (value);
}
+ public void RemoveAt (int index)
+ {
+ ThrowIfOwnerIsDataBound ();
+ RemoveAtInternal (index);
+ SyncOwnerItems ();
+ }
+
+ internal void RemoveAtInternal (int index)
+ {
+ list.RemoveAt (index);
+ }
int IList.Add (object item)
{
#if NET_2_0
+using System.Collections;
using System.ComponentModel;
using System.Drawing.Design;
using System.Drawing;
public DataGridViewComboBoxColumn ()
{
CellTemplate = new DataGridViewComboBoxCell();
+ ((DataGridViewComboBoxCell) CellTemplate).OwningColumnTemplate = this;
SortMode = DataGridViewColumnSortMode.NotSortable;
autoComplete = true;
displayStyle = DataGridViewComboBoxDisplayStyle.DropDownButton;
[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
public override DataGridViewCell CellTemplate {
get { return base.CellTemplate; }
- set { base.CellTemplate = value as DataGridViewComboBoxCell; }
+ set {
+
+ DataGridViewComboBoxCell cellTemplate = value as DataGridViewComboBoxCell;
+ if (cellTemplate == null)
+ throw new InvalidCastException ("Invalid cell tempalte type.");
+
+ cellTemplate.OwningColumnTemplate = this;
+ base.CellTemplate = cellTemplate;
+ }
}
[AttributeProvider (typeof (IListSource))]
}
}
+ internal void SyncItems (IList items)
+ {
+ if (DataSource != null || DataGridView == null)
+ return;
+
+ for (int i = 0; i < DataGridView.RowCount; i++) {
+ DataGridViewComboBoxCell comboCell = DataGridView.Rows[i].Cells[base.Index] as DataGridViewComboBoxCell;
+ if (comboCell != null) {
+ comboCell.Items.ClearInternal ();
+ comboCell.Items.AddRangeInternal (this.Items);
+ }
+ }
+ }
+
public override object Clone ()
{
DataGridViewComboBoxColumn col = (DataGridViewComboBoxColumn) base.Clone();