将WPF DataGrid绑定到DataTable

9

我是一名非英语母语者,因此我的英语不太好。如果我在使用语言方面犯了错误,请谅解 :)

我是C#和WPF的新手,正在尝试将WPF DataGrid双向绑定到DataTable。现在,当我在DataGrid中编辑值时,DataTable中的数据会正确更改。但是,当我尝试使用以下代码填充DataTable时:

OleDbDataAdapter adapter = new OleDbDataAdapter("a query", (a connection));
adapter.Fill(dataTable);

代码可以运行,DataGrid看起来也没问题。但是当我尝试这样做时:
dataTable.Rows[0][1] = (some object);

显示值不会改变。我尝试以以下方式检查DataGrid中的值:
MessageBox.Show((SomeDataGrid.Items[0] as DataRowView).Row[1].ToString());

没问题,看来一切正常。我想知道为什么显示值是这样的。

这是我的 XAML 中的 DataGrid.CellStyle:

<DataGrid.CellStyle>
    <Style TargetType="DataGridCell">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="DataGridCell">
                    <Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Background="{TemplateBinding Background}">
                        <DataGridDetailsPresenter HorizontalAlignment="Stretch" VerticalAlignment="Center" Content="{TemplateBinding Content}"/>
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
        <Style.Triggers>
            <!-- triggers -->
        </Style.Triggers>
    </Style>
</DataGrid.CellStyle>

我一直在这个问题上卡了好几天了,谢谢任何帮助!


当您为DataGrid定义列时,请确保将UpdateMode属性设置为PropertyChanged。 - Sivakumar
3个回答

6

这个可以运行,也许你可以提供更多的信息。

视图模型:

public DataTable MyDataTable { get; private set; }

//ctor
_ds = new DataSet("Test");
this.MyDataTable = _ds.Tables.Add("DT");
this.MyDataTable.Columns.Add("First");
this.MyDataTable.Columns.Add("Second");

this.MyDataTable.Rows.Add("11", "12");
this.MyDataTable.Rows.Add("21", "22");

//view is updated with this
public void UpdateTable()
{
    this.MyDataTable.Rows[0][1] = "haha";
}

xaml

<DataGrid AutoGenerateColumns="True" ItemsSource="{Binding MyDataTable}"/>

6

我不太确定这个解决方案是否有效,但值得一试。

尝试将您的DataGrid绑定到DataView而不是DataTable。 您可以使用DefaultView属性将您的DataTable转换为DataView

DataTable dt = new DataTable();
DataView dv = dt.DefaultView;

当与 DataView 绑定时,您对数据的更改通知应该是双向的。


2
很遗憾,我不认为 DataRow 实现了 INotifyPropertyChanged 接口,也不认为 DataTable 实现了 INotifyCollectionChanged 接口。这些接口告诉 WPF 的 DataBinding 在底层源值发生更改时更新。因此,当您更新底层的 DataTable 值时,Binding 不会自动刷新,这种更改也不会在您的 DataGrid 中反映出来。 这个链接 指向一个类似的问题并提供了答案。基本上,如果您希望您的 DataGrid 在更改底层数据源中的值时能够识别和更新,您需要创建一个实现了 INotifyPropertyChanged 接口的自定义对象。

1
据我所知,WPF绑定到底层的DataView,因此绑定到IBindingListView,因此具有所有通知功能。 - blindmeis
这似乎是一个备受争议的话题,但如果您查看此问题的第二个答案,特别是评论部分,就会得到解释。IBindingListView接口不能替代INotifyPropertyChanged的需要。 - Brian S
您还可以查看MVP的这个演示文稿,第24页指出IBindingListView集合中的项必须实现INotifyPropertyChanged。 - Brian S
尝试一下我的测试代码。它可以正常工作,而且没有实现INotifyPropertyChanged。 - blindmeis

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接