我有一个按钮,当它被点击时,它会填充我的Datagrid。代码是在.xaml.cs文件中编写的,我认为这打破了MVVM规则,但这只是一个临时情况。我知道它对MVVM不太理想。
Calculate.xaml.cs
public void PopulateGrid(object sender, RoutedEventArgs e)
{
BindableCollection<Payments> PaymentCollection = new BindableCollection<Payments>
....
Datagrid.ItemsSource = PaymentCollection
....
}
我的问题是,是否有办法从ViewModel读取Datagrids ItemsSource。
我尝试过什么
LoansViewModel
public BindableCollection<Payments> paymentCollection {get; set;}
Calculate.xaml
<telerik:RadGridView ItemsSource="{Binding paymentCollection, Mode=TwoWay}" ... />
单击计算后,集合paymentCollection不会更新。
答案 0 :(得分:0)
如果您的网格的DataContext设置为声明了paymentCollection属性的ViewModel实例,那么您的xaml代码看起来应该可以正常工作。
设置绑定后,它会调用paymentCollection属性上的get。如果您的集合属性对象没有进一步重新分配,并且您从中添加和删除元素,并通过INotifyCollectionChanged通知这些更改,它将起作用。这就是ObservableCollection的工作原理,并且最常用于此类场景。
但是,如果在计算时,使用新实例重新分配paymentCollection属性,则网格将不会更新,因为您现在拥有完全不同的集合。在这种情况下,您需要通知视图paymentCollection属性本身已更改。在这种情况下,您应该将其实现为通知属性:
private BindableCollection<Payments>_paymentCollection;
public BindableCollection<Payments> paymentCollection {
get { return _paymentCollection; }
set {
_paymentCollection = value;
OnPropertyChanged("paymentCollection");
}
}
protected void OnPropertyChanged(string name) {
PropertyChangedEventHandler handler = PropertyChanged;
if(handler != null) {
handler(this, new PropertyChangedEventArgs(name));
}
}
答案 1 :(得分:0)
这样做是正确的MVVM方式。摆脱.xaml.cs文件中的PopulateGrid方法,并取消在xaml中设置Click属性。而是将按钮的command属性绑定到ViewModel中的ICommand属性,就像绑定RadGridView的ItemsSource一样。您将需要使用ICommand的实现,MVVM Lights RelayCommand是一个选项。
以下是ICommand的代码:
private ICommand _populateGridCommand;
public ICommand PopulateGridCommand
{
get
{
if (_populateGridCommand == null)
{
_populateGridCommand = new RelayCommand(() => PopulateGrid());
}
return _populateGridCommand;
}
}
public void PopulateGrid()
{
PaymentCollection.Clear();
//load data and then add to the collection
}
<强>更新强>
要在后面的代码中执行此操作,您需要访问ViewModel并从中处理集合。我不喜欢这样但它应该有用。
public void PopulateGrid(object sender, RoutedEventArgs e)
{
var loansVM = DataGrid.DataContext as LoansViewModel;
loansVM.paymentsCollection.Clear();
var newData = //load data
foreach (var data in newData)
loansVM.paymentsCollection.Add(data);
}