WPF 使用UserControl / ContentControl显示子界面
想把一个东西很多的界面拆分一下,拆成几个小界面再拼接起来,脑袋里有UserControl / ContentControl这些概念,但是不知道具体怎么实现,记录一下两种方法:
法一:UserControl实现
主界面View:
<Page x:Class="Lithography.View.MainPage"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:telerik="http://schemas.telerik.com/2008/xaml/presentation"xmlns:lc="clr-namespace:FluentVision.Controls;assembly=FluentVision.Controls"xmlns:sonPage="clr-namespace:Lithography.View.SonPage"d:DesignHeight="600"d:DesignWidth="800"mc:Ignorable="d"><Grid><Grid.ColumnDefinitions><ColumnDefinition Width="*"/><ColumnDefinition Width="*"/></Grid.ColumnDefinitions><Grid.RowDefinitions><RowDefinition Height="*"/><RowDefinition Height="Auto"/></Grid.RowDefinitions><!-- 平台运动控制模块 --><sonPage:PlatformMovementControlPage Grid.Row="0" Grid.Column="0"DataContext="{Binding PlatformMovement}"Margin="5"/><!-- 真空控制模块 --><sonPage:VacuumControlPage Grid.Row="0" Grid.Column="1"DataContext="{Binding VacuumControl}"Margin="5"/><!-- IO状态显示模块 --><sonPage:IoStatusPage Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2"DataContext="{Binding IoStatus}"Margin="5"/></Grid>
</Page>
主界面ViewModel
using ReactiveUI;namespace Lithography.ViewModel
{public class MainViewModel : ReactiveObject{public PlatformMovementControlViewModel PlatformMovement { get; }public VacuumControlViewModel VacuumControl { get; }public IoStatusViewModel IoStatus { get; }public MainViewModel(){PlatformMovement = new PlatformMovementControlViewModel();VacuumControl = new VacuumControlViewModel();IoStatus = new IoStatusViewModel();}}
}
主界面声明这些子对象是为了给子界面提供数据源(DataContext绑定),也可以直接在子界面窗体构造函数中指定数据源:

当然还要集合具体使用的MVVM框架,寻求更好实现;
法二:ContentControl + DataTemplate
主界面View:
<Page x:Class="Lithography.View.MainPage"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:telerik="http://schemas.telerik.com/2008/xaml/presentation"xmlns:viewModels="clr-namespace:Lithography.ViewModel.SonPage"d:DesignHeight="600"d:DesignWidth="800"mc:Ignorable="d"><Page.Resources><!-- 定义 ViewModel 到 View 的映射 --><DataTemplate DataType="{x:Type viewModels:PlatformMovementControlViewModel}"><sonPage:PlatformMovementControlPage/></DataTemplate><DataTemplate DataType="{x:Type viewModels:VacuumControlViewModel}"><sonPage:VacuumControlPage/></DataTemplate><DataTemplate DataType="{x:Type viewModels:IoStatusViewModel}"><sonPage:IoStatusPage/></DataTemplate></Page.Resources><Grid><Grid.ColumnDefinitions><ColumnDefinition Width="*"/><ColumnDefinition Width="*"/></Grid.ColumnDefinitions><Grid.RowDefinitions><RowDefinition Height="*"/><RowDefinition Height="Auto"/></Grid.RowDefinitions><!-- 使用 ContentControl 自动选择模板 --><ContentControl Grid.Row="0" Grid.Column="0"Content="{Binding PlatformMovement}"Margin="5"/><ContentControl Grid.Row="0" Grid.Column="1"Content="{Binding VacuumControl}"Margin="5"/><ContentControl Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2"Content="{Binding IoStatus}"Margin="5"/></Grid>
</Page>
主界面ViewModel:
public class MainViewModel : ReactiveObject{public PlatformMovementControlViewModel PlatformMovement { get; }public VacuumControlViewModel VacuumControl { get; }public IoStatusViewModel IoStatus { get; }public MainViewModel(){PlatformMovement = new PlatformMovementControlViewModel();VacuumControl = new VacuumControlViewModel();IoStatus = new IoStatusViewModel();}}
ContentControl严格上来说也是一个控件,是常见的Button、ScrollViewer的基类:

ContentControl 的 Content 属性的类型为 Object(同样Button的Content也是,只不过常用来显示文本,也可以显示图片和其他布局控件等等),这里在主界面把ContentControl 的Content 绑定上后台子界面ViewModel,然后设置了ContentControl的ContentTemplate属性,
ContentTemplate是DataTemplate类型,注意上方xaml 窗体资源中定义的DataTemplate就是变相指定了ContentControl的ContentTemplate属性,还可以下面这样写:
<Window x:Class="_11_4.MainWindow"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"Title="MainWindow" Height="350" Width="525"><Window.Resources><DataTemplate x:Key="datatemplate1"><StackPanel Orientation="Horizontal"><CheckBox/><TextBlock Text=" Hello World"/></StackPanel></DataTemplate></Window.Resources><Grid><Button Content="Button" Height="23" HorizontalAlignment="Left" Margin="153,26,0,0" Name="button1" VerticalAlignment="Top" Width="130" ContentTemplate="{StaticResource datatemplate1}"/><Label Content="Label" Height="28" HorizontalAlignment="Left" Margin="153,68,0,0" Name="label1" VerticalAlignment="Top" Width="130" ContentTemplate="{StaticResource datatemplate1}"/><ScrollViewer Height="23" HorizontalAlignment="Left" Margin="153,127,0,0" Name="scrollViewer1" VerticalAlignment="Top" Width="120" ContentTemplate="{StaticResource datatemplate1}"/></Grid>
</Window>
或者:
<Button><Button.ContentTemplate><DataTemplate><StackPanel Orientation="Horizontal"><Image Source="/Icons/settings.png" Width="16" Height="16" Margin="0,0,5,0"/><TextBlock Text="设置" VerticalAlignment="Center"/></StackPanel></DataTemplate></Button.ContentTemplate>
</Button>
...很多种写法,想了解的话可以问一下AI,我就不愿意列举了。
部分代码引用自:https://blog.csdn.net/lzhui1987/article/details/51878861?fromshare=blogdetail&sharetype=blogdetail&sharerId=51878861&sharerefer=PC&sharesource=qq_59062726&sharefrom=from_link
