我编写了一个工具,其中ListBox绑定到ObserservableCollection<object>
,并且我定义了不同的数据类型。我使用PropertyDataTemplateSelector
在ListBox中显示数据。 PropertyDataTemplateSelector
引用了设置为DataTemplates
的多个UserControls
。有一个后台类通过检查PropertyDataTemplateSelector
类型然后应用正确的object
为DataTemplate
提供逻辑。
以下是UserControls
和MainWindow
的XAML缩写示例。
的UserControl1
<TextBlock Text="{Binding Path=Val1}"
Style="{StaticResourse Yes}" />
<Button Content="I'm Button 1"
Command="{Binding Path=PathtoCommand1}"
CommandParameter="{Binding Parameter1}"
IsEnabled="{Binding IsEnabled1}" />
<Button Content="I'm Button 2"
Command="{Binding Path=PathtoCommand2}"
CommandParameter="{Binding Parameter2}"
IsEnabled="{Binding IsEnabled2}"
Tag="{Binding Path="DataContext.TagItem2}">
<Button.ContextMenu>
<ContextMenu>
<MenuItem IsCheckable="True"
IsChecked="{Binding Path=Tag}"
DataContext="{Binding Path=PlacementTarget, RelativeSource={RelativeSource AncestorType={x:Type ContextMenu}}}" />
</ContextMenu>
</Button.ContextMenu>
</Button>
</StackPanel>
</UserControl>
UserControlN
<UserControl x:Class="AwesomerControl">
<StackPanel Orientation="Vertical">
<TextBlock Text="{Binding Path=FancyName2}"
Style="{StaticResourse Yes}" />
<Button Content="Clicker 1"
Command="{Binding Path=DoSomethingGreat1}"
CommandParameter="{Binding Greatness1}"
IsEnabled="{Binding IsTurnedOn1}" />
<Button Content="Clicker 2"
Command="{Binding Path=DoSomethingGreat2}"
CommandParameter="{Binding Greaterness2}"
IsEnabled="{Binding IsTurnedOn2}"
Tag="{Binding Path="DataContext.TagItem2}">
<Button.ContextMenu>
<ContextMenu>
<MenuItem IsCheckable="True"
IsChecked="{Binding Path=Tag}"
DataContext="{Binding Path=PlacementTarget, RelativeSource={RelativeSource AncestorType={x:Type ContextMenu}}}" />
</ContextMenu>
</Button.ContextMenu>
</Button>
</StackPanel>
</UserControl>
在此,我将UserControls
设置为指定的DataTemplate
。移出UserControl以使XAML更易于阅读/导航。实际上,UserControls各有几百行。
<Window.Resources>
<DataTemplate x:Key"Template1">
<customControls:AwesomeControl/>
</DataTemplate>
...
<DataTemplate x:Key"TemplateN">
<customControls:AwesomerControl/>
</DataTemplate>
<dts:PropertyDataTemplateSelector x:Key="templateselector"
Template1="{StaticResource Template1"}
...
TemplateN="{StaticResource TemplateN"}
</Window.Resources>
ListBox
被定义为此。
<ListBox ItemSource="{Binding Path=CollectionofMyObjects}"
ItemTemplateSelector="{StaticResource templateselector}" />
我使用一个ViewModel
来推动MainWindow
和UserControls
。
所以这就是我所处的位置。我现在正在按照我的意愿工作,但是在不断努力学习(这是我的第一个MVVM / WPF / C#项目)我想继续探索如何让我的代码“更好”(不过那是定义的) 。我不打算在这里解决错误。因此,为了避免一般/广泛的问题,我会问我想知道什么。有人可以纠正我,我会适当地更新“问题”
问题:如何为每个ViewModel
制作UserControls
? ViewModels
的某些UserControls
偶尔需要与MainWindow_ViewModel
进行双向通信。我的问题的主要症结是弄清楚多个虚拟机将如何通信。
答案 0 :(得分:1)
你很接近,但它还不是相当 MVVM。 ;)
UserControl
相关的所有功能分解到自己的类中。这些是您的视图模型类。DataTemplate.DataType
自动将视图模型类类型连接到其视图,而不是使用模板选择器。视图模型之间有很多通信选项。为了进一步提高你的教育水平,我会考虑一个具有内置通信解决方案的轻量级MVVM框架。我个人最喜欢的是Caliburn.Micro,其中包含一个EventAggregator
服务,该服务能够以松散耦合的方式将对象从一个视图模型发布到另一个视图模型。
继续学习,你走在正确的轨道上!