在WPF应用程序开发中,经常需要在用户界面上显示状态信息。状态指示器是一种常见的UI元素,用于直观地表示对象的当前状态。本文将介绍如何使用WPFXAML来设计一个具有活动状态指示器的控件,包括如何使用多触发器来处理不同的状态。
首先,希望实现一个简单的状态循环,即当状态为真时显示绿色,为假时显示红色。为此,定义了一个数据网格列:
<DataGridTemplateColumn Header="Active">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ToggleButton Style="{StaticResource ToggleStyleLight}" IsChecked="{Binding IsActive, UpdateSourceTrigger=PropertyChanged}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
接着,定义了一个使用简单触发器的样式:
<Window.Resources>
<Style x:Key="ToggleStyleLight" TargetType="ToggleButton">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Border x:Name="innerBorder">
<Ellipse Fill="#60606000" Stroke="#FF000000" Stretch="Fill" x:Name="statusLight" Width="15" Height="15" Margin="2" VerticalAlignment="Center" HorizontalAlignment="Center" />
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<ControlTemplate.Triggers>
<Trigger Property="IsChecked" Value="True">
<Setter TargetName="statusLight" Property="Fill" Value="#FF00FF00" />
</Trigger>
<Trigger Property="IsChecked" Value="False">
<Setter TargetName="statusLight" Property="Fill" Value="#FFFF0000" />
</Trigger>
</ControlTemplate.Triggers>
</Style>
</Window.Resources>
这个简单的实现能够正常工作,但还需要解决两个问题:一是更新值在视图模型中不可靠地更新,二是当列被禁用时的处理。
为了解决这些问题,使用了多触发器。多触发器允许根据多个条件定义不同的视图。当开始使用多个条件时,就需要使用多触发器。
<DataGridTemplateColumn Header="Active" IsReadOnly="{Binding IsActivatable}">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ToggleButton Style="{StaticResource ToggleStyleLight}" IsChecked="{Binding IsActive, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" IsEnabled="{Binding IsActivatable}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
定义了一个使用多触发器的样式:
<Window.Resources>
<Style x:Key="ToggleStyleLight" TargetType="ToggleButton">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Border x:Name="innerBorder">
<Ellipse Fill="#60606000" Stroke="#FF000000" Stretch="Fill" x:Name="statusLight" Width="15" Height="15" Margin="2" VerticalAlignment="Center" HorizontalAlignment="Center" />
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<ControlTemplate.Triggers>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="ToggleButton.IsEnabled" Value="True" />
<Condition Property="ToggleButton.IsChecked" Value="True" />
</MultiTrigger.Conditions>
<MultiTrigger.Setters>
<Setter TargetName="statusLight" Property="Fill" Value="#FF00FF00" />
<Setter TargetName="statusLight" Property="Stroke" Value="#FF000000" />
</MultiTrigger.Setters>
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="ToggleButton.IsEnabled" Value="False" />
<Condition Property="ToggleButton.IsChecked" Value="True" />
</MultiTrigger.Conditions>
<MultiTrigger.Setters>
<Setter TargetName="statusLight" Property="Fill" Value="#60606000" />
<Setter TargetName="statusLight" Property="Stroke" Value="#FF00FF66" />
</MultiTrigger.Setters>
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="ToggleButton.IsEnabled" Value="True" />
<Condition Property="ToggleButton.IsChecked" Value="False" />
</MultiTrigger.Conditions>
<MultiTrigger.Setters>
<Setter TargetName="statusLight" Property="Fill" Value="#FFFF0000" />
<Setter TargetName="statusLight" Property="Stroke" Value="#FF000000" />
</MultiTrigger.Setters>
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="ToggleButton.IsEnabled" Value="False" />
<Condition Property="ToggleButton.IsChecked" Value="False" />
</MultiTrigger.Conditions>
<MultiTrigger.Setters>
<Setter TargetName="statusLight" Property="Fill" Value="#60606000" />
<Setter TargetName="statusLight" Property="Stroke" Value="#FFFF0066" />
</MultiTrigger.Setters>
</MultiTrigger>
</ControlTemplate.Triggers>
</Style>
</Window.Resources>