【发布时间】:2019-12-04 02:19:12
【问题描述】:
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
}
}
MainViewModel 代码:
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");
}
}
我希望看到DataTable 以编程方式绑定到DataGrid 的内容(在这种情况下只添加空行),但它只有在通过XAML 绑定时才能正常工作。有什么我可能会错过的想法吗?
【问题讨论】:
-
只有当你绑定到
TableSource属性时,触发OnPropertyChanged("TableSource")才会有效果,而你并没有这样做。 -
var binding = new Binding("TableSource.DefaultView");。 DataContext 已经是mvm,所以不要费心设置Source。UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged毫无意义,因为ItemsSource无法更新源属性。您是否期望它会给您一个新的DataTable或其他东西?你也可以在Refresh()中删除很多无操作的东西。TableSource应该在其 setter 中提升 PropertyChanged 本身,否则将 setter 设为私有。你这样自找麻烦。 -
@Ed 的想法似乎不是替换 TableSource 实例,这对于带有 PropertyChanged 的普通设置器来说是必需的。
-
@Clemens 哦,我明白了。我的脑海在某处添加了一个幻象
new。我现在明白了。 -
@Clemens,确实,当您通过 xaml 绑定它时,它会以某种方式工作,例如
ItemsSource= { Binding TableSource.DefaultView,UpdateSourceTrigger=OnPropertyChanged }并触发OnPropertyChanged("TableSource")。有没有办法在代码隐藏中获得相同的效果?
标签: c# wpf mvvm data-binding binding