• 自传的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

  • 相关阅读:
    线段树快速查找区间值
    html学习笔记
    区块链是怎么运行的
    【C++ 流类库与输入输出 】实验七
    【C++ 实验六 继承与派生】
    10天冲刺第四天后端app开发
    10天冲刺第三天后端app开发
    10天冲刺第二天之完成后端
    第二次冲刺第一天之后台管理
    第一阶段--冲刺总结
  • 原文地址:https://www.cnblogs.com/Dincat/p/13437842.html
Copyright © 2020-2023  润新知