自传的Windows形成自定义控制在自己的话[ComboView] 第一部分。

介绍 我是谁?我在Co

  

deProject做什么?好吧,我将自己回答所有这些问题和其他问题。 我是一个ComboView控件。你可能会想,那是什么?我是一个组合框,具有在列表视图中显示柱状项目的能力。嗯,你可能会问,还有很多类似的控件可用,那我有什么特别的呢?没什么,唯一不同的是我要向你们讲述我是如何被赋予生命的,以及在我被创造的过程中,我的创造者学到的教训。 在开始的时候 几天前,一个疯狂的开发人员想要创造我。这不是出于对我的爱,而是出于贪婪。对学习的渴望,对理解控制发展的复杂性的渴望等等。所以,你看一个人是很贪婪的。他为自己的需要做任何事。 好吧,让我们看看他计划创造我的时候脑子里都在想些什么。 他需要学习。net中的控件创建(特别是c#)。 他需要了解如何创建复合控件。 他需要理解ListView的工作方式。 他需要了解如何提供自定义数据绑定的细节。 他需要了解如何使用定制事件。 等等…… 我得承认一件事。我不是最好的控制者,甚至不是最接近他们的。但我很高兴,因为在某种程度上,正是通过我,我的创造者理解了上述所有目标(或者我认为他理解了)。 让我们剖析一下我自己,在这个旅程中,你和我可以学到一些东西。 解剖自己 先做重要的事。为了我的存在,我需要有一个父母。开发人员决定用户控件应该是我的父控件。 因此,我继承自System.Windows.Forms.Usercontrol。这意味着我将拥有我的父类(UserControl)的所有属性和行为。隐藏,复制Code

public class MyCombo : System.Windows.Forms.UserControl
{

因为我是一个ComboView,为了我的存在,我需要一些其他控件的支持,特别是,一个按钮,一个列表视图和一个文本框。隐藏,复制Code

private System.Windows.Forms.ListView lvObject;
private System.Windows.Forms.TextBox txtObject;
private System.Windows.Forms.Button btnDropDown;

好的,我将解释为什么以上三种控制是必需的: ListView将用于以多栏形式显示数据。 文本框将用于显示所选的值。 这钮扣可以把我钻上钻下。 然后开发人员需要某些变量来控制我的行为。所以,他在自己的区域宣布。隐藏,复制Code

#region MyCombo Variables
    private object _dataSource;
    private string _dataMember;
    private string _displayMember;
    private string _valueMember;

    protected ArrayList _columnHeader = new ArrayList();

    private object _selectedValue;
    private object _selectedText;

    //Size
    const int MIN_WIDTH = 140;
    const int MIN_HEIGHT = 22;
#endregion

让我告诉你这些变量对我来说意味着什么,其他的很明显。(稍后,我们将为上述变量分别添加set/get属性。) _dataSource 我需要能够填充来自不同来源的数据,如自定义类,数据库,XML文件等。使用此属性分配数据源。 _dataMember 一个_dataSource可以包含多个表。通过这个属性指定我应该从哪个表中获取数据。 _displayMember 因为我将以多列格式显示自己,所以通过这个属性指定要在文本框中显示哪一列。 _valueMember 理想情况下,这应该是单行数据中每个数据元素的惟一ID。你需要这个值来查询,保存等等。 _selectedValue 这将返回来自_valueMember变量的值。 _selectedText 这将返回_displayMember变量的值。 _columnHeader 这是一个ArrayList。这将保留列的标题。 现在是事件部分。事件是必要的,以便控件的用户知道什么时候发生了事情。现在,开发人员只提供了一个自定义事件。隐藏,复制Code

#region MyCombo Events
    public delegate void 
      SelectedItemChangedEventHandler(object sender, EventArgs e);
    public event SelectedItemChangedEventHandler 
      OnSelectedItemChangedHandler;
#endregion

每当用户从ListView中选择列表项时,OnSelectedItemChangedHandler就会被触发。 正如我所承诺的,下面是相应的get/set访问器。我的用户会看到这个属性,而不是我们上面看到的变量。隐藏,收缩,复制Code

    public string DisplayMember
    {
        get 
        {
            return _displayMember;
        }
        set 
        {
            _displayMember = value;
        }
 
    }

    public string ValueMember
    {
        get 
        {
            return _valueMember;
        }
        set 
        {
            _valueMember = value;
        }
    }

    public string DataMember
    {
        get 
        {
            return _dataMember;
        }
        set 
        {
            _dataMember = value;
        }
    }

    public object DataSource
    {
        get 
        {
            return _dataSource;
        }
        set 
        {
            _dataSource = value;
            OnDataBind();
        }
    }

    public object SelectedText
    {
        get 
        {
            return _selectedText;
        }
        set 
        {
            _selectedText=value;
        }
    }

    public object SelectedValue
    {     
        get 
        {
            return _selectedValue;
        }
        set 
        {
            _selectedValue = value;
        }
    }

在DataSource属性中,您会看到一个方法OnDataBind()。这将在我们进一步解释。 现在,应该有一种机制可以让我的用户将列分配给我。这由下面的函数来处理。该函数接受两个参数,列的名称和列的宽度。这个函数只是将列名添加到我们在上面看到的ArrayList中。隐藏,复制Code

public void Columns(string columnName, int colWidth)
{
    _columnHeader.Add(columnName);
    OnHeaderBind(columnName,colWidth);
}

现在,让我们看看OnHeaderBind()函数。这个函数将columnName添加到实际的ListView对象中,并设置它的宽度。隐藏,复制Code

protected void OnHeaderBind(object v, int colWidth)
{
    lvObject.Columns.Add(v.ToString(), colWidth, HorizontalAlignment.Left);
}

还应该提供手动向me添加数据的条款,而不是使用数据源和数据成员。这可以通过以下函数实现。这个函数接受一个ID和一个要添加到ListView的项目数组。因此,我的用户可以向我添加一个项目,如:Hide  Code

<instance of me>.Add ("101","Rajesh","23)

Hide副本,复制Code

public void Add(string id, params string [] items)
{
    ListViewItem lvi = new ListViewItem(id);

    foreach(string s in items)
    {
        lvi.SubItems.Add(s);
    }
    lvObject.Items.Add(lvi);
}

现在,如前所述,让我们来讨论OnDataBind() method。每当您将数据源分配给我时,就会调用此方法。这个方法只会在ListView中填充来自数据源的信息。隐藏,复制Code

protected void OnDataBind()
{
    if (_dataSource == null)
        return;
    IList iList = InnerDataSource();

    Type  type = iList.GetType();

    string s;

    for (int i = 0; i < iList.Count ; i++)
    {
        s=  GetField(RuntimeHelpers.GetObjectValue(iList[i]),_valueMember);
        ListViewItem lvi = new ListViewItem(s);
        for (int j = 1; j < _columnHeader.Count; j++)
        {
          lvi.SubItems.Add(GetField(RuntimeHelpers.GetObjectValue(iList[i]),
                                              _columnHeader[j].ToString()));
        }

        lvObject.Items.Add(lvi);
    }
}

runtimehelper . getobjectvalue (obj)做什么?如果它是一个值类,它会返回一个obj的盒装副本;否则会返回obj本身。 函数的作用是:返回与数据源关联的IList对象。稍后,我们可以为IList对象包含的每个列表值枚举它。隐藏,收缩,复制Code

    private IList InnerDataSource()
    {
        IList iList;

        if (_dataSource is DataSet)
        {
            if (_dataMember.Length > 0)
            {
                iList = ((IListSource)
                        ((DataSet)_dataSource).Tables[_dataMember]).GetList();
            }
            else
            {
                iList = ((IListSource)((DataSet)_dataSource).Tables[0]).GetList();
            }
        }
        else if (_dataSource is IListSource)
        {
            iList = ((IListSource)_dataSource).GetList();
        }
        else if (_dataSource is ICollection)
        {
            object[] objs = new object[((ICollection)_dataSource).Count];
            ((ICollection)_dataSource).CopyTo(objs,0);
            iList = objs;
        }
        else
        {
            iList = (IList)_dataSource;
        }
        return iList;
}

IListSource:该接口为对象提供了返回可绑定到数据源的列表的功能。 ICollection:此接口为所有集合定义大小、枚举器和同步方法。 编译我,添加一个测试项目和添加对我的参考,我准备面对世界。 现在对我来说就这些了。有很多事情需要对我做。也许,那是以后的事了。 我希望你喜欢读我的书。任何建议、批评、想法都应该直接给创造我的人,这样他才能提高我或者多学习一点。 要获得完整的源代码,请查看随本文上传的示例项目。 那再见了, ComboView 学分 内部数据源和相关函数->这些函数是从代码项目/或互联网上的某个地方获得的。如果有人知道原作者,请给我发个评论,我很感谢他。 修订历史 12-28-2003:原文。 本文转载于:http://www.diyabc.com/frontweb/news341.html

原文地址:https://www.cnblogs.com/Dincat/p/13437842.html