介绍 有时需要将项目
添加到将出现在下拉列表开头的绑定组合框中。如果您曾经尝试向绑定的ComboBox添加项目,您可能知道抛出一个ArgumentException,说“当DataSource属性被设置时,不能修改项目集合”。不幸的是,对于UI程序员来说,需要添加项,比如在列表的开头添加“Create new item…”。 数据源 为了允许这样的功能,我们将不得不用一个类包装我们的原始数据源,这个类允许我们添加那些额外的项。首先要注意的是,被ComboBox接受的DataSource必须实现IList接口。另外,为了显示所有项,我们必须实现IEnumerable接口。隐藏,复制Code
public class UnboundWrapper : IEnumerable, IList { public UnboundWrapper(IList dataSource) { _dataSource = dataSource; _extra = new ArrayList(); } IList _dataSource; ArrayList _extra; #region ExtraData public void AddExtraData(object extraItem) { _extra.Add(extraItem); } public void RemoveExtraData(object extraItem) { _extra.Remove(extraItem); } #endregion }
上面的代码只是我们的基本框架,不应该提出任何问题。接下来,我们将实现IList和IEnumerable方法。这里的主要思想是,我们应该处理一个额外的项,我们将从_extra ArrayList中获取它。否则,我们只是将调用传递到包含的IList中,通过下标的移位,也就是额外项的大小。隐藏,收缩,复制Code
#region IList Members public bool IsReadOnly { get { return _dataSource.IsReadOnly; } } public object this[int index] { get { string val; if (index < _extra.Count) val = _extra[index].ToString(); else val = _dataSource[index - _extra.Count].ToString(); return val; } set { _dataSource[index - _extra.Count] = value; } } public void RemoveAt(int index) { if (index < _extra.Count) throw new InvalidOperationException(); _dataSource.RemoveAt(index - _extra.Count); } public void Insert(int index, object value) { if (index < _extra.Count) throw new InvalidOperationException(); _dataSource.Insert(index - _extra.Count, value); } public void Remove(object value) { _dataSource.Remove(value); } public bool Contains(object value) { return _dataSource.Contains(value);; } public void Clear() { _dataSource.Clear(); } public int IndexOf(object value) { if (_extra.Contains(value)) return _extra.IndexOf(value); return _dataSource.IndexOf(value) + _extra.Count; } public int Add(object value) { return _dataSource.Add(value); } public bool IsFixedSize { get { return _dataSource.IsFixedSize; } } #endregion #region ICollection Members public bool IsSynchronized { get { return _dataSource.IsSynchronized; } } public int Count { get { return _dataSource.Count + _extra.Count; } } public void CopyTo(Array array, int index) { _extra.CopyTo(array, index); _dataSource.CopyTo(array, index + _extra.Count); } public object SyncRoot { get { return _dataSource.SyncRoot; } } #endregion #region IEnumerable Members public IEnumerator GetEnumerator() { return new UnboundWrapperEnumerator(this); } #endregion
您将注意到,我们还实现了ICollection接口。这是因为IList继承了它,让我们别无选择。 因为我们已经实现了IEnumerable接口,所以必须为用户提供枚举器。但是,我们不能提供IList的默认枚举器,因为它不包含额外的项。所以现在,我们必须创建一个新类—枚举器:Hide收缩,复制Code
class UnboundWrapperEnumerator : IEnumerator { public UnboundWrapperEnumerator(UnboundWrapper wrapper) { _wrapper = wrapper; } private UnboundWrapper _wrapper; int _index = -1; public void Reset() { _index = -1; } public object Current { get { return _wrapper[_index]; } } public bool MoveNext() { if (_index >= _wrapper.Count - 1) return false; _index++; return true; } }
如您所见,枚举器甚至比包装器本身更简单。 例子 在我们离开之前,让我们看一个简单的例子。创建一个新表单,并向其中添加一个组合框。在表单的构造函数中,添加以下代码:复制Code
string[] items = new string[] {"s1", "s2", "s3"}; UnboundWrapper w1 = new UnboundWrapper(items); w1.AddExtraData("a"); w1.AddExtraData("b"); w1.AddExtraData("c"); w1.AddExtraData("z"); comboBox1.DataSource = w1;
在上面的示例中,数据源是一个简单的字符串数组。扩展代码以支持更多“有趣”的数据源(比如数据集)应该不会太难。 本文转载于:http://www.diyabc.com/frontweb/news274.html