使用MVVM DataTriggers在WPF XAML视图之间切换/Window窗口自适应内容大小并居中

  1. 云栖社区>
  2. 博客>
  3. 正文

使用MVVM DataTriggers在WPF XAML视图之间切换/Window窗口自适应内容大小并居中

杰克.陈 2018-11-02 09:20:00 浏览470
展开阅读全文

原文 使用MVVM DataTriggers在WPF XAML视图之间切换

相关文章:

http://www.technical-recipes.com/2016/switching-between-wpf-xaml-views-using-mvvm-datatemplate/

这篇文章解决了能够根据ViewModel类的属性在不同视图之间切换的问题。

要开始使用Visual Studio,请创建一个新的WPF应用程序:

XamlSwitching1

因此,当我们构建并运行应用程序时,我们有一个这样的空白窗口:

XamlSwitching2

为了演示如何在不同视图之间切换WPF窗口,创建两个新的XAML视图View1.xaml和View2.xaml,每个视图由一个包含不同文本的简单TextBlock组成,以证明视图不同。

在Visual Studio项目中,右键单击项目文件夹,然后选择“添加”>“新建项”。选择用户控件(WPF)并将文件命名为View1.xaml:

XamlSwitching3

在文件的xaml部分中,插入代码以在视图中显示Text,如下所示:

<UserControl
    x:Class="MvvmSwitchViews.View1"
    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:ei="http://schemas.microsoft.com/expression/2010/interactions"
    xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
    xmlns:local="clr-namespace:MvvmSwitchViews"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    Width="800"
    Height="450"
    Background="Red"
    mc:Ignorable="d">
    <Grid>
        <Button
            Margin="10"
            HorizontalAlignment="Center"
            VerticalAlignment="Center"
            Content="  Screen for View2"
            FontSize="20">
            <i:Interaction.Triggers>
                <i:EventTrigger EventName="Click">
                    <ei:ChangePropertyAction
                        PropertyName="ContentTemplate"
                        TargetObject="{Binding ElementName=ct}"
                        Value="{DynamicResource View2Template}" />
                </i:EventTrigger>
            </i:Interaction.Triggers>
        </Button>
    </Grid>
</UserControl>

 

 

重复上一步,但这次创建一个名为View2.xaml的新视图。插入View2.xaml的代码,如下所示:

<UserControl
    x:Class="MvvmSwitchViews.View2"
    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:ei="http://schemas.microsoft.com/expression/2010/interactions"
    xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
    xmlns:local="clr-namespace:MvvmSwitchViews"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    Width="400"
    Height="200"
    Background="Green"
    mc:Ignorable="d">
    <Grid>
        <Button
            Margin="10"
            HorizontalAlignment="Center"
            VerticalAlignment="Center"
            Content="  Screen for View1"
            FontSize="20">
            <i:Interaction.Triggers>
                <i:EventTrigger EventName="Click">
                    <ei:ChangePropertyAction
                        PropertyName="ContentTemplate"
                        TargetObject="{Binding ElementName=ct}"
                        Value="{DynamicResource View1Template}" />
                </i:EventTrigger>
            </i:Interaction.Triggers>
        </Button>
    </Grid>
</UserControl>

 

 

我们可能希望根据类的属性在XAML视图之间切换。例如,如果我们的ViewModel属性设置为“0”,则显示View1; 否则,如果我们的ViewModel属性设置为“1”,则显示View 2。在这种情况下,您将使用DataTrigger。

右键单击项目文件夹,创建一个非常简单的ViewModel类,选择Add> New Item。选择Class,我们将调用我们的ViewModel类MainWindowViewModel.cs:

XamlSwitching4

我们的ViewModel类包含一个getter / setter属性和一个用于设置默认属性值的构造函数:

namespace MvvmSwitchViews
{
    public class MainWindowViewModel
    {
        public int SwitchView
        {
            get;
            set;
        }

        public MainWindowViewModel()
        {
            SwitchView = 1;
        }
    }
}

 

 

在我们的MainWindow.xaml中,我们使用我们创建的ViewModel类配置DataTemplate,DataContext。

还有DataTrigger,告诉应用程序显示哪个视图,如果属性设置为默认值以外的任何值:

<Window
    x:Class="MvvmSwitchViews.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:local="clr-namespace:MvvmSwitchViews"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    Title="MainWindow"
    local:CenterOnSizeChangeBehaviour.CenterOnSizeChange="True"
    SizeToContent="WidthAndHeight"
    WindowStartupLocation="CenterScreen"
    mc:Ignorable="d">
    <Window.DataContext>
        <local:MainWindowViewModel />
    </Window.DataContext>
    <Window.Resources>
        <DataTemplate x:Key="View1Template" DataType="{x:Type local:MainWindowViewModel}">
            <local:View1 />
        </DataTemplate>
        <DataTemplate x:Key="View2Template" DataType="{x:Type local:MainWindowViewModel}">
            <local:View2 />
        </DataTemplate>
    </Window.Resources>
    <Grid>
        <ContentControl x:Name="ct" Content="{Binding}">
            <ContentControl.Style>
                <Style TargetType="{x:Type ContentControl}">
                    <Setter Property="ContentTemplate" Value="{StaticResource View1Template}" />
                    <Style.Triggers>
                        <DataTrigger Binding="{Binding SwitchView}" Value="0">
                            <Setter Property="ContentTemplate" Value="{StaticResource View2Template}" />
                        </DataTrigger>
                    </Style.Triggers>
                </Style>
            </ContentControl.Style>
        </ContentControl>
    </Grid>
</Window>

 

 

在我们的ViewModel构造函数中,'SwitchView'属性默认为“0”,从而导致应用程序在运行时显示View1:

XamlSwitching5

现在在ViewModel构造函数中将'SwitchView'属性设置为“1”:

   public MainWindowViewModel()
        {
            SwitchView = 1;
        }

 

 

重新构建并重新运行应用程序时,我们将显示View2屏幕,如下所示:

XamlSwitching6

Window窗口自适应内容大小并居中

using System.Windows;

namespace MvvmSwitchViews
{
    public static class CenterOnSizeChangeBehaviour
    {
        /// <summary>
        /// Centers the window in the screen, when its changing its size.
        /// </summary>
        public static readonly DependencyProperty CenterOnSizeChangeProperty =
            DependencyProperty.RegisterAttached
            (
                "CenterOnSizeChange",
                typeof(bool),
                typeof(CenterOnSizeChangeBehaviour),
                new UIPropertyMetadata(false, OnCenterOnSizeChangePropertyChanged)
            );

        public static bool GetCenterOnSizeChange(DependencyObject obj)
        {
            return (bool)obj.GetValue(CenterOnSizeChangeProperty);
        }
        public static void SetCenterOnSizeChange(DependencyObject obj, bool value)
        {
            obj.SetValue(CenterOnSizeChangeProperty, value);
        }

        private static void OnCenterOnSizeChangePropertyChanged(DependencyObject dpo, DependencyPropertyChangedEventArgs args)
        {
            System.Windows.Window window = dpo as System.Windows.Window;
            if (window != null)
            {
                if ((bool)args.NewValue)
                {
                    window.SizeChanged += OnWindowSizeChanged;
                }
                else
                {
                    window.SizeChanged -= OnWindowSizeChanged;
                }
            }
        } 
        private static void OnWindowSizeChanged(object sender, SizeChangedEventArgs e)
        {
            System.Windows.Window window = (System.Windows.Window)sender; 
            window.WindowStartupLocation = WindowStartupLocation.Manual;
            window.Left = (SystemParameters.WorkArea.Width - window.ActualWidth) / 2 + SystemParameters.WorkArea.Left;
            window.Top = (SystemParameters.WorkArea.Height - window.ActualHeight) / 2 + SystemParameters.WorkArea.Top;
        }
    }
}

 

网友评论

登录后评论
0/500
评论
杰克.陈
+ 关注