- A+
所属分类:.NET技术
一 引入
在设计设备界面时,经常会有一种需求,展示一个阀门,阀门有通断两种状态:
二 CommonValveControl
考虑实现一个自定义控件,CommonValveControl。
使用自定义控件比用户控件更灵活,更具扩展性,可以使用不同的样式和模板。
CommonValveControl定义两个依赖属性,Orientation表示安装展示的方向,Status表示阀门的通断状态。
public class CommonValveControl : Control { static CommonValveControl() { DefaultStyleKeyProperty.OverrideMetadata(typeof(CommonValveControl), new FrameworkPropertyMetadata(typeof(CommonValveControl))); } public bool Status { get => (bool)GetValue(StatusProperty); set => SetValue(StatusProperty, value); } public static readonly DependencyProperty StatusProperty = DependencyProperty.Register( "Status", typeof(bool), typeof(CommonValveControl)); public Orientation ValveOrientation { get => (Orientation)GetValue(CommonValveOrientationProperty); set => SetValue(CommonValveOrientationProperty, value); } public static readonly DependencyProperty CommonValveOrientationProperty = DependencyProperty.Register( "ValveOrientation", typeof(Orientation), typeof(CommonValveControl)); }
设计CommonValveControl的样式模板,可通过设计不同的模板,以呈现出不同的效果。
通过ValveOrientation属性触发切换阀门的竖直状态和水平状态。
<Style TargetType="{x:Type local:CommonValveControl}"> <Setter Property="Cursor" Value="Hand" /> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type local:CommonValveControl}"> <Viewbox Stretch="Fill"> <Grid> <Canvas Width="40" Height="40" > <Ellipse Height="40" Width="40" Fill="Gray"/> <Ellipse x:Name="InnerEllipse" Height="30" Width="30" Canvas.Left="5" Canvas.Top="5" <Rectangle x:Name="Rectangle" Fill="White" RadiusX="2" RadiusY="2"/> </Canvas> </Grid> </Viewbox> <ControlTemplate.Triggers> <Trigger Property="Status" Value="false"> <Setter TargetName="InnerEllipse" Property="Fill" Value="Red"/> </Trigger> <Trigger Property="Status" Value="true"> <Setter TargetName="InnerEllipse" Property="Fill" Value="Green"/> </Trigger> <MultiTrigger> <MultiTrigger.Conditions> <Condition Property="ValveOrientation" Value="Horizontal"/> <Condition Property="Status" Value="false"/> </MultiTrigger.Conditions> <Setter TargetName="Rectangle" Property="Width" Value="6"/> <Setter TargetName="Rectangle" Property="Height" Value="30"/> <Setter TargetName="Rectangle" Property="Canvas.Left" Value="17"/> <Setter TargetName="Rectangle" Property="Canvas.Top" Value="5"/> </MultiTrigger> <MultiTrigger> <MultiTrigger.Conditions> <Condition Property="ValveOrientation" Value="Horizontal"/> <Condition Property="Status" Value="true"/> </MultiTrigger.Conditions> <Setter TargetName="Rectangle" Property="Width" Value="30"/> <Setter TargetName="Rectangle" Property="Height" Value="6"/> <Setter TargetName="Rectangle" Property="Canvas.Left" Value="5"/> <Setter TargetName="Rectangle" Property="Canvas.Top" Value="17"/> </MultiTrigger> <MultiTrigger> <MultiTrigger.Conditions> <Condition Property="ValveOrientation" Value="Vertical"/> <Condition Property="Status" Value="false"/> </MultiTrigger.Conditions> <Setter TargetName="Rectangle" Property="Width" Value="30"/> <Setter TargetName="Rectangle" Property="Height" Value="6"/> <Setter TargetName="Rectangle" Property="Canvas.Left" Value="5"/> <Setter TargetName="Rectangle" Property="Canvas.Top" Value="17"/> </MultiTrigger> <MultiTrigger> <MultiTrigger.Conditions> <Condition Property="ValveOrientation" Value="Vertical"/> <Condition Property="Status" Value="true"/> </MultiTrigger.Conditions> <Setter TargetName="Rectangle" Property="Width" Value="6"/> <Setter TargetName="Rectangle" Property="Height" Value="30"/> <Setter TargetName="Rectangle" Property="Canvas.Left" Value="17"/> <Setter TargetName="Rectangle" Property="Canvas.Top" Value="5"/> </MultiTrigger> </ControlTemplate.Triggers> </ControlTemplate> </Setter.Value> </Setter> </Style>
三 效果演示
Xaml代码:
<Canvas> <local:PipeControl Width="106" Height="14" Canvas.Left="26" Canvas.Top="53"/> <local:PipeControl Width="14" Height="80" Canvas.Left="185" Canvas.Top="22" Orientation="Vertical"/> <local:CommonValveControl x:Name="valve1" Status="False" ValveOrientation="Horizontal" Width="40" Height="40" Canvas.Left="60" Canvas.Top="41"/> <local:CommonValveControl x:Name="valve2" Status="False" ValveOrientation="Vertical" Width="40" Height="40" Canvas.Left="172" Canvas.Top="41"/> <Button Content="Open" Click="OpenButton_Click" Canvas.Left="272" Canvas.Top="15" Width="66" Height="35"/> <Button Content="Close" Click="CloseButton_Click" Canvas.Left="272" Canvas.Top="71" Width="66" Height="35"/> </Canvas>
后台代码:
public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); } private void OpenButton_Click(object sender, RoutedEventArgs e) { valve1.Status = true; valve2.Status = true; } private void CloseButton_Click(object sender, RoutedEventArgs e) { valve1.Status = false; valve2.Status = false; } }