我有一个传统的表单布局,顶部是菜单栏,底部是状态栏。当用户选择一个菜单项时,中间的空白区域(表单的整个剩余客户区域)将被替换为一个用户控件 - 请想象一下可以托管多种类型文档的SDI应用程序。
如果您知道更好的方法,请提出意见。目前,我正在尝试使用ContentControl创建一个非常简化的版本,但我无法在设置其DataContext时更新屏幕。
这是ViewModelA的非常简单的代码。除了Bs外,ViewModelB完全相同。
主窗口非常简单。它基本上声明了一个属性来保存托管控件的视图模型,并暴露了两个命令来分配视图模型A或B。
如果您知道更好的方法,请提出意见。目前,我正在尝试使用ContentControl创建一个非常简化的版本,但我无法在设置其DataContext时更新屏幕。
这是ViewModelA的非常简单的代码。除了Bs外,ViewModelB完全相同。
namespace Dynamic_ContentControl
{
public class ViewModelA: ViewModelBase
{
public ViewModelA()
{
DisplayName = "This is A";
}
}
}
主窗口非常简单。它基本上声明了一个属性来保存托管控件的视图模型,并暴露了两个命令来分配视图模型A或B。
namespace Dynamic_ContentControl
{
public class MainViewModel: ViewModelBase
{
private ViewModelBase clientContent = null;
public ICommand ShowA { get; private set; }
public ICommand ShowB { get; private set; }
public ViewModelBase ClientContent {
get
{
return clientContent;
}
private set
{
clientContent = value;
OnPropertyChanged("ClientContent");
}
}
public MainViewModel()
{
ShowA = new RelayCommand((obj) =>
{
ClientContent = new ViewModelA();
});
ShowB = new RelayCommand((obj) =>
{
ClientContent = new ViewModelB();
});
}
}
}
最后,XAML声明了一个ContentControl并将其ContentTemplate设置为名为ClientAreaTemplate的DataTemplate,它的ContentPresenter指向另一个名为TextBlockLayout的DataTemplate:
<Window x:Class="Dynamic_ContentControl.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vm="clr-namespace:Dynamic_ContentControl"
Title="MainWindow" Height="350" Width="525">
<Window.DataContext>
<vm:MainViewModel />
</Window.DataContext>
<Window.Resources>
<DataTemplate x:Key="TextBlockLayout">
<TextBlock Text="{Binding Path=DisplayName}" />
</DataTemplate>
<DataTemplate x:Key="ButtonLayout">
<Button Content="{Binding Path=DisplayName}" />
</DataTemplate>
<DataTemplate x:Key="CheckBoxLayout">
<CheckBox Content="{Binding Path=DisplayName}" />
</DataTemplate>
<DataTemplate x:Key="ClientAreaTemplate">
<ContentPresenter x:Name="ContentArea" ContentTemplate="{StaticResource ResourceKey=TextBlockLayout}"/>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding Path=DataContext}"
Value="{x:Type vm:ViewModelB}">
<Setter TargetName="ContentArea"
Property="ContentTemplate"
Value="{StaticResource ResourceKey=ButtonLayout}" />
</DataTrigger>
<DataTrigger Binding="{Binding Path=DataContext}"
Value="{x:Type vm:ViewModelB}">
<Setter TargetName="ContentArea"
Property="ContentTemplate"
Value="{StaticResource ResourceKey=CheckBoxLayout}" />
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</Window.Resources>
<Grid>
<Button Content="Show A"
Command="{Binding Path=ShowA}"
HorizontalAlignment="Left"
Margin="10,10,0,0"
VerticalAlignment="Top"
Width="75" />
<Button Content="Show B"
Command="{Binding ShowB}"
HorizontalAlignment="Left"
Margin="90,10,0,0"
VerticalAlignment="Top"
Width="75" />
<Label Content="{Binding Path=ClientContent.DisplayName}"
HorizontalAlignment="Left"
Margin="170,8,0,0"
VerticalAlignment="Top" />
<ContentControl DataContext="{Binding Path=ClientContent}"
Content="{Binding}"
ContentTemplate="{StaticResource ResourceKey=ClientAreaTemplate}"
HorizontalAlignment="Left"
Margin="10,37,0,0"
VerticalAlignment="Top"
Height="198"
Width="211" />
</Grid>
</Window>
期望的行为
当屏幕打开时,我希望 TextBoxLayout 显示。如果用户点击其中任何一个按钮,则应根据分配的实际运行时视图模型类型加载 ButtonLayout 或 CheckBoxLayout。
实际的行为
屏幕打开时 TextBoxLayout 被加载,但在单击按钮时它从未更改到另一种类型。
我认为问题在于 DataTrigger 尝试与类型进行比较的方式,但输出窗口中没有绑定消息。