wpf中,根据数据的值的不同,UI的界面随之改变(显示控件、隐藏控件以及改变控件的其它属性),
这时我们可以用DataTrigger数据触发器。
下面两个案例实现同样的功能,当条件(数据的值)不同时,显示不同的按钮。
创建 Core类:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.ComponentModel; namespace DataTriggerDemo2 { public class Core : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; public void OnPropertyChanged(string propertyName) { if (this.PropertyChanged != null) { this.PropertyChanged.Invoke(this, new PropertyChangedEventArgs(propertyName)); } } private string condition; public string Condition { get { return condition; } set { condition = value; OnPropertyChanged("Condition"); } } } }
XAML:
<Window x:Class="DataTriggerDemo2.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:DataTriggerDemo2" Title="MainWindow" Height="350" Width="525" Loaded="Window_Loaded"> <Window.Resources> <local:Core x:Key="core" /> <Style TargetType="{x:Type Button}"> <Setter Property="Margin" Value="5" /> <Setter Property="Padding" Value="0,8.5" /> <Setter Property="FontSize" Value="16" /> </Style> </Window.Resources> <Grid> <ContentControl> <ContentControl.ContentTemplate> <DataTemplate> <DockPanel LastChildFill="True" DataContext="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=Window, AncestorLevel=1}, Path=DataContext}"> <TextBlock DockPanel.Dock="Top" Text="按钮列表" HorizontalAlignment="Center" FontSize="18"/> <Border DockPanel.Dock="Right" Width="160"> <StackPanel Orientation="Vertical"> <TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" Foreground="Red" FontSize="16" Text="{Binding Source={StaticResource ResourceKey=core},Path=Condition}"/> <Button x:Name="btn1" Content="编辑按钮1" Visibility="Collapsed"/> <Button x:Name="btn2" Content="编辑按钮2" Visibility="Collapsed"/> <Button x:Name="btn3" Content="编辑按钮3" Visibility="Collapsed"/> <Button x:Name="btn4" Content="编辑按钮4" Visibility="Collapsed"/> </StackPanel> </Border> </DockPanel> <DataTemplate.Triggers> <DataTrigger Binding="{Binding Source={StaticResource ResourceKey=core},Path=Condition}" Value="条件1"> <Setter TargetName="btn1" Property="Visibility" Value="Visible"/> </DataTrigger> <DataTrigger Binding="{Binding Source={StaticResource ResourceKey=core},Path=Condition}" Value="条件2"> <Setter TargetName="btn1" Property="Visibility" Value="Visible"/> <Setter TargetName="btn2" Property="Visibility" Value="Visible"/> </DataTrigger> <DataTrigger Binding="{Binding Source={StaticResource ResourceKey=core},Path=Condition}" Value="条件3"> <Setter TargetName="btn1" Property="Visibility" Value="Visible"/> <Setter TargetName="btn2" Property="Visibility" Value="Visible"/> <Setter TargetName="btn3" Property="Visibility" Value="Visible"/> </DataTrigger> <DataTrigger Binding="{Binding Source={StaticResource ResourceKey=core},Path=Condition}" Value="条件4"> <Setter TargetName="btn1" Property="Visibility" Value="Visible"/> <Setter TargetName="btn2" Property="Visibility" Value="Visible"/> <Setter TargetName="btn3" Property="Visibility" Value="Visible"/> <Setter TargetName="btn4" Property="Visibility" Value="Visible"/> </DataTrigger> </DataTemplate.Triggers> </DataTemplate> </ContentControl.ContentTemplate> </ContentControl> </Grid> </Window>
C#:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; namespace DataTriggerDemo2 { /// <summary> /// MainWindow.xaml 的交互逻辑 /// </summary> public partial class MainWindow : Window { private Core core; public MainWindow() { InitializeComponent(); } private void Window_Loaded(object sender, RoutedEventArgs e) { core = this.FindResource("core") as Core; core.Condition = "条件3"; } } }
Loaded方法里赋值: core.Condition = "条件3",
则数据触发器触发相应的DataTrigger:
运行结果只显示三个按钮:
wpf的灵活之处在与,同样的效果可以用很多种方法实现。
下面介绍另一种实现方法:
首先创建wpf应用程序,引用下面两个dll:
Xaml头部引用名称空间:
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"
完整Xaml:
<Window x:Class="DataTriggerDemo.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions" xmlns:local="clr-namespace:DataTriggerDemo" Title="MainWindow" Height="350" Width="525" Loaded="Window_Loaded" DataContext="{DynamicResource ResourceKey=core}"> <Window.Resources> <local:Core x:Key="core" /> </Window.Resources> <Grid> <DockPanel LastChildFill="True" DataContext="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=Window, AncestorLevel=1}, Path=DataContext}"> <TextBlock DockPanel.Dock="Top" Text="按钮列表" HorizontalAlignment="Center" FontSize="18"/> <Border DockPanel.Dock="Right" Width="160"> <StackPanel Orientation="Vertical"> <TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="18" Text="{Binding Path=Condition}"/> <Button x:Name="btn1" Content="编辑按钮1" Visibility="Collapsed"/> <Button x:Name="btn2" Content="编辑按钮2" Visibility="Collapsed"/> <Button x:Name="btn3" Content="编辑按钮3" Visibility="Collapsed"/> <Button x:Name="btn4" Content="编辑按钮4" Visibility="Collapsed"/> </StackPanel> </Border> </DockPanel> <i:Interaction.Triggers> <ei:DataTrigger Binding="{Binding Path=Condition}" Value="条件1"> <ei:ChangePropertyAction TargetObject="{Binding ElementName=btn1}" TargetName="Button" PropertyName="Visibility" Value="Visible"/> <ei:ChangePropertyAction TargetObject="{Binding ElementName=btn2}" TargetName="Button" PropertyName="Visibility" Value="Visible"/> <ei:ChangePropertyAction TargetObject="{Binding ElementName=btn3}" TargetName="Button" PropertyName="Visibility" Value="Visible"/> <ei:ChangePropertyAction TargetObject="{Binding ElementName=btn4}" TargetName="Button" PropertyName="Visibility" Value="Visible"/> </ei:DataTrigger> <ei:DataTrigger Binding="{Binding Path=Condition}" Value="条件2"> <ei:ChangePropertyAction TargetObject="{Binding ElementName=btn2}" TargetName="Button" PropertyName="Visibility" Value="Visible"/> <ei:ChangePropertyAction TargetObject="{Binding ElementName=btn3}" TargetName="Button" PropertyName="Visibility" Value="Visible"/> <ei:ChangePropertyAction TargetObject="{Binding ElementName=btn4}" TargetName="Button" PropertyName="Visibility" Value="Visible"/> </ei:DataTrigger> <ei:DataTrigger Binding="{Binding Path=Condition}" Value="条件3"> <ei:ChangePropertyAction TargetObject="{Binding ElementName=btn3}" TargetName="Button" PropertyName="Visibility" Value="Visible"/> <ei:ChangePropertyAction TargetObject="{Binding ElementName=btn4}" TargetName="Button" PropertyName="Visibility" Value="Visible"/> </ei:DataTrigger> <ei:DataTrigger Binding="{Binding Path=Condition}" Value="条件4"> <ei:ChangePropertyAction TargetObject="{Binding ElementName=btn4}" TargetName="Button" PropertyName="Visibility" Value="Visible"/> </ei:DataTrigger> </i:Interaction.Triggers> </Grid> </Window>
C#:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; namespace DataTriggerDemo { /// <summary> /// MainWindow.xaml 的交互逻辑 /// </summary> public partial class MainWindow : Window { private Core core; public MainWindow() { InitializeComponent(); } private void Window_Loaded(object sender, RoutedEventArgs e) { core = this.FindResource("core") as Core; core.Condition = "条件3"; } } }
窗体的 loaded事件加载数据时设置 core.Condition = "条件3",
运行结果如下图:
与XAML里的数据触发器执行的预期效果是一样的: