簡體   English   中英

檢測綁定到 DataGrid 的集合(元素)中的更改,以更新 WPF (MVVM) 中的其他 collections

[英]Detect changes in (elements of) a collection bound to a DataGrid to update other collections in WPF (MVVM)

響應式 UI 設計: DataGrid輸入自動引起更改 (MVVM)

我正在嘗試創建一個簡單的應用程序,其中我有一個圖表工具,它接受 collections 作為要繪制的系列。 我的計划是有一個輸入DataGrid綁定到可以手動填充的集合。

Based on the values inside the DataGrid , I would then like to simultaneously populate a different collection that represents the definite integral of whatever function is being plotted, in other words a different function that shows the area between the input function and the x-axis.

隨着DataGrid的更新,我也想使用 MVVM 來響應更新圖表,以顯示輸入數據和 output 數據的變化。

A. 應用部分(模型和結構)

到目前為止,我已經創建了一個包含我的實現的要點。

一、主要部件

簡而言之,該應用程序具有以下組件:

  • Coordinate<T, U>具有 X 和 Y 屬性(並使用INotifyPropertyChanged
  • ObservableCollection<Coordinate<double, double>>用於繪圖
  • 用於執行數值方法的NumericalCalculator

2.轉換器

在 WPF 聊天室中,Maverik 建議我可以使用值轉換器讓 WPF 完成繁重的工作,因此我編寫了以下轉換器:

  • CoordinateSeriesToStringConverter將坐標集合轉換為字符串,其中所有坐標用逗號分隔
  • FunctionToEquallySpacedConverter嘗試將坐標集合轉換為包含n個等距坐標的新集合
  • FunctionToIntegralConverter嘗試將輸入 function(坐標集合)積分到其兩個邊界之間的數值積分(目前尚未積分,用於測試目的)

B. 我的實際問題:如何檢測DataGrid的項目源元素的變化?

我已經走了值轉換器路線,但事實證明,即使在綁定的ObservableCollection的元素上實現了INotifyPropertyChanged ,這些更改也不會激活轉換器。

我已經用另一種方法從sparedev得到了一個很好的答案,我也可能會嘗試,但我仍然很好奇如何解決價值轉換器問題。 我敢肯定,如果我解決了這個問題,這兩種選擇都是同樣可行的。

更新:我嘗試了備用開發的方法,但即使使用INotifyPropertyChanged ,從 UI 操作DataGrid的項目也不會引發任何新事件。 添加新行或刪除它們會引發CollectionChanged事件,但不幸的是,僅此一項並不能讓我響應地更新繪圖。

讓我們注冊 CollectionChanged 事件並更新結果集合,見下文。

    public MainViewModel()
    {
      InputCollection.CollectionChanged += Items_CollectionChanged;
    }

    private void Items_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
    {
      if (e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Add)
      {
        foreach (var i in e.NewItems)
        {
          var c = i as Coordinate<double, double>;
          ResultCollection.Add(c);
          c.PropertyChanged += Item_PropertyChanged;
        }
      }

      if (e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Remove)
      {
        foreach (var i in e.OldItems)
        {
          var c = i as Coordinate<double, double>;
          ResultCollection.Remove(c);
          c.PropertyChanged += Item_PropertyChanged;
        }
      }
    }

    private void Item_PropertyChanged(object sender, PropertyChangedEventArgs e)
    {
      var c = sender as Coordinate<double, double>;
      Console.WriteLine(c.X + " " + c.Y);
    }

可能是您的坐標 class 應該實現 INotifyPropertyChanged 接口。 在設置 X 或 Y 屬性期間,應提高 PropertyChanged。

  public class Coordinate<T, U> : IComparable<Coordinate<T, U>>, INotifyPropertyChanged
    where T : IComparable<T>
    where U : IComparable<U>
  {
    public Coordinate() { }
    public Coordinate(T x, U y)
        => (X, Y) = (x, y);

    public event PropertyChangedEventHandler PropertyChanged;

    private T _X;
    public T X
    {
      get => _X;
      set
      {
        if (value.CompareTo(_X) != 0)
        {
          _X = value;
          PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(X)));
        }
      }
    }

    private U _Y;
    public U Y
    {
      get => _Y;
      set
      {
        if (value.CompareTo(_Y) != 0)
        {
          _Y = value;
          PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Y)));
        }
      }
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM