简体   繁体   English

从GridView访问ItemsSource

[英]Accessing ItemsSource from GridView

I have a button, When it's clicked it populates my Datagrid. 我有一个按钮,单击它会填充我的Datagrid。 The code is written within the .xaml.cs file, which I believe breaks the MVVM rule but it's just a temporary situation. 该代码写在.xaml.cs文件中,我认为这违反了MVVM规则,但这只是暂时的情况。 I know it's not ideal for MVVM. 我知道这不是MVVM的理想选择。

Calculate.xaml.cs Calculate.xaml.cs

public void PopulateGrid(object sender, RoutedEventArgs e)
{
    BindableCollection<Payments> PaymentCollection = new BindableCollection<Payments>
    ....
    Datagrid.ItemsSource = PaymentCollection
    ....
}

My question is if there's a way to read the Datagrids ItemsSource From the ViewModel. 我的问题是是否有一种方法可以从ViewModel中读取Datagrids ItemsSource。

What I've Tried 我尝试过的

LoansViewModel 贷款查看模型

public BindableCollection<Payments> paymentCollection {get; set;}

Calculate.xaml Calculate.xaml

<telerik:RadGridView ItemsSource="{Binding paymentCollection, Mode=TwoWay}" ... />

The collection paymentCollection Doesn't Update after calculate is clicked. 单击collection之后,collectionCollectionCollection不会更新。

Your xaml code looks like it should work provided the DataContext of your grid is set to your ViewModel instance where your paymentCollection property is declared. 如果将网格的DataContext设置为声明了PaymentCollection属性的ViewModel实例,则您的xaml代码看起来应该可以工作。

Once your binding is set, it calls the get on the paymentCollection property. 设置绑定后,它将调用paymentCollection属性上的get。 If your collection property object is not reassigned any further, and you add and remove elements from it, and it notifies on those changes via INotifyCollectionChanged, it will work. 如果没有进一步重新分配集合属性对象,而是从中添加和删除了元素,并且它通过INotifyCollectionChanged通知了这些更改,则它将起作用。 This is how ObservableCollection works and used most commonly for such scenarios. 这就是ObservableCollection的工作方式,并且最常用于此类情况。

However, if when you calculate, you re-assign your paymentCollection property with a new instance, your grid will not update, because you now have an entirely different collection. 但是,如果在计算时用新实例重新分配您的paymentCollection属性,则网格将不会更新,因为您现在拥有一个完全不同的集合。 In that case you will need to notify the view that the paymentCollection property itself has changed. 在这种情况下,您将需要通知视图paymentCollection属性本身已更改。 In which case you should implement it as a notification property: 在这种情况下,应将其实现为通知属性:

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

Just do this the correct MVVM way. 只需以正确的MVVM方法执行此操作即可。 Get rid of your PopulateGrid method in the .xaml.cs file and eliminate setting the Click property in your xaml. 删除.xaml.cs文件中的PopulateGrid方法,并消除在xaml中设置Click属性的可能性。 Instead bind the command property of the button to an ICommand property in your ViewModel the same way you are binding the ItemsSource of the RadGridView. 而是以绑定RadGridView的ItemsSource的相同方式,将按钮的command属性绑定到ViewModel中的ICommand属性。 You will need an implementation of ICommand to use and MVVM Lights RelayCommand is one option for that. 您将需要实现ICommand才能使用,而MVVM Lights RelayCommand是其中一种选择。

Here is the code for the ICommand: 这是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
}

UPDATE 更新

To do this in code behind, you'll need to access the ViewModel and work on the collection from it. 要在后面的代码中执行此操作,您需要访问ViewModel并处理其中的集合。 I don't like this but it should work. 我不喜欢这样,但是应该可以。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM