【问题标题】:ComboBox On DataRepeater Control Shares Selected IndexDataRepeater 控件共享选定索引上的 ComboBox
【发布时间】:2012-05-14 15:04:11
【问题描述】:

我有一个数据重复器,每一行都使用一个组合框。当您单击“添加”按钮时,它会在 DataRepeater 中添加一个新行。

   public enum ColorTypes {Red, Green, Yellow}
   class LineItem
   {
       public ColorTypes Color {get;set;} 
   }

当您单击表单上的按钮时,它会创建一个新的 LineItem,然后重新绑定。

  private void btnAdd_Click(object sender, EventArgs e)
  {
       LineItem CopyItem = new LineItem();
       CurrentList= ((List<LineItem>)dataRepeater.DataSource); 

       CurrentList.Add(CopyItem);
       dataRepeater.DataSource = CurrentList;
  }

这会正确地将新行添加到 DataRepeater,但现在更改组合框的索引会修改这两行。您需要执行一些特殊的绑定吗?

这是我的绑定代码:

 this.cbPackage.DataSource = System.Enum.GetValues(typeof(ColorTypes));
 this.cbPackage.DisplayMember = "Color";

【问题讨论】:

    标签: c# winforms data-binding combobox datarepeater


    【解决方案1】:

    经过大量搜索和整理后,您可以成功了!为了在 DataRepeater 中正确使用组合框,您需要添加以下事件。

    this.dataForm.ItemCloned += new Microsoft.VisualBasic.PowerPacks.DataRepeaterItemEventHandler(dataForm_ItemCloned);
    this.dataForm.DrawItem += new Microsoft.VisualBasic.PowerPacks.DataRepeaterItemEventHandler(dataForm_DrawItem);
    this.cbPackage.SelectedIndexChanged += new System.EventHandler(cbColor_SelectedIndexChanged);
    

    MSDN ItemCloned

    MSDN DrawItem

    现在,当调用 ItemCloned 事件时,您需要找到组合框控件并手动映射数据源(这可以防止下拉菜单使用相同的源并共享相同的选定索引)

        void dataForm_ItemCloned(object sender,                Microsoft.VisualBasic.PowerPacks.DataRepeaterItemEventArgs e)
        {
            var combo = (ComboBox)e.DataRepeaterItem.Controls.Find("cbColor", false)[0];
            //Set the data source
            Combo.DataSource = System.Enum.GetValues(typeof(DataRepeater.ColorTypes));
        }
    

    如果您的数据在添加行发生更改,或者您需要重新绘制中继器,则组合框索引将设置为空。所以要修复它,在项目模板完成后,您将不得不在绘制时重置选定的索引。

        /// <summary>
        /// After Item is cloned, draw item. The index is now available to select the proper data
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void dataForm_DrawItem(object sender, Microsoft.VisualBasic.PowerPacks.DataRepeaterItemEventArgs e)
        {
            var dataRepeater = (Microsoft.VisualBasic.PowerPacks.DataRepeater)sender;
            var combo = (ComboBox)e.DataRepeaterItem.Controls.Find("cbPackage", false)[0];
            //Set the selected item based of the list item index
            Combo.SelectedItem = ((List<LineItem>)DataRepeater.DataSource)[e.DataRepeaterItem.ItemIndex].PackageType;  
        }
    

    最后,当您更改下拉列表的值时,会出现最后一个问题。数据源不会自动更新。所以现在你需要根据组合框的索引手动更新源。

     void cbPackage_SelectedIndexChanged(object sender, System.EventArgs e)
        {
            var combo = (ComboBox)sender;
            var dataRepeaterItem = (Microsoft.VisualBasic.PowerPacks.DataRepeaterItem)combo.Parent;
            var dataRepeater = (Microsoft.VisualBasic.PowerPacks.DataRepeater)combo.Parent.Parent;
            var source = ((List<ColorData>)DataRepeater.DataSource)[DataRepeaterItem.ItemIndex];
            source.PackageType = (DropData)combo.SelectedValue;        
        }
    

    哇……好了,一切都准备好了。

    【讨论】:

    • 你刚刚为我节省了大量时间。对普遍知识的伟大补充:)
    • 将 ComboBox 的 SelectedValue 绑定到实体框架对象属性 (?int) 时,我得到一个奇怪的 InvalidOperation 异常:“集合已修改;枚举操作可能无法执行。”我觉得很奇怪的原因是,处理异常后,一切正常。但是什么会导致这个异常呢?当我将 EF 对象(即实体列表)分配给数据中继器的绑定源(RepeaterBindingSource.DataSource == EFClass;)时,就会发生这种情况。我根本不知道为什么......
    猜你喜欢
    • 2011-01-13
    • 1970-01-01
    • 2012-06-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-26
    • 1970-01-01
    • 2015-03-08
    相关资源
    最近更新 更多