从GridView访问ItemsSource

时间:2014-08-21 21:24:14

标签: c# wpf

我有一个按钮,当它被点击时,它会填充我的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不会更新。

2 个答案:

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