【问题标题】:Setting DataRow as ComboBox's value member将 DataRow 设置为 ComboBox 的值成员
【发布时间】:2009-05-04 14:02:40
【问题描述】:

我正在使用 DataTable 将 XML 文件中的项目填充到我的 ComboBox 中。目前我已将其设置为一列是 ComboBox 的显示成员,另一列是它的值成员。但是,这可能并不总是对我有用,因为我必须设置 selectedItem 参数,并且 value 成员可能不是唯一的。

我不知道表中是否存在重复的值成员,所以我的想法是我将整个 DataRow 作为 ComboBox 的值成员,然后使用 ComboBox.SelectedITem = (DataRow)一些数据行;用于选择,它总是会选择正确的 ComboBox 对象。

我将如何做到这一点?有没有更好的方法来做到这一点?我对建议持开放态度,但重要的是我可以同时获得展示会员和价值会员。

感谢您的帮助!

编辑:也许我之前不够清楚,但是当我问这是否是这里最好的方法时,我也在问如何这样做。如果我不设置 valuemember 参数,则 SelectedItem 是 DataRowView 类型...请注意,我想使用 selectedValue 参数从 ComboBox 中选择项目,如果我尝试在没有明确设置 value 成员的情况下这样做抛出异常。

【问题讨论】:

    标签: c# combobox datatable


    【解决方案1】:

    如果您将ListBox 绑定到DataTable,您实际上是将其绑定到代表DataTableDataViewDataTable 实现IListSource,并返回DataView) .您不能直接将SelectedItem 设置为DataRow 实例,您必须将其设置为DataRowView 实例。不幸的是,没有简单的方法可以从DataRow 获得DataRowView

    您最好通过DataRowView 进行所有交互。这将允许您明确设置SelectedItem

    您不能使用SelectedValue 属性,您必须为此使用SelectedItem

    【讨论】:

      【解决方案2】:

      首先感谢 Adam Robinson,我确信您的回答是正确的,但这并不是我想听到的。我以不同的方式解决了我的问题,我认为它可能对其他人有用,所以我在这里发布。

      我所做的是我创建了一个新类,在我的例子中,我将它命名为 ListObject,它有一个属性 DataRow(稍后您将看到它也适用于其他类型,我只是使用它,因为这是我真正想要的作为我的项目值属性)。它还覆盖了方法:

      • 字符串 ToS​​tring()
      • bool Equals(object obj)
      • int GetHashCode() -- 在我的情况下不需要,但是 Visual Studio
        警告你它应该被覆盖。

      我的想法是我可以用我自己的类的对象填充 ComboBox.Items 集合,显示一个自定义字符串(如果我没有像这样解决它,我关于堆栈溢出的下一个问题可能是关于在阅读时自定义 DisplayMembers来自 DataRow 的项目)并仅比较一个类的项目(在我的情况下为 DataRow)。

      所以这是代码,它工作得很好(至少对于我想用它做的)。

      public class ListObject
      {
          public DataRow element;
      
          public String DisplayObject = null;
      
          public ListObject(DataRow dr)
          {
              element = dr;
          }
      
          public ListObject(DataRow dr, String dspObject)
          {
              element = dr;
              DisplayObject = dspObject;
          }
      
          public override String ToString()
          {
              if (DisplayObject == null) throw new Exception("DisplayObject property was not set.");
      
              return element[DisplayObject].ToString();
          }
      
          public override bool Equals(object obj)
          {
              if (obj.GetType() == typeof(ListObject))
                  return Equals(((ListObject)obj).element, this.element);
              else return base.Equals(obj);
          }
      
          public override int GetHashCode()
          {
              return base.GetHashCode();
          }
      }
      

      在我的情况下它工作得很好,因为我可以用 foreach 语句填充 ComboBox:

      dtUsers.ReadXml(Program.Settings.xmlInputUsers);
      
      foreach(DataRow dr in dtUsers.Rows) 
      {
          cmbUser.Items.Add(new ListObject(dr, "Name"));
      }
      

      当我得到我想要选择的 DataRow 时,我只是这样做:

      cmbUser.SelectedItem = new ListObject(dlg.SelectedDataRow);
      

      我不必担心 DisplayMember 等,因为只会比较 DataRow,并且您的显示参数仍然会在您填充 ComboBox.Items 集合时设置。此外,由于 toString 方法被覆盖,您可以真正自定义输出。

      只有在 ComboBox.SelectedItem 属性 上的 msdn 文章中才可能创建此类,其中指出 SelectedItem 属性使用 IndexOf 方法工作。此方法使用 Equals 方法来确定相等性。

      【讨论】:

        【解决方案3】:

        这是获取 DataTable 到组合框的最简单方法

        private void load() { 
        DataTable dt = // get data from DB 
        comboBox1.ValueMember = null; // allows you to get all fields in the obj to combobox
        comboBox1.DisplayMember = "ccType";//label displayed from dt
        comboBox1.DataSource = dt;
        }
        //to test 
        private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
            {
        
                DataRowView current = (DataRowView)comboBox1.SelectedValue;
                string drs = current.Row["ID"].ToString();
        
            }
        

        【讨论】:

          猜你喜欢
          • 2014-12-01
          • 2018-05-24
          • 1970-01-01
          • 2012-11-11
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-11-16
          • 1970-01-01
          相关资源
          最近更新 更多