Свойство DataGridViewColumn.DataPropertyName - PullRequest
7 голосов
/ 08 февраля 2010

У меня есть элемент управления DataGridView, и я хочу заполнить его данными.

Я использую свойство DataSource

// dgvDealAsset is DataGridView
        private void DealAssetListControl_Load(object sender, EventArgs e)
        {
            dgvDealAssets.AutoGenerateColumns = false;
            dgvDealAssets.DataSource = DealAssetList.Instance.Values.ToList();
}

Теперь проблема номер один. Класс моей коллекции не содержит только простых типов, которые можно сопоставить со столбцами с помощью DataPropertyName. Это класс, который содержится в коллекции.

class MyClass
{
  public String Name;
  MyOtherClass otherclass;
}

class MyOtherClass
{
 public String Name;
}

Теперь я привязываю свойства MyClass к столбцам

col1.DataPropertyName = "Name"  // Ok 
col2.DataPropertyName = "otherclass" // Not OK - I will have empty cell

Проблема в том, что я хочу отобразить поле otherclass.Name. Но если я попытаюсь написать

col2.DataPropertyName = "otherclass.Name" 

Я получаю пустую клетку.

Я пытался вручную установить столбец

private void DealAssetListControl_Load(object sender, EventArgs e)
{
    dgvDealAssets.AutoGenerateColumns = false;
    dgvDealAssets.DataSource = DealAssetList.Instance.Values.ToList();

// iterate through rows and set the column manually
        foreach (DataGridViewRow row in dgvDealAssets.Rows)
        {
            row.Cells["Column2"].Value = ((DealAsset)row.DataBoundItem).otherclass.Name;
        }

Но этот цикл foreach занимает около минуты (2k элементов). Как решить эту проблему?

Ответы [ 5 ]

3 голосов
/ 07 октября 2015

В случае, если вы хотите использовать много дочерних элементов, таких как:

class MyClass
{
   public int Id;
   public MyOtherClass OtherClass;
}

class MyOtherClass
{
   public string Name;
   public int Number;
}

Как насчет

1-й раствор Задайте значение для каждой ячейки в каком-либо событии (лучше, чем другое), вручную, после установки источника данных, например:

private void dgv_CellFormatting( object sender, DataGridViewCellFormattingEventArgs e )
{
   MyClass data = dgv.Rows[ e.RowIndex ].DataBoundItem as MyClass;

   dgv.Rows[ e.RowIndex ].Cells[ "colName" ].Value = data.OtherClass.Name;
   dgv.Rows[ e.RowIndex ].Cells[ "colNumber" ].Value = data.OtherClass.Number;
}

2-й раствор Как насчет создания DataTable из данных, а затем связать его?

Буду благодарен за любое мнение; -)

3 голосов
/ 09 февраля 2010

DataGridView не поддерживает привязку данных к дочерним свойствам. Для получения дополнительной информации, проверьте этот пост

Мне нравится решение, которое использует событие CellFormatting.

2 голосов
/ 08 февраля 2010

№ задачи 1:

Попробуйте сделать следующее:

  1. расширить MyOtherClass из объекта (этот шаг может не потребоваться)

  2. и переопределить или создать метод ToString ().

Это должно сделать это.

1 голос
/ 15 сентября 2016

Способ привязки определенной таблицы столбца данных к дочернему свойству источника данных сетки данных использует свойство DataGridView.Column.Tag вместе с методом переопределения ToString() внутри дочернего объекта. Это выглядит следующим образом:

public class Car
{
    public int Id { get; set; }

    public int Name { get; set; }

    public string Colour { get; set; }

    public Wheel Wheel { get; set; }
}

public class Wheel 
{
    public string WheelName { get; set; }

    public override string ToString()
    {
        return WheelName;
    }
}

public class Main
{
   private void LoadGrid(List<Car> data)
   {
       this.dataGridView.Columns["Wheel"].Tag = "WheelName";
   }
}
1 голос
/ 12 марта 2010

Похоже, что виртуальный режим DataGridView решит вашу проблему. В виртуальном режиме DataGridView будет запускать событие всякий раз, когда ему нужно отобразить ячейку. Событие позволяет вам заполнить ячейку, как вам угодно. Преимущество виртуального режима состоит в том, что системе нужно только извлекать данные, которые на самом деле отображаются, поэтому нет медленного запуска при загрузке всего.

    private void my_init_function() {
        datagridview.VirtualMode = true;
        datagridview.CellValueNeeded += new System.Windows.Forms.DataGridViewCellValueEventHandler(datagridview_CellValueNeeded);
    }

    private void datagridview_CellValueNeeded(object sender, DataGridViewCellValueEventArgs e)
    {
        e.Value = get_my_data(e.RowIndex, e.ColumnIndex);
    }
...