原文 使用MVVM DataTriggers在WPF XAML视图之间切换
相关文章:
http://www.technical-recipes.com/2016/switching-between-wpf-xaml-views-using-mvvm-datatemplate/
这篇文章解决了能够根据ViewModel类的属性在不同视图之间切换的问题。
要开始使用Visual Studio,请创建一个新的WPF应用程序:
因此,当我们构建并运行应用程序时,我们有一个这样的空白窗口:
为了演示如何在不同视图之间切换WPF窗口,创建两个新的XAML视图View1.xaml和View2.xaml,每个视图由一个包含不同文本的简单TextBlock组成,以证明视图不同。
在Visual Studio项目中,右键单击项目文件夹,然后选择“添加”>“新建项”。选择用户控件(WPF)并将文件命名为View1.xaml:
在文件的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:
我们的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:
现在在ViewModel构造函数中将'SwitchView'属性设置为“1”:
public MainWindowViewModel() { SwitchView = 1; }
重新构建并重新运行应用程序时,我们将显示View2屏幕,如下所示:
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; } } }