繁体   English   中英

向绑定到 DataGridView 的 DataTable 添加列不会更新视图

[英]Adding columns to a DataTable bound to a DataGridView does not update the view

我有一个从 CSV 文件填充的 DataTable,然后使用 DataGridView 在内存中编辑数据。 据我了解,数据的编程编辑应该在用户编辑通过的 DataTable 上完成。 数据网格视图。

但是,当我以编程方式向 DataTable 添加列时,它不会自动反映在 DataGridView 中,我怀疑反过来也是如此。

你如何保持两者同时发生? 我认为数据绑定的想法是这是自动的......

添加行也可以正常工作。


已解决:

尽管在属性对话框中为true (并在代码中明确设置),但AutoGeneratedColumns在设计器代码中设置为false 初始列是以编程方式生成的,因此不应该出现,但是由于设计器代码还继续生成最初用于调试的“设计中”列,因此并未采用这种方式。

道德:检查自动生成的代码!

除此之外,请参阅此帖子此帖子

这听起来不对。 为了测试它,我编写了一个简单的应用程序,它创建了一个 DataTable 并向其中添加了一些数据。
button1.Click它将表绑定到 DataGridView。
然后,我添加了第二个按钮,当单击该按钮时,会将另一列添加到基础 DataTable。
当我测试它并单击第二个按钮时,网格立即反映了更新。

为了测试相反的情况,我添加了第三个按钮,它会弹出一个对话框,其中包含绑定到同一个 DataTable 的 DataGridView。 在运行时,我向第一个 DataGridView 添加了一些值,当我单击按钮打开对话框时,这些更改就被反映了。

我的观点是,它们应该保持并发。 马克可能是对的,他建议您检查AutoGenerateColumns是否设置为true 不过,您不需要调用 DataBind,这仅适用于 Web 上的 DataGridView。 也许你可以发布你在做什么,因为这应该有效。

我是如何测试的:

DataTable table = new DataTable();
public Form1()
{
    InitializeComponent();
}

private void button1_Click(object sender, EventArgs e)
{
    table.Columns.Add("Name");
    table.Columns.Add("Age", typeof(int));
    table.Rows.Add("Alex", 26);
    table.Rows.Add("Jim", 36);
    table.Rows.Add("Bob", 34);
    table.Rows.Add("Mike", 47);
    table.Rows.Add("Joe", 61);

    this.dataGridView1.DataSource = table;
}

private void button2_Click(object sender, EventArgs e)
{
    table.Columns.Add("Height", typeof(int));
    foreach (DataRow row in table.Rows)
    {
        row["Height"] = 100;
    }
}

private void button3_Click(object sender, EventArgs e)
{
    GridViewer g = new GridViewer { DataSource = table };
    g.ShowDialog();
}

public partial class GridViewer : Form //just has a DataGridView on it
{
    public GridViewer()
    {
    InitializeComponent();
    }

    public object DataSource
    {
        get { return this.dataGridView1.DataSource; }
        set { this.dataGridView1.DataSource = value; }
    }
}

这是另一个不需要为数据网格分配“名称”的解决方案,因此数据网格可以是模板元素。

(就我而言,数据网格是 TabControl.ContentTemplate 中的模板元素)

显示新列(在初始绑定后以编程方式添加)的关键是强制刷新数据网格。 Force WPF DataGrid to regenerate AutoGenerateColumns的答案来看,Andres 建议将AutoGenerateColumns从 false 设置为 true 将强制数据网格刷新。

这意味着我只需要:

  1. AutoGenerateColumns绑定到我的对象的属性
  2. 在添加列之前将属性设置为 false
  3. 添加列后将属性设置为true。

这是代码:

XAML:

<DataGrid AutoGenerateColumns="{Binding toggleToRefresh}"
          ItemsSource="{Binding dataTable}"
          />

C#:

 public class MyTabItem : ObservableObject 
 {
        private DataTable _dataTable = new DataTable();
        public DataTable dataTable
        {
            get { return _dataTable; }
        }

        private bool _toggleToRefresh = true;
        public bool toggleToRefresh
        {
            get { return _toggleToRefresh; }
            set
            {
                if (_toggleToRefresh != value)
                {
                    _toggleToRefresh = value;
                    RaisePropertyChanged("toggleToRefresh");
                }
            }
        }

        public void addDTColumn()
        {
            toggleToRefresh = false;
            string newColumnName = "x" + dataTable.Columns.Count.ToString();
            dataTable.Columns.Add(newColumnName, typeof(double));
            foreach (DataRow row in dataTable.Rows)
            {
                row[newColumnName] = 0.0;
            }
            toggleToRefresh = true;
        }

        public void addDTRow()
        {
            var row = dataTable.NewRow();
            foreach (DataColumn col in dataTable.Columns)
            {
                row[col.ColumnName] = 0.0;
            }
            dataTable.Rows.Add(row);
        }
 }

希望这有帮助:)

AutoGenerateColumns 是否设置为 true? 如果您在初始绑定后进行更改,您还必须调用 DataBind() 来重新绑定更改后的数据源。 我知道这对于 AJAX 回调是正确的,我认为对于 WinForms 控件 PostBack 也是如此。

我有同样的问题,我发出了一个 DataBind()。 这不是万能的灵丹妙药,但它在某些情况下对我有所帮助。 我必须在通过 DataView 捕获信息之前,在 EditCommand 和 UpdateCommand 事件之后立即将其放入 EditItemIndex 语句之后,

protected void datalistUWSolutions_EditCommand(object source, DataListCommandEventArgs e)
{
  datalistUWSolutions.EditItemIndex = e.Item.ItemIndex;
  datalistUWSolutions.DataBind(); // refresh the grid.
}

protected void datalistUWSolutions_UpdateCommand(object source, DataListCommandEventArgs e)
{
  objDSSolutions.UpdateParameters["Name"].DefaultValue = ((Label)e.Item.FindControl("lblSolutionName")).Text;
  objDSSolutions.UpdateParameters["PriorityOrder"].DefaultValue = ((Label)e.Item.FindControl("lblOrder")).Text;
  objDSSolutions.UpdateParameters["Value"].DefaultValue = ((TextBox)e.Item.FindControl("txtSolutionValue")).Text;
  objDSSolutions.Update();
  datalistUWSolutions.EditItemIndex = -1; // Release the edited record
  datalistUWSolutions.DataBind();         // Redind the records for refesh the control
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM