[WPF] 区域导航的简单实现

区域导航的简单实现

在学习Prism的时候不知道Prism的区域导航是如何实现的,然后看了一些讲解,下面是自己的一些总结。

这次的总结中主要包含如下的知识点:

1、DataTemplate 以及 DataType
2、ContentControl

什么是DataType?

DataTemplate中的DataType的功能实际上和Style中的TargetType很类似。

在Style中,使用了TargetType之后,如果不定义Style的Key,那么这个Style将会影响到它所在区域的所有TargetType控件的样式。

同理,在DataTemplate中,使用了DataType之后,如果不定义DataTemplate的Key,那么这个DataTemplate将应用于它所在区域,所有的以这个DataType为数据源的控件。

首先我们创建一个WPF项目:

image

这是项目结构,其中每个ViewModel都继承了Prism的 BindableBase ,这里用 Prism 主要是为了简单的使用它的MVVM框架。

US1ViewModel 页面中,我简单的讲其页面的颜色设置为红色:

<UserControl x:Class="BlankApp5.Views.US1View"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:BlankApp5.Views"
             mc:Ignorable="d" 
             d:DesignHeight="450" d:DesignWidth="800">
    <Grid Background="Red">
            
    </Grid>
</UserControl>

US2ViewModel页面中,我简单的将其页面的颜色设置为黄色:

<UserControl
    x:Class="BlankApp5.Views.US2View"
    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:local="clr-namespace:BlankApp5.Views"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    d:DesignHeight="450"
    d:DesignWidth="800"
    mc:Ignorable="d">
    <Grid Background="Yellow" />
</UserControl>

在MainWindows中,我创建了两个DataTemple 并将其 DataType 设置为 两个Usercontrol 的Viewmodel :

    xmlns:v="clr-namespace:BlankApp5.Views"
    xmlns:vm="clr-namespace:BlankApp5.ViewModels" 

<Window.Resources>
        <DataTemplate DataType="{x:Type vm:US1ViewModel}">
            <v:US1View />
        </DataTemplate>
        <DataTemplate DataType="{x:Type vm:US2ViewModel}">
            <v:US2View />
        </DataTemplate>
 </Window.Resources>

然后设置了一个简单的页面,如下图所示:

image

对应的代码:

<Window
    x:Class="BlankApp5.Views.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:m="clr-namespace:Module1;assembly=Module1"
    xmlns:m11="clr-namespace:Module1.Views;assembly=Module1"
    xmlns:prism="http://prismlibrary.com/"
    xmlns:v="clr-namespace:BlankApp5.Views"
    xmlns:vm="clr-namespace:BlankApp5.ViewModels"
    Title="{Binding Title}"
    Width="1200"
    Height="800"
    prism:ViewModelLocator.AutoWireViewModel="True">
     <Window.Resources>
        <DataTemplate DataType="{x:Type vm:US1ViewModel}">
            <v:US1View />
        </DataTemplate>
        <DataTemplate DataType="{x:Type vm:US2ViewModel}">
            <v:US2View />
        </DataTemplate>
    </Window.Resources>

    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="50"/>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <Button Grid.Row="0" Grid.Column="0" Content="us1" Command="{Binding NagiveCommand}" CommandParameter="us1">
            
        </Button>

        <Button Grid.Column="2" Grid.Row="0" Content="us2" Command="{Binding NagiveCommand}" CommandParameter="us2"/>

        <ContentControl Content="{Binding ContentViewModel}" Grid.Row="1" Grid.ColumnSpan="3"/>

    </Grid>

</Window>

对应的MainWindowViewModel代码为:

using Module1.Common;
using Module1.Views;
using Prism.Commands;
using Prism.Ioc;
using Prism.Mvvm;
using Prism.Regions;
using System;

namespace BlankApp5.ViewModels
{
    public class MainWindowViewModel : BindableBase
    { 
        public MainWindowViewModel()
        {
        	NagiveCommand = new DelegateCommand<string>(Nagive);
        }
        
         private void Nagive(string obj)
        {
            switch (obj)
            {
                case "us1":
                    ContentViewModel = US1ViewModel;
                    break;
                case "us2":
                    ContentViewModel = US2ViewModel;
                    break;
                default:
                    break;
            }
        }
        
        public DelegateCommand<string> NagiveCommand { get; set; }
        US1ViewModel US1ViewModel = new US1ViewModel();
        US2ViewModel US2ViewModel = new US2ViewModel();


        private BindableBase _ContentViewModel;
        public BindableBase ContentViewModel
        {
            get { return _ContentViewModel; }
            set { SetProperty(ref _ContentViewModel, value); }
        }

上面的代码的意思为,当点击按钮的时候,触发NagiveCommand命令从而触发Nagive 方法,然后根据按钮所带的参数对 ContentViewModel 的值

进行设置,选择的参数不同,绑定的ViewModel也不同,在前端代码中,因为DataTemple 没有设置 自己的Key 那么这个数据模板将对所有的DataType 为这个类型所有的Control 应用这个DataTemple ,所以这里的CententControl 将会根据Centent 属性所Binding 不同的ViewModel 而选择不同的DataTemple ,再显示不同的View。

posted @ 2021-12-06 23:51  干杯Archer  阅读(293)  评论(0编辑  收藏  举报