C# 向绑定到DataGridView的DataTable添加列不会更新该视图
我有一个从CSV文件填充的DataTable,然后使用DataGridView在内存中编辑数据。据我所知,数据的编程编辑应该在DataTable上完成,用户编辑是通过DataTable完成的。DataGridView 但是,当我以编程方式向DataTable添加列时,它不会自动反映在DataGridView中,我怀疑反过来也是正确的 你如何使两者同时进行?我认为数据绑定的想法是这是自动的 另外,添加行也可以C# 向绑定到DataGridView的DataTable添加列不会更新该视图,c#,winforms,visual-studio-2008,datagridview,datatable,C#,Winforms,Visual Studio 2008,Datagridview,Datatable,我有一个从CSV文件填充的DataTable,然后使用DataGridView在内存中编辑数据。据我所知,数据的编程编辑应该在DataTable上完成,用户编辑是通过DataTable完成的。DataGridView 但是,当我以编程方式向DataTable添加列时,它不会自动反映在DataGridView中,我怀疑反过来也是正确的 你如何使两者同时进行?我认为数据绑定的想法是这是自动的 另外,添加行也可以 已解决: 尽管在属性对话框中为true(并在代码中明确设置),但在设计器代码中将Aut
已解决: 尽管在属性对话框中为
true
(并在代码中明确设置),但在设计器代码中将AutoGeneratedColumns
设置为false
。初始列是以编程方式生成的,因此不应该出现,但是由于设计器代码还继续生成最初用于调试的“design in”列,因此没有注意到这一点
寓意:检查自动生成的代码
除此之外,请参见和,AutoGenerateColumns是否设置为true?如果在初始绑定后进行更改,还必须调用DataBind()重新绑定更改的数据源。我知道这对于AJAX回调是正确的,我认为对于WinForms控件回发也是正确的。这听起来不对。为了测试它,我编写了一个简单的应用程序,它创建了一个DataTable并向其中添加了一些数据。
在
按钮1上,单击将表绑定到DataGridView。
然后,我添加了第二个按钮,当单击该按钮时,会将另一列添加到基础数据表中。
当我测试它时,我点击了第二个按钮,网格立即反映了更新
为了测试反向,我添加了第三个按钮,它会弹出一个对话框,其中包含绑定到同一个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; }
}
}
我也有同样的问题,我发布了一个DataBind()。它不是万能的,但它在一些情况下帮助了我。我必须在通过DataView捕获信息之前,在EditCommand和UpdateCommand事件之后,在EditItemIndex语句之后立即将其放入
protected void datalistUWSolutions_EditCommand(object source, DataListCommandEventArgs e)
{
datalistUWSolutions.EditItemIndex = e.Item.ItemIndex;
datalistUWSolutions.DataBind(); // refresh the grid.
}
及
这里是另一个解决方案,您不需要为数据网格指定“名称”,这样数据网格就可以是一个模板元素
(在我的例子中,数据网格是TabControl.ContentTemplate中的模板元素)
显示新列(在初始绑定后以编程方式添加)的关键是强制刷新datagrid。
根据中的回答,Andres建议将AutoGenerateColumns
从false设置为true将强制datagrid刷新
这意味着我只需要:
将AutoGenerateColumns
绑定到我的对象的属性
在添加列之前,将属性设置为false
添加列后,将属性设置为true
代码如下:
XAML:
希望获得以下帮助:)System.Windows.Forms中的DataGridView没有数据绑定方法。您考虑的是作为System.Web.UI.WebControl一部分的GridView。OP讨论的是WinForms。特别是,检查设计器代码中的AutoGenerateColumns值。由于示例在调试中帮助很大,所以选择了答案!
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
}
<DataGrid AutoGenerateColumns="{Binding toggleToRefresh}"
ItemsSource="{Binding dataTable}"
/>
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);
}
}