2012-06-25 3 views
0

У меня есть небольшая проблема с привязкой данных между DataGridView и PropertyGrid.Datagridview привязки данных при создании нового объекта при создании новой строки

Вот код из объекта Я связывание и 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.

Когда я выбираю строку, которая имеет объект в списке в момент загрузки, я могу редактировать свойства.

Не могли бы вы помочь?

+0

Код, который вы указали, не работает как есть.Я собираюсь отредактировать его с кодом, который, как я полагаю, вы пропустили, но, пожалуйста, проверьте, что то, что я сделал, является правильным и с дальнейшим кодом дает именно то, что у вас есть. –

+0

Извините, я вижу, и это корреспондент, это сокращенная версия моего рабочего источника. –

+0

Должно быть, у вас есть возможность выбора? Это работает очень хорошо, если вы используете 'SelectedObject', а не' SelectedObjects'. Я смотрю, почему новая строка не работает сейчас. –

ответ

0

Причина, по которой новая строка не отображается в сетке свойств, заключается в том, что ее значение DataBoundItem равно null, поэтому ее можно удалить с помощью оператора LINQ where r.DataBoundItem != null.

Я согласен с вами в том, что это очень неприятное поведение, особенно потому, что объект в некотором смысле был создан.

Я думал, что жизнеспособный обходной путь не в определенных обстоятельствах привязки сетки собственности на новый объект либо родительский объект 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; 
    } 
    
  • Держите сетку как, но не позволяют новые строки - вместо того, чтобы обрабатывать новые объекты между отдельной панелью создания строки.


Это работает таким образом, по-видимому, дизайн - DataBoundItem не совершил uptil вы покидаете сетку. Существует небольшая дискуссия, в том числе код DataGridViewhere.

+0

Спасибо, Дэвид, я использую другое обходное решение. Я создаю кнопку, которая добавляет новый элемент в список данных данных, когда это createt, сетка будет отображать объект. –

Смежные вопросы