WPF / MVVM /内容控制
实现一个使用按钮在UserControls之间切换的应用:App Diagram
该方法将UserControlDataTemplates分配给不同的视图模型,并通过按钮切换视图模型。问题是每个UserControl都是重新示例化的,这会导致集成的旧版Windows窗体控件出现问题。有没有一种方法可以实现这种缓存UserControls的方法?我想我可以加载所有内容并更改可见性作为备用,但想知道是否有什么我错过了。
MainWindow.xaml
<Window x:Class="ContentControl.View.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:vm="clr-namespace:ContentControl.ViewModel"
xmlns:local="clr-namespace:ContentControl.View"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Window.DataContext>
<vm:MainViewModel/>
</Window.DataContext>
<Window.Resources>
<DataTemplate DataType="{x:Type vm:UC1ViewModel}">
<local:UC1UserControl/>
</DataTemplate>
<DataTemplate DataType="{x:Type vm:UC2ViewModel}">
<local:UC2UserControl/>
</DataTemplate>
</Window.Resources>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="50"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0">
<Button Command="{Binding UpdateContentCommand}" CommandParameter="uc1">UC 1</Button>
<Button Command="{Binding UpdateContentCommand}" CommandParameter="uc2">UC 2</Button>
</StackPanel>
<ContentControl Grid.Column="1" Content="{Binding SelectedViewModel}"/>
</Grid>
</Window>
UpdateContentCommand.cs
internal class UpdateContentCommand : ICommand
{
public event EventHandler? CanExecuteChanged;
private MainViewModel vm;
public bool CanExecute(object? parameter)
{
return true;
}
public void Execute(object? parameter)
{
if (parameter is string p)
{
if (p.ToLower() == "uc1")
{
vm.SelectedViewModel = vm.UC1VM;
}
else if (p.ToLower() == "uc2")
{
vm.SelectedViewModel = vm.UC2VM;
}
}
}
public UpdateContentCommand(MainViewModel vm)
{
this.vm = vm;
}
}
1条答案
按热度按时间gfttwv5a1#
您可以定义希望作为资源重用的控件示例。这样,XAML引擎将只创建一个共享示例。请记住,此示例只能添加到可视化树的 * 单个 * 位置。这意味着,你不能在
DataTemplate
中使用这个特定的示例,并使它成为例如StackPanel
同时。如果需要示例化DataTemplate
的多个示例(例如ListBox
中的项目),这也不起作用。另一种解决方案是创建一个控件来管理内容主机并生成/回收实际的数据容器(您的控件),就像
ListBox
所做的那样。这将给予你更多的灵活性。