gpt4 book ai didi

C# MVVM 如何动态创建 View

转载 作者:太空宇宙 更新时间:2023-11-03 19:47:52 26 4
gpt4 key购买 nike

我正在尝试创建一个内存游戏,同时严格遵循 MVVM 模式来学习如何使用它。现在我在运行时创建 View 时遇到了问题。

我创建了以下项目结构:

  • 模型项目
  • -MemoryCardModel30
  • -名片
  • ViewModel 项目
  • -MainWindowViewModel
  • -CardViewModel
  • 查看项目
  • -CardView
  • 启动应用项目
  • -主窗口 View

依赖关系如下:StartApplication项目->View项目->ViewModel项目->Model项目

单击 MainWindowView 上的按钮后,MainWindowViewModel 中该按钮的 ICommand 函数将从模型项目加载 MemoryCardModel30 实例。对于 MemoryCardModel30 实例中的每个 Card,都会创建一个 CardViewModel。

现在我面临的问题是:如何创建 CardView 实例,如何将它们的 DataContext 链接到 CardViewModels 以及如何在 MainWindowView 上安排/分配 CardViews? ViewModel 项目无法创建 View ,因为它不依赖于 View 项目(会创建循环依赖并破坏模式)。如何在遵循 MVVM 模式的同时解决这个问题?

P.S.:CardViews 需要通过 x 和 y pos 精确定位。这将需要一些复杂的计算,这些计算应该通过相应的 CardViewModel。所以我认为像网格这样的一些基本布局是不够的。

最佳答案

ItemsControl 中显示它们.我假设 MainWindowViewModel.CardsObservableCollection<CardViewModel> .

<ItemsControl
ItemsSource="{Binding Cards}"
>
<!--
This creates UI for each item. There are other ways, if you've got a collection
of heterogeneous item types.
-->
<ItemsControl.ItemTemplate>
<DataTemplate DataType="local:CardViewModel">
<views:CardView />
</DataTemplate>
</ItemsControl.ItemTemplate>

<!--
Make it use a Canvas to be the actual container for the items, so we can control
their position arbitrarily, instead of the default StackPanel that just stacks
them up vertically.
-->
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>

<!--
The ItemsControl will put the instantiated item templates in ContentPresenters
that it creates. The positioning attributes have to go on the ContentPresenters,
because those are the direct children of the Canvas. The ContentPresenters are
the "item containers". You can customize them via the ItemContainerStyle property
of the ItemsControl.
-->
<ItemsControl.ItemContainerStyle>
<Style TargetType="ContentPresenter">
<!--
The datacontext will be CardViewModel.

Bind Canvas.Left and Canvas.Top to appropriate properties
of CardViewModel. I'll assume it's got Point Position { get; }

A much better, more "pure MVVM" way to do this is for the items to
provide some kind of abstraction, maybe row/column or something else,
and either place them in a Grid or UniformGrid or some other kind of
dynamic layout control, or else convert that abstraction into Canvas
coordinates with a value converter on the Binding.

Then you can display the same item objects in different ways at the same
time without locking them into one layout.

Don't drive yourself crazy striving for ideological purity at the expense
of getting code out the door, but do consider redesigning that part.
-->

<Setter Property="Canvas.Left" Value="{Binding Position.X}" />
<Setter Property="Canvas.Top" Value="{Binding Position.Y}" />
</Style>
</ItemsControl.ItemContainerStyle>

这是在 WPF/MVVM 中执行此操作的规范方法。使用 DataTemplate s 创建适当类型的 View 实例。 View 模型负责应该向用户呈现哪些对象; View 负责它们的显示方式。您不需要或不需要为此使用任何 MVVM 框架。内置 DataTemplate WPF 的功能非常强大。不要相信任何认为您需要为这个规模的两个数量级以内的项目提供任何其他东西的人。

关于C# MVVM 如何动态创建 View ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43053302/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com