我有一个MVVM WPF应用程序,用于显示纸牌游戏的卡片。我只是将它们显示在屏幕上,但是对于许多卡片,它们都在可观察的集合中。但是,卡片都是不同的类型,它们都是从一个基类继承而来的。每种卡片类型与用户控件都有自己完全不同的视图。因此,根据我的经验,我明白我可以将ItemSource属性绑定到可观察集合,但是如何根据我的ItemSource中的项目类型指定使用某些用户控件?我推理我可以加载所有用户控制卡,并根据卡类型在转换器中打开或关闭每个控制器的可见性,但这听起来对我来说效率极低。任何人有任何想法?如何在XAML WPF窗口中使用动态元素
回答
您正在寻找DataTemplates。例如,假设您有以下类别:
public class MyViewModel
{
public List<PersonInfo> DataItems { get; }
= new List<PersonInfo>()
{
new AgeInfo() { Age = 25 },
new NameInfo() { Name = 13 }
};
}
public abstract class PersonInfo
{
}
public class AgeInfo : PersonInfo
{
public int Age { get; set; }
}
public class NameInfo : PersonInfo
{
public int Name { get; set; }
}
你可以有一个ItemsControl(或列表框,ListView控件等),根据该项目的数据类型显示每个项目:
<ItemsControl ItemsSource="{Binding DataItems}">
<ItemsControl.Resources>
<!-- Names are edited via textboxes -->
<DataTemplate DataType="{x:Type local:NameInfo}">
<StackPanel>
<Label>Name:</Label>
<TextBox Text="{Binding Name}" />
</StackPanel>
</DataTemplate>
<!-- Ages are edited via slider -->
<DataTemplate DataType="{x:Type local:AgeInfo}">
<StackPanel>
<Label>Age:</Label>
<Slider Minimum="0" Maximum="150" Value="{Binding Age}" />
</StackPanel>
</DataTemplate>
</ItemsControl.Resources>
</ItemsControl>
放置DataTemplate的位置取决于您,但只要它位于控件的资源层次结构中,就会使用它。
用于映射UI创建ResourceDictionary
(EI地图视图模型模型),并将其注册
XAML
<ResourceDictionary .....
xmlns:views="clr-namespace:...."
xmlns:viewModels="clr-namespace:...."
>
<DataTemplate DataType="{x:Type viewModels:viewModels1}">
<views:view1 />
</DataTemplate>
<DataTemplate DataType="{x:Type viewModels:viewModels2}">
<views:view2 />
</DataTemplate>
...
</ResourceDictionary>
C#
public static class ViewsMapping
{
private static bool _isUIMappingRegistered = false;
public static void Register()
{
if (!_isUIMappingRegistered)
{
ResourceDictionary MyResourceDictionary = new ResourceDictionary();
MyResourceDictionary.Source = new Uri(".....", UriKind.Relative);
Application.Current.Resources.MergedDictionaries.Add(MyResourceDictionary);
_isUIMappingRegistered = true;
}
}
}
的观察集合然后换为ObservableCollection<BaseClass>
,所选视图将显示派生类视图。
对于SO的要求,这似乎太过分了。他们不需要在自己的ResourceDictionary中,即使他们不需要将它合并到代码中,也可以将其添加到应用程序xaml中。 –
嗨马克,当然,你是对的,解决方案只需要'将ViewModel匹配到视图',但我仍然认为最优雅,有序和可维护的解决方案就是我的回答。 –
感谢您对这个答案的输入!虽然我确实喜欢这个解决方案的简单性,但是这个项目并没有创建/处理资源字典的能力。这有点奇怪,但是团队中的每个成员都具有某些他们可以做的事情,并且创建一个全球资源字典对于这个项目来说是不可能的。 – Chris
- 1. XAML C#按网格在窗口中元素的动态位置
- 2. wpf动态窗口
- 3. 如何在弹出窗口中动态创建HTML元素?
- 4. WPF中窗口元素的TabNavigation
- 5. WPF:使用XAML显示新窗口
- 6. 如何在C#中使用WPF在Xaml中绑定动态值#
- 7. C#WPF窗口不显示元素
- 8. 使用附加属性在XAML中动画WPF元素?
- 9. WPF动态GUI元素
- 10. 如何从父窗口动态创建子窗口中的元素
- 11. 使用WPF中的XAML动态样式
- 12. 如何在窗口中找到wpf元素的位置
- 13. 如何在单元测试项目中使用WPF窗口
- 14. 如何拖动窗口元素
- 15. WPF动态添加控件到窗口
- 16. 如何在WPF窗口中加载Xaml文件?
- 17. WPF窗口/用户控件继承XAML
- 18. C#WPF XAML窗口,消息框中
- 19. WPF - XAML页面中心到窗口
- 20. 如何在WPF中动态调整窗口的高度?
- 21. 如何在WPF中动态交换窗口内容
- 22. 如何仅使用XAML在我的Wpf窗口中显示位图图像?
- 23. 如何访问WPF弹出窗口中的元素?
- 24. WPF/Xaml - 获取动态元素的高度
- 25. WPF主题的动态窗口背景
- 26. 使用C#/ WPF遮罩窗口/画布的所有元素
- 27. 滚动窗口中的元素,该元素具有滚动条。
- 28. 从窗口中拖动窗口WPF
- 29. 使用窗口缩放所有屏幕元素vb.net wpf
- 30. 如何在XAML中使用WPF“行为”?
您声明每种卡类型的[DataTemplate](https://msdn.microsoft.com/library/ms742521(v = vs.100).aspx)。或者,如果卡片的类型都是相同的,但是在属性中指定了它们的类型,则可以使用[DataTriggers](http://www.wpf-tutorial.com/styles/trigger-datatrigger-event-trigger/)。 –