首页 > 其他分享 >WPF开发经验-实现一种机械泵控件

WPF开发经验-实现一种机械泵控件

时间:2023-01-28 17:34:44浏览次数:47  
标签:控件 int 机械泵 State typeof WPF public MechanicalPumpControl

一 引入

考虑实现一种机械泵控件。

机械泵是工业中通常用来制造真空的一类设备,我们在绘制界面UI时希望可以生动形象地来表述一个机械泵,下面讲述了一种简单的实现。

二 MechanicalPumpControl

声明一个MechanicalPumpControl的自定义控件,它继承自Control类。

对于一个MechanicalPump来说,它具有状态,这里定义一个State依赖属性来简单描述泵的状态,State等于0表示泵停止状态,State等于1表示泵运行状态。

State可以绑定到实际的泵状态数据源,当泵状态数据变化时,MechanicalPumpControl需要相应动态显示泵状态动画。

定义StartAnimation和StopAnimation两个依赖属性,来启动和停止泵状态动画。

关于控件的状态切换也可以考虑用VisualStateManager来实现,可以更方便地管理控件的状态以及用于状态过渡的逻辑,推荐用这种方式。

public class MechanicalPumpControl : Control
{
    static MechanicalPumpControl()
    {
        DefaultStyleKeyProperty.OverrideMetadata(typeof(MechanicalPumpControl), new FrameworkPropertyMetadata(typeof(MechanicalPumpControl)));
    }

   
    public static readonly DependencyProperty StateProperty = DependencyProperty.Register(
    "State",
    typeof(int),
    typeof(MechanicalPumpControl), new PropertyMetadata(PropertyChangedCallback));

    public int State
    {
        get => (int)GetValue(StateProperty);
        set => SetValue(StateProperty, value);
    }

    private static void PropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var pumpControl = d as MechanicalPumpControl;

        if ((int)e.OldValue == 0 && (int)e.NewValue == 1)
        {
            pumpControl.StopAnimation = false;
            pumpControl.StartAnimation = true;
        }
        else if ((int)e.OldValue == 1 && (int)e.NewValue == 0)
        {
            pumpControl.StopAnimation = true;
            pumpControl.StartAnimation = false;
        }
    }

    public static readonly DependencyProperty StartAnimationProperty = DependencyProperty.Register(
        "StartAnimation",
        typeof(bool),
        typeof(MechanicalPumpControl));

    public bool StartAnimation
    {
        get => (bool)GetValue(StartAnimationProperty);
        set => SetValue(StartAnimationProperty, value);
    }

    public static readonly DependencyProperty StopAnimationProperty = DependencyProperty.Register(
        "StopAnimation",
        typeof(bool),
        typeof(MechanicalPumpControl));

    public bool StopAnimation
    {
        get => (bool)GetValue(StopAnimationProperty);
        set => SetValue(StopAnimationProperty, value);
    }
}

 

三 Style

接下来编写MechanicalPumpControl的样式。

考虑绘制出不动的泵体部分,和动作的扇叶部分。当泵停止状态时,扇叶静止,当泵运转状态时,扇叶转动。

样式代码如下:

 <Style TargetType="{x:Type Rectangle}" x:Key="FanRec">
     <Setter Property="Canvas.Left" Value="7"/>
     <Setter Property="Width" Value="48"/>
     <Setter Property="Height" Value="6"/>
     <Setter Property="RadiusX" Value="0.5"/>
     <Setter Property="RadiusY" Value="0.5"/>
     <Setter Property="Fill" Value="SlateGray"/>
     <Setter Property="RenderTransform">
         <Setter.Value>
             <SkewTransform AngleX="-20" AngleY="-7"/>
         </Setter.Value>
     </Setter>
 </Style>

 <Style TargetType="{x:Type local:MechanicalPumpControl}">
     <Setter Property="Template">
         <Setter.Value>
             <ControlTemplate TargetType="{x:Type local:MechanicalPumpControl}">
                 <Viewbox Stretch="Fill">
                     <Canvas Width="180" Height="100">
                         <Rectangle Width="60" Height="60" Canvas.Top="10" Stroke="Gray"  StrokeThickness="3" RadiusX="3" RadiusY="3" />
                         <Canvas  Width="60" Height="54" Canvas.Top="14" ClipToBounds="True">
                             <Canvas x:Name="canvas1" Width="60" Height="54">
                                 <Rectangle x:Name="rec1" Style="{StaticResource FanRec}" Canvas.Top="6"/>
                                 <Rectangle x:Name="rec2" Style="{StaticResource FanRec}" Canvas.Top="16"/>
                                 <Rectangle x:Name="rec3" Style="{StaticResource FanRec}" Canvas.Top="26"/>
                                 <Rectangle x:Name="rec4" Style="{StaticResource FanRec}" Canvas.Top="36"/>
                                 <Rectangle x:Name="rec5" Style="{StaticResource FanRec}" Canvas.Top="46"/>
                             </Canvas>
                             <Canvas x:Name="canvas2" Width="60" Height="54">
                                 <Rectangle x:Name="rec6" Style="{StaticResource FanRec}" Canvas.Top="56"/>
                                 <Rectangle x:Name="rec7" Style="{StaticResource FanRec}" Canvas.Top="66"/>
                                 <Rectangle x:Name="rec8" Style="{StaticResource FanRec}" Canvas.Top="76"/>
                                 <Rectangle x:Name="rec9" Style="{StaticResource FanRec}" Canvas.Top="86"/>
                                 <Rectangle x:Name="rec10" Style="{StaticResource FanRec}" Canvas.Top="96"/>
                                 <Rectangle x:Name="rec11" Style="{StaticResource FanRec}" Canvas.Top="106"/>
                             </Canvas>
                         </Canvas>
                         <Rectangle  Width="5" Height="40" Canvas.Left="60" Canvas.Top="20"  Stroke="Gray"  StrokeThickness="4"/>
                         <Rectangle  Width="110" Height="82" Canvas.Left="65"  RadiusX="3" RadiusY="3" Stroke="Gray"  StrokeThickness="4"/>
                         <Rectangle  Width="10" Height="8" Canvas.Left="75" Canvas.Top="82" Fill="Gray" />
                         <Rectangle  Width="10" Height="8" Canvas.Left="155" Canvas.Top="82" Fill="Gray" />
                         <Rectangle  Width="140" Height="10" Canvas.Left="40" Canvas.Top="90" Fill="Black" RadiusX="2" RadiusY="2"/>
                     </Canvas>
                 </Viewbox>
                 <ControlTemplate.Triggers>
                     <Trigger Property="StartAnimation" Value="true">
                         <Trigger.EnterActions>
                             <BeginStoryboard Name="moveStory">
                                 <Storyboard RepeatBehavior="Forever" SpeedRatio="4">
                                     <DoubleAnimationUsingKeyFrames 
                                                 Storyboard.TargetName="canvas1" 
                                                 Storyboard.TargetProperty="(Canvas.Top)" 
                                                 Duration="0:0:6" >
                                         <LinearDoubleKeyFrame Value="0" KeyTime="0:0:0"/>
                                         <LinearDoubleKeyFrame Value="-10" KeyTime="0:0:1"/>
                                         <LinearDoubleKeyFrame Value="-20" KeyTime="0:0:2"/>
                                         <LinearDoubleKeyFrame Value="-30" KeyTime="0:0:3"/>
                                         <LinearDoubleKeyFrame Value="-40" KeyTime="0:0:4"/>
                                         <LinearDoubleKeyFrame Value="-50" KeyTime="0:0:5"/>
                                         <LinearDoubleKeyFrame Value="-60" KeyTime="0:0:6"/>
                                     </DoubleAnimationUsingKeyFrames>
                                     <DoubleAnimationUsingKeyFrames 
                                                 Storyboard.TargetName="canvas2" 
                                                 Storyboard.TargetProperty="(Canvas.Top)" 
                                                 Duration="0:0:6" >
                                         <LinearDoubleKeyFrame Value="0" KeyTime="0:0:0"/>
                                         <LinearDoubleKeyFrame Value="-10" KeyTime="0:0:1"/>
                                         <LinearDoubleKeyFrame Value="-20" KeyTime="0:0:2"/>
                                         <LinearDoubleKeyFrame Value="-30" KeyTime="0:0:3"/>
                                         <LinearDoubleKeyFrame Value="-40" KeyTime="0:0:4"/>
                                         <LinearDoubleKeyFrame Value="-50" KeyTime="0:0:5"/>
                                         <LinearDoubleKeyFrame Value="-60" KeyTime="0:0:6"/>
                                     </DoubleAnimationUsingKeyFrames>
                                 </Storyboard>
                             </BeginStoryboard>
                         </Trigger.EnterActions>
                     </Trigger>
                     <Trigger Property="StopAnimation" Value="true">
                         <Trigger.EnterActions>
                             <StopStoryboard BeginStoryboardName="moveStory">
                             </StopStoryboard>
                         </Trigger.EnterActions>
                     </Trigger>
                     <Trigger Property="State" Value="1">
                         <Setter TargetName="rec1" Property="Fill" Value="SeaGreen"/>
                         <Setter TargetName="rec2" Property="Fill" Value="SeaGreen"/>
                         <Setter TargetName="rec3" Property="Fill" Value="SeaGreen"/>
                         <Setter TargetName="rec4" Property="Fill" Value="SeaGreen"/>
                         <Setter TargetName="rec5" Property="Fill" Value="SeaGreen"/>
                         <Setter TargetName="rec6" Property="Fill" Value="SeaGreen"/>
                         <Setter TargetName="rec7" Property="Fill" Value="SeaGreen"/>
                         <Setter TargetName="rec8" Property="Fill" Value="SeaGreen"/>
                         <Setter TargetName="rec9" Property="Fill" Value="SeaGreen"/>
                         <Setter TargetName="rec10" Property="Fill" Value="SeaGreen"/>
                         <Setter TargetName="rec11" Property="Fill" Value="SeaGreen"/>
                     </Trigger>
                 </ControlTemplate.Triggers>
             </ControlTemplate>
         </Setter.Value>
     </Setter>
 </Style>

 

四 效果演示

Xaml代码如下:

<Window x:Class="WpfApp1.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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfApp1"
        mc:Ignorable="d"
        Title="MainWindow" Height="768" Width="1366">
    <Canvas>
        <local:MechanicalPumpControl x:Name="pump" Canvas.Left="115" Canvas.Top="85"/>
        <Button Content="START" Width="60" Height="30"  Canvas.Left="363" Canvas.Top="94" Click="STARTButton_Click"/>
        <Button Content="STOP"  Width="60" Height="30"  Canvas.Left="363" Canvas.Top="143" Click="STOPButton_Click"/>
    </Canvas>
</Window>

后台代码如下:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
    }
    private void STARTButton_Click(object sender, RoutedEventArgs e)
    {
        pump.State = 1;
    }
    private void STOPButton_Click(object sender, RoutedEventArgs e)
    {
        pump.State = 0;
    }
}

 

标签:控件,int,机械泵,State,typeof,WPF,public,MechanicalPumpControl
From: https://www.cnblogs.com/wwwen/p/17070859.html

相关文章

  • 在WPF中播放RTSP视频流
    在WPF中可以使用LibVLCSharp.WPF、Vlc.DotNet.Wpf组件直接播放RTSP流,此外还可以通过LibVLCSharp+SkiaSharp的方式将VLC视频流通过WriteableBitmap的方式关联到Image对象......
  • 数据可视化大屏高德地图javascript webAPI开发的智慧治安物联网管理系统实战解析(web
    文章目录​​高德地图开发系列文章目录​​​​前言​​​​一、项目说明​​​​二、核心代码开发​​​​1.引入库​​​​2.构建DOM容器​​​​3.高德地图开发​​​​(1......
  • 界面组件DevExpress WPF v22.2 - Windows 11暗黑主题发布
    DevExpressWPF拥有120+个控件和库,将帮助您交付满足甚至超出企业需求的高性能业务应用程序。通过DevExpressWPF能创建有着强大互动功能的XAML基础应用程序,这些应用程序专......
  • WPF鼠标、键盘、拖拽事件、用行为封装事件
    WPF鼠标、键盘、拖拽事件、用行为封装事件本文主要介绍了WPF中常用的鼠标事件、键盘事件以及注意事项,同时使用一个案例讲解了拓展事件。除此之外,本文还讲述如何用行为(Behav......
  • WPF鼠标、键盘、拖拽事件、用行为封装事件
    WPF鼠标、键盘、拖拽事件、用行为封装事件本文主要介绍了WPF中常用的鼠标事件、键盘事件以及注意事项,同时使用一个案例讲解了拓展事件。除此之外,本文还讲述如何用行为(Beha......
  • C# WPF 报错 CS0103 当前上下文中不存在名称的解决方法
    使用WPF时有时会出现此错误 但是此部分是软件自动生成的,所以不可能出错,有时候重启VS就会好,但是也会遇到重启几次仍然报错的情况这个问题的解决方法是,在调试中打开,启动......
  • Android高级控件之下拉框和几种适配器
    7.1下拉框首先介绍下拉框在xml文件中的两种表达形式,再介绍在代码中的两种写法在xml文件中,下拉框控件Spinner的写法如下所示:<Spinner android:id="@id/sp_XXX"  ......
  • WPF的MVVM的数据驱动学习示例
    项目结构  界面数据绑定<Windowx:Class="WpfApp1.MainWindow"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="h......
  • WPF的APP生命周期以及全局异常捕获
    WPF的APP生命周期以及全局异常捕获APP生命周期wpf项目目录中有一个App.xaml.cs文件,该文件中App是一个partical类,与之对应的另一partical部分在App.g.i.cs文件中,该文件是......
  • WPF的APP生命周期以及全局异常捕获
    WPF的APP生命周期以及全局异常捕获APP生命周期wpf项目目录中有一个App.xaml.cs文件,该文件中App是一个partical类,与之对应的另一partical部分在App.g.i.cs文件中,该文件是在......