【发布时间】:2013-12-03 23:44:10
【问题描述】:
我编写了一个工具,其中 ListBox 绑定到 ObserservableCollection<object>,并具有我定义的不同数据类型。我使用PropertyDataTemplateSelector 来呈现ListBox 中的数据。 PropertyDataTemplateSelector 引用了几个设置为UserControls 的DataTemplates。有一个后台类通过检查object 类型然后应用正确的DataTemplate 为PropertyDataTemplateSelector 提供逻辑。
这是UserControls 和MainWindow 的XAML 的缩写示例。
用户控件1
<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>
用户控制N
<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。 UserControls 被移出以使 XAML 更易于阅读/导航。实际上,每个 UserControl 有几百行。
<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# 项目)中,我想继续探索如何使我的代码“更好”(无论如何定义) .我不想在这里解决错误。所以为了避免一个一般/广泛的问题,我会问我想知道什么。有人可以纠正我,我会适当地更新“问题”
问题:我怎样才能为每个UserControls 生成一个ViewModel?某些ViewModels,对于UserControls,偶尔需要与MainWindow_ViewModel 进行双向通信。我的问题的主要症结在于弄清楚多个虚拟机将如何通信。
【问题讨论】:
标签: c# wpf mvvm listbox viewmodel