Не удается обновить ячейку DataGridView через DataBoundItem? - PullRequest
2 голосов
/ 06 октября 2019

Я создал форму с двумя элементами управления dataGridView1 и button1.

public partial class Form1 : Form
{
    public List<Foo> ds { get; private set; }

    public Form1()
    {
        InitializeComponent();
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        ds = new List<Foo> {
            new Foo { A="abc" }, new Foo{B="bbb"}
        };
        dataGridView1.DataSource = new BindingList<Foo>(ds);
    }

    private void button1_Click(object sender, EventArgs e)
    {
        var foo = (Foo)dataGridView1.Rows[0].DataBoundItem;
        foo.B = "1BBB";
        foreach(DataGridViewRow x in dataGridView1.Rows)
        {
            if (x.DataBoundItem != null)
                ((Foo)x.DataBoundItem).C = "CCC";
        }
    }
}

Однако при нажатии button1 не отображаются измененные значения в форме? Отладка в Visual Studio показывает, что значения были установлены.


Обновление:

Я изменил код на следующий, чтобы использовать DataTable. Тем не менее, нажатие кнопки по-прежнему не обновляет интерфейс?

public partial class Form1 : Form
{
    public List<Foo> ds { get; private set; }

    private Dictionary<string, Foo> dict;

    public Form1()
    {
        InitializeComponent();
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        //ds = new List<Foo> {
        //    new Foo { A="abc" }, new Foo{B="bbb"}
        //};
        //dataGridView1.DataSource = new BindingList<Foo>(ds);
        var dt = new DataTable();
        dt.Columns.Add(new DataColumn { DataType = typeof(string), ColumnName = "A", Unique = true });
        dt.Columns.Add(new DataColumn { DataType = typeof(string), ColumnName = "B", Unique = false });
        dt.Columns.Add(new DataColumn { DataType = typeof(string), ColumnName = "C", Unique = false });
        dt.Columns.Add(new DataColumn { DataType = typeof(string), ColumnName = "D", Unique = false });
        dt.Columns.Add(new DataColumn { DataType = typeof(string), ColumnName = "E", Unique = false });
        dt.Columns.Add(new DataColumn { DataType = typeof(string), ColumnName = "F", Unique = false });
        dt.Columns.Add(new DataColumn { DataType = typeof(string), ColumnName = "G", Unique = false });
        dt.Columns.Add(new DataColumn { DataType = typeof(string), ColumnName = "H", Unique = false });
        dt.Columns.Add(new DataColumn { DataType = typeof(string), ColumnName = "I", Unique = false });
        dt.Columns.Add(new DataColumn { DataType = typeof(string), ColumnName = "J", Unique = false });
        dt.Columns.Add(new DataColumn { DataType = typeof(string), ColumnName = "K", Unique = false });
        dt.Columns.Add(new DataColumn { DataType = typeof(string), ColumnName = "L", Unique = false });
        dt.PrimaryKey = new DataColumn[] { dt.Columns["A"] };

        var row = dt.NewRow();
        row["A"] = "1";
        dt.Rows.Add(row);
        row = dt.NewRow();
        row["A"] = "2";
        dt.Rows.Add(row);
        row = dt.NewRow();
        row["A"] = "3";
        dt.Rows.Add(row);
        dataGridView1.DataSource = dt;
    }

    private void button1_Click(object sender, EventArgs e)
    {
        var foo = (DataRowView)dataGridView1.Rows[0].DataBoundItem;
        foo["B"] = "1BBB";
        //foreach (DataGridViewRow x in dataGridView1.Rows)
        //{
        //    if (x.DataBoundItem != null)
        //        ((Foo)x.DataBoundItem).C = "CCC";
        //}
        //dataGridView1.DataSource = ds;
    }
}

Ответы [ 2 ]

2 голосов
/ 06 октября 2019

Добавьте «EndEdit» после изменения значения:

private void button1_Click(object sender, EventArgs e)
    {
        var foo = (DataRowView)dataGridView1.Rows[0].DataBoundItem;
        foo["B"] = "1BBB";
        foo.EndEdit();
    }

Вы также можете изменить источник на источник привязки и затем работать непосредственно с таблицей.

1 голос
/ 06 октября 2019

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

Попробуйте это:

  foreach ( DataGridViewRow x in dataGridView1.Rows )
  {
    if ( x.DataBoundItem != null)
      ((Foo)x.DataBoundItem ).C = "CCC";
  }
  dataGridView1.DataSource = new BindingList<Foo>(ds);

В противном случае вы можете написать вместо:

  x.Cells[2].Value = "CCC";

Таким образом, сетка обновляется, а также ограниченный экземпляр.

Вам не нужен BindingList, и вы можете написать это, в первый раз и после модификации:

dataGridView1.DataSource = null;
dataGridView1.DataSource = ds;

Это лучший шаблон:

Как я могу обновить c # dataGridView после обновления?

Но мы можем использовать DataTable или лучше DataSetналичие DataTable при использовании дизайнеров Visual Studio и использование перетаскивания таблицы на формах для написания меньшего количества кода и автоматического создания сетки данных и всех невизуальных компонентов данных.

Вот сводная информация

Чтобы обновить представление модифицированного DataBoundItem, который является объектом источника данных, который является BindingList или просто List, мы можем переназначить источник данных.

Но если это BindingSource, вы можете использовать ResetBindings на BindingSurce.

Но если вы используете DataTable вместо источника данных в списке, то вы можете использовать EndEdit в DataBoundItem, который является DataRowView.

Тогда возникает вопрос: что лучше делать здесь: использовать BindingSource в List или создать DataTable и управлять LoadFromStream и SaveFromStream, поскольку вы сказали, что данные поступают из потока IEnumerable <>?

Поэтому вы можете видеть CopyToDataTable() для сопоставления вашего List<Foo> с DataTable:

Создание таблицы данных из запроса (LINQ to DataSet)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...