以编程方式绑定到数据表时,C#WPF DataGrid不会更新

以编程方式绑定到数据表时,C#WPF DataGrid不会更新,c#,wpf,mvvm,data-binding,binding,C#,Wpf,Mvvm,Data Binding,Binding,当ItemsSource以编程方式绑定到DataTable时,DataGrid不会更新 我正在构建一个用户控件,可以根据条件(通过MVVM)更改其内部内容。 Xaml示例: <Window ...> <grid x:Name="mainGrid" /> </Window> public partial class MainWindow : Window { public MainViewModel mvm { get; set; } = ne

ItemsSource
以编程方式绑定到
DataTable
时,
DataGrid
不会更新

我正在构建一个用户控件,可以根据条件(通过MVVM)更改其内部内容。
Xaml示例:

<Window ...>
    <grid x:Name="mainGrid" />
</Window>
public partial class MainWindow : Window
{
    public MainViewModel mvm { get; set; } = new MainViewModel();

    public MainWindow()
    {
        InitializeComponent();

        this.DataContext = mvm;

        var dataGrid = new DataGrid()
        {
            Width = 400,
            Height = 400,
            AutoGenerateColumns = true,
            IsReadOnly = true,
        };

        var binding = new Binding("DefaultView")
        {
            Source = mvm.TableSource,
            UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged
        };

        BindingOperations.SetBinding(dataGrid, DataGrid.ItemsSourceProperty, binding);

        mainGrid.Children.Add(dataGrid);
    }

    private void button_Click_1(object sender, RoutedEventArgs e)
    {
        mvm.TableSource.Columns.Add("test" + new Random().Next());
        mvm.TableSource.Rows.Add("test" + new Random().Next());
        mvm.Refresh(); //force update
    }
}
public class MainViewModel:ModelBase // ModelBase implements INotifyPropertyChanged
{
    public DataTable TableSource {get;set;} = new DataTable()

    public void Refresh()
    {
        var temp = TableSource;
        TableSource = null;
        OnPropertyChanged("TableSource");
        TableSource = temp;
        OnPropertyChanged("TableSource");
    }
}
MainViewModel代码:

<Window ...>
    <grid x:Name="mainGrid" />
</Window>
public partial class MainWindow : Window
{
    public MainViewModel mvm { get; set; } = new MainViewModel();

    public MainWindow()
    {
        InitializeComponent();

        this.DataContext = mvm;

        var dataGrid = new DataGrid()
        {
            Width = 400,
            Height = 400,
            AutoGenerateColumns = true,
            IsReadOnly = true,
        };

        var binding = new Binding("DefaultView")
        {
            Source = mvm.TableSource,
            UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged
        };

        BindingOperations.SetBinding(dataGrid, DataGrid.ItemsSourceProperty, binding);

        mainGrid.Children.Add(dataGrid);
    }

    private void button_Click_1(object sender, RoutedEventArgs e)
    {
        mvm.TableSource.Columns.Add("test" + new Random().Next());
        mvm.TableSource.Rows.Add("test" + new Random().Next());
        mvm.Refresh(); //force update
    }
}
public class MainViewModel:ModelBase // ModelBase implements INotifyPropertyChanged
{
    public DataTable TableSource {get;set;} = new DataTable()

    public void Refresh()
    {
        var temp = TableSource;
        TableSource = null;
        OnPropertyChanged("TableSource");
        TableSource = temp;
        OnPropertyChanged("TableSource");
    }
}

当以编程方式将
数据表绑定到
数据网格
(本例中仅添加空行)时,我希望看到
数据表
的内容,但只有通过
XAML
绑定时,它才能正常工作。有什么想法我可能会错过吗?

如何在代码中模拟相同的功能还不清楚,所以我添加了一个解决方案,在实际绑定之前添加列。

触发
OnPropertyChanged(“TableSource”)
只有在绑定到
TableSource
属性时才会生效,您没有这样做。
var binding=newbinding(“TableSource.DefaultView”)。DataContext已经是
mvm
,所以不必费心设置
Source
UpdateSourceTrigger=UpdateSourceTrigger.PropertyChanged
是毫无意义的,因为
ItemsSource
无法更新源属性。你希望它能给你一个新的
数据表
或者什么吗?您也可以在
Refresh()
中删除许多无操作的内容
TableSource
应在其setter中引发PropertyChanged自身,否则将setter设置为私有。您这样是在自找麻烦。@Ed您的想法似乎不是要替换TableSource实例,这对于一个属性已更改的普通setter是必要的。@Clemens Ohh,我明白了。我的大脑在某处添加了一个幻影
新的
。我现在明白了。@Clemens,当你通过xaml像这样绑定它时,它确实会起作用,
ItemsSource={binding TableSource.DefaultView
UpdateSourceTrigger=OnPropertyChanged}
和激发
OnPropertyChanged(“TableSource”)
。有没有办法在代码背后获得同样的效果?