0

我在DataGridView和 之间的数据绑定有一点问题PropertyGrid

这是我绑定到的对象的代码和DataGridView

 public class Effort
 {
     public BindingList<EffortCalculationRelation> CalculationRelations { get; set; }
     public int ID { get; set; }
     // more properties

     public Effort()
     {
         CalculationRelations = new BindingList<EffortCalculationRelation>();
         CalculationRelations.Clear();

         for (int i=0;i<10;i++)
         {
             CalculationRelations.Add( new EffortCalculationRelation() { ID = i, Name = "Round:" + i.ToString(), calculation = "Some calc" });
         }
     }

     public Effort(int id) : this()
     {
         this.ID = id;
         // Load all other properties
     }

     public class EffortCalculationRelation
     {
         public int ID { get; set; }
         public string Name { get; set; }
         public string calculation { get; set; }


         public int Save()
         {
             // save or insert and return id or 0 on fail
             if (this.ID > 0)
             {
                 return this.Update();
             }
             else
             {
                 return this.Insert();
             }
         }
         public string Delete()
         {
             // delete and return "" or errormsg on fail
             return "";
         }
         private int Insert()
         {
             // insert and return id or 0 on fail
             return ID;
         }
         private int Update()
         {
             // return affected rows or 0 on fail
             return 1;
         }

         public string Representation
         {
             get { return String.Format("{0}: {1}", ID, Name); }
         }
     }
 }

datagridview 连接非常简单,只有一点点样式:

  public test()
  {
     effort = new Effort(1209);
     dgv.DataSource = effort.CalculationRelations;
     dgv.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.FullRowSelect;
     dgv.AllowUserToAddRows = true;
     //this.dgv.AllowUserToDeleteRows = false;
     dgv.AllowUserToResizeRows = false;
     dgv.ReadOnly = true;
     dgv.SelectionChanged += (sender, args) =>
     {
         var selectedObjects =
              (from System.Windows.Forms.DataGridViewRow r in dgv.SelectedRows
              where r.DataBoundItem != null && r.DataBoundItem.GetType() == typeof(EffortCalculationRelation)
              select r.DataBoundItem).ToArray();

         // pg is a propertygrid
         this.pg.SelectedObjects = selectedObjects;
     };
  }

所以我的问题是,当我在 datagridview 中选择新行时,propertygrid 中没有显示任何属性。

当我在加载时选择列表中包含对象的行时,我可以编辑属性。

那你能帮忙吗?

4

1 回答 1

0

新行未显示在属性网格中的原因是它DataBoundItem为空,因此被您的 LINQ 语句删除where r.DataBoundItem != null1

我同意你的观点,这是非常烦人的行为,特别是因为在某种意义上已经创建了对象。

我曾认为在某些情况下有一种可行的解决方法,可以将属性网格绑定到父Effort对象中的新对象,或者BindingSource使用如下代码:

var selectedObjects =
        (from System.Windows.Forms.DataGridViewRow r in dataGridView1.SelectedRows
        where r.DataBoundItem != null && r.DataBoundItem.GetType() == typeof(Effort.EffortCalculationRelation)
        select r.DataBoundItem).ToArray();

if (dataGridView1.CurrentRow.IsNewRow && dataGridView1.SelectedRows.Count == 1)
{
    // I tried accessing the parent object like this:
    //Effort.EffortCalculationRelation ecr = effort.CalculationRelations[effort.CalculationRelations.Count - 1];
    //propertyGrid1.SelectedObject = ecr;

    // Or accessing a binding source like:
    propertyGrid1.SelectedObject = calculationRelations.Current;
}
else
{
    propertyGrid1.SelectedObjects = selectedObjects;
}

我对这些变体进行了一些试验,并将这些项目添加到 SelectedObjects 数组中,认为某些东西会满足您的要求,但我最终意识到在 DataGridView 提交新行之前将焦点从新行转移到属性网格意味着新行丢失并且无法再编辑

那么该怎么办?

如果我在你的位置,我会考虑以下两件事之一:

  • 允许在某种形式的网格中直接编辑 - 可能只是到新行。

    在选择更改事件中这样的事情会起作用:

    if (dataGridView1.CurrentRow.IsNewRow)
    {
        dataGridView1.CurrentRow.ReadOnly = false;
    }
    else
    {
        dataGridView1.CurrentRow.ReadOnly = true;
    }
    
  • 保持网格不变,但不允许新行 - 而是在单独的行创建面板之间处理新对象。


1这显然是通过设计以这种方式工作的 - 在您离开网格之前不会提交 DataBoundItem。这里有一些讨论,包括有问题DataGridView代码。

于 2012-06-25T13:58:56.573 回答