【问题标题】:Updating ObservableCollection using delegates in MVVM?在 MVVM 中使用委托更新 ObservableCollection?
【发布时间】:2015-01-07 10:41:37
【问题描述】:

我有三个 ViewModel:MainViewModel、PreferencesViewModel 和 ColourControllerViewModel - 后两个是 MainViewModel 的属性。

ColourControllerViewModel 用于“ColourSelector”视图,可以在其中创建和删除各种颜色。它包含一个 ColourViewModel 的 ObservableCollection,它有一个详细说明颜色的属性和一个布尔属性,用于确定它是否应该显示在首选项选项卡 (DisplayOnPreferences) 上。

PreferencesViewModel 用于“Preferences”视图,其中包含一个颜色组合框 - 这由 ColourViewModel 的 ObservableCollection 表示,并且仅应显示 DisplayOnPreferences == true 的那些 ColourViewModel。

我的问题是,最简单的方法是什么?目前,我正在使用一个名为 UpdateList() 的 Action 委托,它将更新后的列表从 ColourControllerViewModel 传递到 MainViewModel,而 MainViewModel 又会更新 PreferencesViewModel。不过我不是很喜欢这样,感觉有更好的方法。

是否应该在 MainViewModel 上存在由任一实例更新/访问的 ColourViewModel 的单个 ObservableCollection?

以下是课程:

public class MainViewModel : ViewModel
{
      private ColourMappingControllerViewModel _colourMappingControllerViewModel;
      private PreferencesControllerViewModel _preferencesTabViewModel;


      public MainViewModel()
      {
        // Initialise the database Handler
        dbHandler = DatabaseHandler.DbHandlerInstance;

        _colourMappingControllerViewModel = new ColourMappingControllerViewModel(dbHandler.GetColourMappingsList(), UpdateColourList);
        _preferencesTabViewModel = new PreferencesControllerViewModel(dbHandler.GetPreferences, ColourMappingList)    
       }

      public ObservableCollection<ColourMappingViewModel> ColourMappingList
      {
          get { return ColourMappingControllerViewModel.ColourMappingList; }        
      }


      public void UpdateColourList(ObservableCollection<ColourMappingViewModel> colourList)
      {
          PreferencesTabViewModel.UpdateColourList(colourList);
      }       
}

public class ColourMappingControllerViewModel : ViewModel
{

    public ColourMappingControllerViewModel(IEnumerable<ColourMapping> colourMappingsList,  Action<ObservableCollection<ColourMappingViewModel>> updateColourListAction)
    {
        InitialiseCommands();
        ColourMappingList = new ObservableCollection<IColourMappingViewModel>(InitialiseColourMappingsList(colourMappingsList));
    }

    public ICommand AddColourMappingCommand { get; set; }
    private void InitialiseCommands()
    {
        AddColourMappingCommand = new DelegatingCommand(AddColourMapping);
    }
    private void AddColourMapping() // Attached to Command on View
    {
        var newColourMapping = new ColourMappingViewModel(
            new ColourMapping());
        ColourMappingList.Add(newColourMapping);
        ColourMappingsCollectionView.MoveCurrentToLast();
        UpdateColourMappingList();
    }


    private void UpdateColourMappingList()
    {
        UpdateColourListAction.Invoke(ColourMappingList);
    }
}


public PreferencesControllerViewModel : ViewModel
{

    public PreferencesControllerViewModel(object preferenceInfo, ObservableCollection<ColourMappingViewModel> colourMappingsList)
    {
        var pciTrendBlocks = pciBlocks;
        ColourMappingsList = colourMappingsList;            
    }

    public void UpdateColourList(ObservableCollection<ColourMappingViewModel> colourList)
    {
        ColourMappingsList = colourList;
    }    

}

我知道 ObservableCollection 类被滥用了——它可能在 Preferences 上没有必要,因为它只会在 ColourMappingController 中更新。

【问题讨论】:

    标签: c# wpf mvvm delegates observablecollection


    【解决方案1】:

    我同意您需要一个在视图之间共享的ObservableCollection。这有效地成为您在 MVVM 中的“模型”。

    您可能还希望通过将ReadOnlyObservableCollection 传递给您的首选项VM 等来强制执行不同的访问语义。这确保只有ColourControllerViewModel(获取底层ObservableCollection)才能实际更改集合。

    在我的应用程序中,我倾向于有一个单独的数据层,但是是的,目前最简单的方法是将它们添加到 MainViewModel

    另一种方法是让ColourControllerViewModel 成为拥有该集合的东西(并将其公开为ReadOnlyObservableCollection),让您MainViewModel 将集合传递给任何其他需要它的VM。

    【讨论】:

    • 我的问题是如何传递 ObservableCollection?我试图更新的前一段代码实际上将 mainViewModel 的实例传递给了 Preferences 和 ColourController,这是我试图避免的。
    • 不,不传递虚拟机,只传递集合。例如,您的 Preferences VM 将 ReadOnlyObservableCollection 作为构造函数参数。
    • 我会试一试,干杯 - 虽然我不是 100% 知道为什么会这样 - 大概在 MainVM 中创建它,将它传递给 Pref & Colour,并且任何颜色的更新都应该体现在 Pref.
    • 它将起作用,因为 ObservableCollection 在其内容更改时会触发通知。颜色会更新它,会触发一个通知,并且 Pref 视图绑定将作为响应更新。
    • 啊,那好吧。就 ObservableCollection 而言,它可以工作,但困难在于该列表不应显示所有 ObservableCollection - 仅显示 DisplayOnTrend == true 的子集。我不确定如何最好地实现这一目标......
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-06
    • 2011-08-25
    相关资源
    最近更新 更多