绑定组合框中未绑定的项目

 

介绍 有时需要将项目

  

 

添加到将出现在下拉列表开头的绑定组合框中。如果您曾经尝试向绑定的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

posted @ 2020-08-05 02:15  Dincat  阅读(132)  评论(0编辑  收藏  举报