【问题标题】:Creating a ViewModel for each item of ItemsControl为 ItemsControl 的每一项创建一个 ViewModel
【发布时间】:2015-07-20 21:29:09
【问题描述】:


我定义了一个包含公共属性的类型 Board

ObservableCollection<Column> Columns

我想使用 MVVM 模式来显示它。 我创建了 BoardView 并将其绑定到 BoardViewModel。 BoardViewModel 公开了 Board 类型的公共属性 Board。 BoardView 包含一个控件 ItemsControl,它设置 ItemsSource={Binding Board.Columns}。

<ItemsControl ItemsSource="{Binding Board.Columns}">
<ItemsControl.ItemTemplate>
    <DataTemplate>
        <Border BorderThickness="2" Margin="10" BorderBrush="#9f9f9f" Width="250">
            <v:BoardColumnView Background="#e3e3e3" />
        </Border>
    </DataTemplate>
</ItemsControl.ItemTemplate>

BoardColumnView 应该显示 Column 类型的属性,并且效果很好。 我的问题是我想为 BoardColumn 创建一个 ViewModel,而不是只显示 Column 类型的属性,我想显示 BoardColumnViewModel 这将在 Column 属性中定义。 我怎样才能做到这一点? 提前致谢!

【问题讨论】:

  • 非常不清楚。为什么你不能像你在问题末尾写的那样在 Column 类中定义 BoardColumnViewModel?
  • 嗨,很抱歉描述不清楚,但我已经尽力了。我不能使用 Column 来保存 ColumnBoardViewModel,因为它是数据库实体。我只是想知道是否可以将 BoardColumnView.xaml.DataContext 绑定到 BoardColumnViewModel 并在 ItemsControl 中将 BoardColumnViewModel.Column 绑定到 ItemsControl.CurrentItem。
  • 嗨,它帮助并引导我在 Stackoverflow 上找到一些有趣的线程。谢谢

标签: c# wpf mvvm


【解决方案1】:

您可以简单地在您的BoardViewModel 中定义一个Columns 属性,该属性将包含BoardColumnViewModel 的集合。像这样的:

public ObservableCollection<BoardColumnViewModel> Columns { get; private set; }

您需要在BoardViewModel 中的某处初始化此属性,例如:

public BoardViewModel(...)
{
     ...
     Columns = new ObservableCollection<BoardColumnViewModel>(Board.Columns.Select(c => new BoardColumnViewModel(c)));
}

然后绑定到那个属性,而不是Board.Columns

<ItemsControl ItemsSource="{Binding Columns}">
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <Border BorderThickness="2" Margin="10" BorderBrush="#9f9f9f" Width="250">
                <v:BoardColumnView Background="#e3e3e3" />
            </Border>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

作为 MVVM 的一般原则,不建议直接绑定到模型。相反,您应该始终尝试绑定到视图模型。这就是您遇到所描述问题的原因 - 因为您绑定到公共属性 Board,这是您的模型。

【讨论】:

  • 嗨,我想过这样的解决方案,但我担心它是好还是坏的解决方案。你让我相信这是要走的路。感谢您提到不建议直接绑定到模型,我不知道这一点。非常感谢!
【解决方案2】:

在我的理解中BoardColumnView 是一个自己的UserControl?

如果是这样,只需在后面的代码中使用 this.DataContext = new BoardColumnViewModel(); 设置此 UserControl 的 DataContext 或使用 XAML 等效项。然后在您的BoardViewModel 中创建一个ObserveableCollection&lt;&gt;,其中包含BoardColumnView 的多个实例,并将ItemSource 设置为此集合。在您的BoardColumnView XAML 中定义您的布局、绑定等,这些将显示在BoardView 中。

因此,每次将BoardColumnView 添加到绑定到集合的 ItemsSource 时,都会创建一个新的 BoardColumnViewModel 实例。

...这是我对您的问题的理解,但我可能完全错了:)。

【讨论】:

  • 您好,谢谢您的回答。我是否正确理解了您的答案,您在 BoardViewModel 的正文中写道,我应该有一个 BoardColumnView 的集合(或者您的意思是 BoardColumnViewModel)?因为,在 ViewModel 中连接 BoardColumnView 违反了 MVVM 的整体理念。如果这只是一个错误,那么我认为这是一个很好的解决方案。非常感谢。
  • 是的,我这边的小错误。帕夫洛斯的答案是要走的路!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多