4

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

但是,当我以编程方式向 DataTable 添加列时,它不会自动反映在 DataGridView 中,我怀疑反之亦然。

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

添加行也可以正常工作。


解决了:

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

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

除此之外,请参阅这篇文章这篇文章

4

4 回答 4

2

这听起来不对。为了测试它,我编写了一个简单的应用程序,它创建了一个 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; }
    }
}
于 2009-01-28T22:21:17.103 回答
1

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

于 2009-01-28T21:31:58.407 回答
1

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

(在我的例子中,数据网格是 TabControl.ContentTemplate 中的一个模板元素)

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

这意味着我只需要:

  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);
        }
 }

希望这有帮助:)

于 2015-03-29T17:09:27.060 回答
-1

我有同样的问题,我发出了 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
}
于 2009-01-28T22:30:19.957 回答