【问题标题】:Is it good practice to give the ObservableCollection extension some Lists? [closed]给 ObservableCollection 扩展一些列表是一种好习惯吗? [关闭]
【发布时间】:2021-05-07 04:49:10
【问题描述】:

我正在使用 MVVM 模式在 C# 中编写应用程序。

我的问题是:在我的模型中,我有一些扩展 ObservableCollection 的集合。将三个列表放在模型中的一个 ObservableCollection 中是一种好习惯吗?或者我应该如何实现?

假设我有一本带属性的书。这些书都分为两类(现实和虚构)。所以我会创建三个模型:

  1. BookCollection : ObservableCollection 列表小说 = new Listy(); 列出现实= new Listy();

  2. BookCollectionCollection : ObservableCollection

【问题讨论】:

  • 我会使用一个列表并使用 LINQ 来对付它。
  • 请出示可编译的代码。

标签: c# mvvm observablecollection


【解决方案1】:

简短回答:我认为您的模型中不应该有任何 ObservableCollections。模型都应该是需要最小结构完整性的简单类,例如字符串、整数,并且最多是一个 List 用于书籍集合。仅当您打算使用 3rd 方建模框架时才超出此范围,但我离题了。

长答案: MVVM 模式的关键是知道如何正确创建“关注点分离”。这意味着,了解您的模型、您希望这些模型如何在 UI 上显示/行为(即视图模型),以及您希望这些模型如何在 UI 上显示(即视图)。

你的模型是什么?

根据您最初的问题和描述,我想说您只有两个模型:

  1. 书籍(有一个名称,可能是一个 ID,一个 BookType 枚举器,如 Fiction/Reality/etc...)
  2. 书店(有一个名称和一个列表来代表他们的整个图书收藏,无论小说/现实/等等。)

你的 ViewModel 是什么?

  1. BookView 模型。您想从 Book 模型中公开哪些属性?也许它的所有属性,如 Name、ID 和 BookType。或者您可能只想公开 Name 和 BookType。这就是您使用此 ViewModel 保护模型免受直接访问或操纵的方式。
  2. 书店视图模型。这个视图模型的模型将是一个书店。但是您向 UI 公开的内容应该是:
    • 字符串名称(商店名称)
    • ObservableCollection 图书(商店的图书收藏)

你的观点是什么?

  1. 书店视图。这可能是一个包含商店名称文本框的控件,也可能是他们小说书籍的列表视图和现实书籍的另一个列表视图。

部分代码示例:请考虑这个伪代码,而不是可编译的示例。

型号:

public enum BookType
{
  Fiction,
  Reality,
  Other
}

public class Book
{
  public string ID { get; set; }
  public string Name { get; set; }
  public BookType BookType { get; set; }
}  

public class Bookstore
{
  public string Name { get; set; }
  public List<Book> Books { get; set; }
}

视图模型:

// Note: This view model may seem redundant and unnecessary, and 99% of the time it is.
// But by having this ViewModel, you can protect your Book model from direct manipulation,
// or make some properties read-only, etc.  I'm not doing it here, but I'm saying you could.
public class BookViewModel : INotifyPropertyChanged
{
  public Book Model { get; private set; }
  public BookViewModel(Book model)
  {
    Model = model;
  }

  public string Name { get => Model.Name; set { Model.Name = value; OnPropertyChanged(); }
  public string BookType { get => Model.BookType; set { Model.BookType = value; OnPropertyChanged(); }
}

public class BookstoreViewModel: INotifyPropertyChanged
{
  private ObservableCollection<BookViewModel> books = new ObservableCollection<BookViewModel>();

  public BookstoreViewModel(Bookstore model)
  {
    Model = model;
    foreach (var book in Model.Books)
    {
        books.Add(book);
    }
  }

  public ObservableCollection<BookViewModel> FictionBooks
  {
    get => books.Where(b => b.BookType == BookType.Fiction);
  }
  public ObservableCollection<BookViewModel> RealityBooks
  {
    get => books.Where(b => b.BookType == BookType.Reality);
  }
  public ObservableCollection<BookViewModel> OtherBooks
  {
    get => books.Where(b => b.BookType == BookType.Other);
  }
}

视图:这是一个 WPF 用户控件示例,用于显示有关书店及其书籍的详细信息。

<StackPanel>
  <TextBlock Text="{Binding Name}"/>
  <ListBox ItemsSource="{Binding FictionBooks}"/>
  <ListBox ItemsSource="{Binding RealityBooks}"/>
</StackPanel>

【讨论】:

  • 非常感谢您的精彩回答
猜你喜欢
  • 2020-02-06
  • 2014-12-22
  • 2013-03-30
  • 2017-06-14
  • 1970-01-01
  • 1970-01-01
  • 2015-02-18
  • 2016-03-20
  • 2020-08-25
相关资源
最近更新 更多