【问题标题】:MVVM, XML, and Master/Detail ScenariosMVVM、XML 和主/详细方案
【发布时间】:2011-10-11 04:39:39
【问题描述】:

我正在使用 C# 编写我的第一个 MVVM 项目,这是一个非 MVVM 项目的转换,并且在每个角落都有问题。虽然我无法分享我使用的确切数据,但我想出了一个类似的方案来帮助解决我的问题。

这是数据:

   <Stock>
      <Container Store="Store1"
                 Aisle="1"
                 Shelf="2"
                 Name="Box1">
         <Item Name="GreenBeans"/>
         <Item Name="Carrots"/>
         ...
      </Container>
      <Container Store="Store3"
                 Aisle="4"
                 Shelf="6"
                 Name="Box2">
         <Item Name="Pillow"/>
         <Item Name="Blanket"/>
         ...
      </Container>
      ...
   </Stock>

可能会有数千个容器,每个容器包含 10-15 件物品。任何两个定位器(Store/Aisle/Shelf)可能是等效的,但不是所有三个(即一个容器可以存在于某个位置 Store -> Aisle -> Shelf)。

我目前的型号如下。这些不是完整的模型,但这让我知道我要去哪里。有可能,但不太可能,我需要知道特定商店或特定通道上的所有&lt;Item\&gt;。话虽如此,我必须拥有这些课程吗?

public class Store
{
   public String StoreName;
   public Aisles StoreAisles; 
}

public class Stores
{
   ObservableCollection<Store>
}

public class Aisle
{
   public int AisleNumber;
   public Shelfs AisleShelfs;
}

public class Aisles
{
   ObservableCollection<Aisle>
}

public class Shelf
{
  public int ShelfNumber;
  public Items ShelfItems;
}

public class Shelfs
{
   ObservableCollection<Shelf>
}

public class Item
{
   public string Name;
}

public class Items
{
   ObservableCollection<Item>
}

在主/从场景中将有三个组合框(商店、过道和货架)。将查询数据以告诉我哪些商店可用,商店的哪些过道正在使用,然后每个过道上正在使用哪些货架。一旦建立了&lt;Container\&gt;,那么该容器中的&lt;Item(s)\&gt; 将绑定到用户控件。

此时,我不确定如何处理数据。在走 MVVM 路线之前,我从每个 SelectedItem 中收集字符串并将其用作 XElement Linq 查询的输入。这将返回一个&lt;Container\&gt;,然后我将在其中查询&lt;Item(s)\&gt;

当我对任何组合框进行更改时,我想利用绑定并避免所有查询。如何使用绑定将选定的&lt;Container\&gt; 返回到视图模型中的属性?

欢迎所有帮助和建议!

【问题讨论】:

    标签: c# xml linq mvvm master-detail


    【解决方案1】:

    即使您在后面使用查询,您仍然可以使用绑定(为什么不使用) - 您只需触发正确的 INotifyPropertyChanges 作为一个 ComboBox-Changing 的结果(以及您的 ViewModel 中的绑定值) -像这样:

    public string SelectedStoreName
    {
       get { return _storeName; }
       set {
          if (!Equals(value, _storeName))
          {
             _storeName = value;
             _currentStore = FindStore(value);
             OnPropertyChanged("SelectedStoreName"); // invokes INotifyPropertyChanged
             OnPropertyChanged("AvaiableAisles");
          }
       }
    }
    
    public IEnumerable<Aisles> AvaiableAisles
    {
        get { return _currentStore.StoreAisles.ToArray(); }
    }
    
    /* same with the rest of your chain */
    

    请注意几点:

    • SelectedStoreName 应该绑定到您的 Store-Combobox 如果您不喜欢字符串部分更改它(但我认为没有必要)
    • AvaiableAisles 应该绑定到 Aisles-Combobox 的 Itemsource - 您需要一个 ItemTemplate 或 Aisles 中的正确 .ToString() 重载来显示您喜欢的内容。如果您不喜欢这种方法,请在.ToArray() 之前使用.Select(...) 更改AvaiableAisles 以选择一个字符串并将签名更改为IEnumerable&lt;string&gt; AvaiableAisles
    • 我不介意任何错误处理,例如使用_currentStore
    • 如果你还没有准备好,你必须实现 INotifyPropertyChanged
    • 您必须实现 FindStore - 这是查询部分的位置

    【讨论】:

    • 我正在尝试完全理解您在上面发布的 VM sn-p。您是否建议每次更改 Store 组合框时都会触发两个属性的 OnPropertyChanged 事件。那么当使用 Aisle 组合框进行选择时,您会触发 SelectedAisle 和 AvailableShelfs 的 OnPropertyChanged 事件,等等?
    • 另外,我开始使用 DependencyObjects 而不是 INotifyPropertyChanged 方法编写我的 VM。是否可以对 DO 使用相同的方法?
    • 您好,第一个问题:是的!如果您使用 DependencyObjects,这可能已经发生在您身上。但通常我更喜欢在我的 Viewmodels 上只实现 INotifyPropertyChanged。您只需确保在某些重要值发生更改时通知所有依赖项。
    猜你喜欢
    • 1970-01-01
    • 2016-08-16
    • 2011-01-30
    • 2013-09-14
    • 2012-08-19
    • 2010-10-13
    • 2011-02-11
    • 2011-10-05
    • 1970-01-01
    相关资源
    最近更新 更多