基于WPF技术的换热站智能监控系统16--动态数据绑定

1、实现思路

1)实时读取到的数据绑定到前台UI控件上,这个通过MVVM模式实现,同时注意实时读取必须通过任务task异步方式,这就需要读取PLC数据。

2)UI控件的动作,如开或关水泵,必定能够将值写入PLC,这就需要写入PLC数据,此时当上面1的任务执行时,又获取到了新的实时数据,从而改变UI控件

注意:

默认启动程序后,就主动读取PLC数据,启动成功后,可以关闭某个水泵

2、开搞

1、完善数据块中的变量

每个水泵有3个数据,即状态,温度,压力,所以有9个变量

2、完善监控变量

 

3、完善逻辑代码

  private void ReadmyPLC()
  {
      tasks.Add(Task.Run(async () =>
      { 
          plc.Open();
          while (!cts.IsCancellationRequested)
          {
              await Task.Delay(5000);
              //读取float,从左到右参数依次是:数据块类型,数据块号,启始地址,变量类型,读取数量
              var result = plc.Read(S7.Net.DataType.DataBlock, 1, 2, S7.Net.VarType.Real, 6);
              float[] values = (float[])result; 
              //水泵1数据
              MainData.MomentDataList1[0].Value = values[0]; 
              MainData.MomentDataList1[1].Value = values[1];
              //水泵2数据
              MainData.MomentDataList2[0].Value = values[2];
              MainData.MomentDataList2[1].Value = values[3];
              //水泵3数据
              MainData.MomentDataList3[0].Value = values[4];
              MainData.MomentDataList3[1].Value = values[5];

              //读取bool,DB1.DBX0.0是变量的具体地址
              var result2 = plc.Read(pumpaddr1);   //水泵1状态 
              Pump1State = bool.Parse(result2.ToString());
              if (!Pump1State)
              {
                  WaterDirection1 = "NONE";//停止流动
              }
              else
              {
                  WaterDirection1 = "EW";//开始流动
              }
              result2 = plc.Read(pumpaddr2);//水泵2状态 
              Pump2State = bool.Parse(result2.ToString());
              if (!Pump3State)
              {
                  WaterDirection2 = "NONE";
              }
              else
              {
                  WaterDirection2 = "EW";
              }
              result2 = plc.Read(pumpaddr3); //水泵3状态 
              Pump3State = bool.Parse(result2.ToString());
              if (!Pump3State)
              {
                  WaterDirection3 = "NONE";
                  WaterDirection32 = "NONE";
              }
              else
              {
                  WaterDirection3 = "EW";
                  WaterDirection32 = "WE";
              }

          }
      }, cts.Token)
      );
  } 

4、完善控件数据绑定

<Window x:Class="West.HeatExchange.Views.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:West.HeatExchange.Views"
        mc:Ignorable="d"
        xmlns:c="clr-namespace:West.HeatExchange.Controls"
        xmlns:lvc="clr-namespace:LiveCharts.Wpf;assembly=LiveCharts.Wpf"
        WindowStyle="None" AllowsTransparency="True" WindowStartupLocation="CenterScreen" ResizeMode="CanResizeWithGrip"
        Background="#F7F9FA" FontFamily="Microsoft YaHei" Foreground="#333"
        Title="MainWindow" Height="650" Width="1200"  >
    <!--窗体资源-->
    <Window.Resources>
        <!--手动模式/自动模式单选控件样式-->
        <Style TargetType="RadioButton" x:Key="ModeButtonStyle">
            <Setter Property="Background" Value="#FFF0F4F8"/>
            <Setter Property="Foreground" Value="Gray"/>
            <Setter Property="FontSize" Value="12"/>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="RadioButton">
                        <Border Background="{TemplateBinding Background}" Name="bor">
                            <ContentPresenter Margin="30,5"/>
                        </Border>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
            <!--触发器-->
            <Style.Triggers>
                <Trigger Property="IsChecked" Value="True">
                    <Setter Property="Background" Value="#FF3BBAFF"/>
                    <Setter Property="Foreground" Value="White"/>
                </Trigger>
            </Style.Triggers>
        </Style>
        <!--水泵开样式-->
        <Style TargetType="RadioButton" x:Key="LeftSwitchButtonStyle">
            <Setter Property="Background" Value="#FFF0F4F8"/>
            <Setter Property="Foreground" Value="Gray"/>
            <Setter Property="HorizontalAlignment" Value="Center"/>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="RadioButton">
                        <Grid>
                            <!--绘制下划线-->
                            <Border BorderBrush="Transparent" BorderThickness="0,0,0,1" Height="30" Margin="5,0" Name="bor" Width="20" HorizontalAlignment="Left"/>
                            <!--绘制曲线-->
                            <Path Data="M3 0 45 0 48 3 28 20 3 20 0 17 0 3z" Stroke="#DDD" StrokeThickness="1" Fill="{TemplateBinding Background}" Margin="0,0,2,0" VerticalAlignment="Center"/>
                            <TextBlock Text="开" VerticalAlignment="Center" HorizontalAlignment="Center" FontSize="10" Margin="0,0,15,0"/>
                        </Grid>
                        <!--触发器-->
                        <ControlTemplate.Triggers>
                            <Trigger Property="IsChecked" Value="True">
                                <Setter TargetName="bor" Property="Visibility" Value="Visible"/>
                                <Setter TargetName="bor" Property="BorderBrush" Value="#FF3BBAFF"/>
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
            <Style.Triggers>
                <Trigger Property="IsChecked" Value="True">
                    <Setter Property="Background" Value="#FF3BBAFF"/>
                    <Setter Property="Foreground" Value="White"/>
                </Trigger>
            </Style.Triggers>
        </Style>
        <!--水泵关样式-->
        <Style TargetType="RadioButton" x:Key="RightSwitchButtonStyle">
            <Setter Property="Background" Value="#FFF0F4F8"/>
            <Setter Property="Foreground" Value="Gray"/>
            <Setter Property="HorizontalAlignment" Value="Center"/>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="RadioButton">
                        <Grid>
                            <Border BorderBrush="Transparent" BorderThickness="0,0,0,1" Height="30" Margin="8,0" Name="bor" Width="20" HorizontalAlignment="Right"/>
                            <Path Data="M0 17 20 0 45 0 48 3 48 17 45 20 3 20z" Stroke="#DDD" StrokeThickness="1" Fill="{TemplateBinding Background}" Margin="0,0,2,0" VerticalAlignment="Center"/>
                            <TextBlock Text="关" VerticalAlignment="Center" HorizontalAlignment="Center" FontSize="10" Margin="10,0,0,0"/>
                        </Grid>
                        <ControlTemplate.Triggers>
                            <Trigger Property="IsChecked" Value="True">
                                <Setter TargetName="bor" Property="Visibility" Value="Visible"/>
                                <Setter TargetName="bor" Property="BorderBrush" Value="#FF3BBAFF"/>
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
            <Style.Triggers>
                <Trigger Property="IsChecked" Value="True">
                    <Setter Property="Background" Value="#FF3BBAFF"/>
                    <Setter Property="Foreground" Value="White"/>
                </Trigger>
            </Style.Triggers>
        </Style>
        <!--故障样式-->
        <Style TargetType="CheckBox" x:Key="WarningButtonStyle">
            <Setter Property="FontSize" Value="11"/>
            <Setter Property="Foreground" Value="White"/>
            <Setter Property="Opacity" Value="0.2"/>
            <Setter Property="Margin" Value="0,2"/>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="CheckBox">
                        <Grid>
                            <Border BorderBrush="Red" BorderThickness="1" Padding="1" Name="root">
                                <Border.Background>
                                    <DrawingBrush TileMode="Tile" Viewport="0,0,0.1,0.2" >
                                        <!--画笔填充-->
                                        <DrawingBrush.Drawing>
                                            <GeometryDrawing>
                                                <GeometryDrawing.Pen>
                                                    <Pen Brush="blue" Thickness="10" x:Name="pen"/>
                                                </GeometryDrawing.Pen>
                                                <GeometryDrawing.Geometry>
                                                    <LineGeometry StartPoint="50,0" EndPoint="0,50"/>
                                                </GeometryDrawing.Geometry>
                                            </GeometryDrawing>
                                        </DrawingBrush.Drawing>
                                    </DrawingBrush>
                                </Border.Background>
                                <Border Background="Red" Margin="0,6,0,0" BorderBrush="White" BorderThickness="1" Height="20">
                                    <ContentPresenter VerticalAlignment="Center" HorizontalAlignment="Center" Margin="15,0"/>
                                </Border>
                            </Border>
                        </Grid>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
            <Style.Triggers>
                <Trigger Property="IsChecked" Value="True">
                    <Setter Property="Opacity" Value="1"/>
                </Trigger>
            </Style.Triggers>
        </Style>
    </Window.Resources>
    <DockPanel>
        <!--顶部区域,分5列-->
        <Grid DockPanel.Dock="Top"  >
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="48"/>
                <ColumnDefinition Width="Auto"/>
                <ColumnDefinition/>
                <ColumnDefinition Width="Auto"/>
                <ColumnDefinition Width="50"/>
            </Grid.ColumnDefinitions>
            <!--图标-->
            <Border Width="45" Grid.Column="0" Background="#3BBAFF" BorderBrush="#EEE"  BorderThickness="1" HorizontalAlignment="Left">
                <Image Source="../Assets/Images/Logo_white.png" Margin="8"/>
            </Border>
            <!--背景-->
            <Border Grid.ColumnSpan="4"  Grid.Column="1"   Background="#5E7593"  MouseLeftButtonDown="Border_MouseLeftButtonDown"/>
            <!--文字-->
            <TextBlock Text="换热站远程监控系统" VerticalAlignment="Center" Foreground="White" FontSize="19" Margin="10,0" Grid.Column="1"/>
            <!--时间-->
            <TextBlock  Text="{Binding NowTime, StringFormat={}{0:yyyy年MM月dd日HH时mm分ss秒}}" VerticalAlignment="Center"  Foreground="White" FontSize="19"  Margin="20,0" Grid.Column="3"/>
            <!--退出按钮-->
            <Button   Grid.Column="4" Width="25" Height="25"  Click="Button_Click">
                <Button.Background>
                    <ImageBrush ImageSource="../Assets/Images/closewin.png"/>
                </Button.Background>
            </Button>

        </Grid>

        <!--左侧区域,分5行-->
        <Border DockPanel.Dock="Left" Width="280" Background="White" CornerRadius="3" Margin="30,10,10,10" >
            <Border.Effect>
                <DropShadowEffect BlurRadius="10" ShadowDepth="0" Color="LightGray" Opacity="0.3"/>
            </Border.Effect>
            <Grid Margin="20,10">
                <Grid.RowDefinitions>
                    <RowDefinition Height="50"/>
                    <RowDefinition/>
                    <RowDefinition/>
                    <RowDefinition Height="1.2*"/>
                    <RowDefinition Height="1.2*"/>
                </Grid.RowDefinitions>
                <!--第1行,文字栏-->
                <Border Grid.Row="0" Background="#3BBAFF" CornerRadius="3" Margin="0,8">
                    <StackPanel Orientation="Horizontal" VerticalAlignment="Center" HorizontalAlignment="Center">
                        <c:RunLoading Width="23" Height="23" Margin="10,0"/>
                        <TextBlock Text="换热站综合信息详情" Foreground="White" FontSize="12" VerticalAlignment="Center"/>
                    </StackPanel>
                </Border>

                <!--第2行,历史曲线-->
                <Grid Grid.Row="1" Background="#FFF0F4F8" Margin="0,5">
                    <Border Height="16" VerticalAlignment="Bottom" Background="#FF0E3A52" CornerRadius="8"/>
                    <!--livechart图表配置,Values绑定序列数据-->
                    <lvc:CartesianChart DisableAnimations="True">
                        <lvc:CartesianChart.Series>
                            <lvc:LineSeries Values="29,225,380,97,440,129,532" LineSmoothness="0"  Fill="Transparent"/>
                        </lvc:CartesianChart.Series>
                        <!--X轴配置-->
                        <lvc:CartesianChart.AxisX>
                            <lvc:Axis Labels="周一,周二,周三,周四,周五,周六,周日" FontSize="8" Foreground="White">
                                <lvc:Axis.Separator>
                                    <lvc:Separator StrokeThickness="0" Step="1"/>
                                </lvc:Axis.Separator>
                            </lvc:Axis>
                        </lvc:CartesianChart.AxisX>
                        <!--Y轴配置-->
                        <lvc:CartesianChart.AxisY>
                            <lvc:Axis MinValue="0" MaxValue="600" Foreground="Transparent"></lvc:Axis>
                        </lvc:CartesianChart.AxisY>
                    </lvc:CartesianChart>
                    <Border Background="#3BBAFF" VerticalAlignment="Top" HorizontalAlignment="Left">
                        <TextBlock Text="历史曲线" Foreground="White" FontSize="10" Margin="5,1"/>
                    </Border>
                </Grid>

                <!--第3行,能耗排名-->
                <Grid Grid.Row="2" Background="#FFF0F4F8" Margin="0,5">
                    <UniformGrid Columns="1">
                        <!--文字部分-->
                        <StackPanel Orientation="Horizontal" VerticalAlignment="Top">
                            <Border Background="#FF3BBAFF">
                                <TextBlock Text="能耗排名" Foreground="White" FontSize="10" Margin="5,1"/>
                            </Border>
                            <TextBlock FontSize="10" VerticalAlignment="Center" Margin="5,0">
                                <Run Text="耗水" Foreground="#666"/>
                                <Run Text="&#xe92e;" FontFamily="../Assets/Fonts/#iconfont"/>
                            </TextBlock>
                            <TextBlock FontSize="10" VerticalAlignment="Center">
                                <Run Text="耗电" Foreground="#666"/>
                               <Run Text="&#xe8b6;" FontFamily="../Assets/Fonts/#iconfont"/>
                            </TextBlock>
                            <TextBlock  FontSize="10" VerticalAlignment="Center" Margin="5,0">
                                <Run Text="耗热" Foreground="#666"/>
                                <Run Text="&#xe60e;" FontFamily="../Assets/Fonts/#iconfont"/>
                            </TextBlock>
                        </StackPanel>
                        <!--耗水-->
                        <Grid Margin="0,0,10,0">
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="20"/>
                                <ColumnDefinition/>
                            </Grid.ColumnDefinitions>
                            <TextBlock Text="&#xe92e;" FontFamily="../Assets/Fonts/#iconfont" VerticalAlignment="Center" HorizontalAlignment="Center" Foreground="#FF3BBAFF"/>
                            <ProgressBar Grid.Column="1" Minimum="0" Maximum="200" Value="182" Background="LightGray" Foreground="Orange" Height="4"/>
                        </Grid>
                        <!--耗电-->
                        <Grid Margin="0,0,10,0">
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="20"/>
                                <ColumnDefinition/>
                            </Grid.ColumnDefinitions>
                            <TextBlock Text="&#xe8b6;" FontFamily="../Assets/Fonts/#iconfont" VerticalAlignment="Center" HorizontalAlignment="Center" Foreground="#FF3BBAFF"/>
                            <ProgressBar Grid.Column="1" Minimum="0" Maximum="200" Value="156" Background="LightGray" Foreground="Orange" Height="4"/>
                        </Grid>
                        <!--耗热-->
                        <Grid Margin="0,0,10,0">
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="20"/>
                                <ColumnDefinition/>
                            </Grid.ColumnDefinitions>
                            <TextBlock Text="&#xe60e;" FontFamily="../Assets/Fonts/#iconfont" VerticalAlignment="Center" HorizontalAlignment="Center" Foreground="#FF3BBAFF"/>
                            <ProgressBar Grid.Column="1" Minimum="0" Maximum="200" Value="116" Background="LightGray" Foreground="Orange" Height="4"/>
                        </Grid>
                        <!--装饰-->
                        <Border Height="5" Margin="10,0">
                            <Border.Background>
                                <!--线性渐变-->
                                <LinearGradientBrush StartPoint="0,0" EndPoint="1,0">
                                    <GradientStop Color="#FF3BBAFF" Offset="0"/>
                                    <GradientStop Color="#113BBAFF" Offset="1"/>
                                </LinearGradientBrush>
                            </Border.Background>
                        </Border>
                    </UniformGrid>
                </Grid>

                <!--第4行,故障统计-->
                <Grid Grid.Row="3" Background="#FFF0F4F8" Margin="0,5">
                    <Border Height="16" VerticalAlignment="Bottom" Background="#FF0E3A52" CornerRadius="8"/>
                    <lvc:CartesianChart DisableAnimations="True">
                        <lvc:CartesianChart.Series>
                            <lvc:ColumnSeries Values="319,223,63,257,335,440,178,223,53,117" MaxColumnWidth="6"/>
                        </lvc:CartesianChart.Series>
                        <lvc:CartesianChart.AxisX>
                            <lvc:Axis Labels="设备1,设备2,设备3,设备4,设备5,设备6,设备7,设备8,设备9,设备10" FontFamily="Microsoft YaHei" FontSize="6" Foreground="White">
                                <lvc:Axis.Separator>
                                    <lvc:Separator Step="1" StrokeThickness="0"/>
                                </lvc:Axis.Separator>
                            </lvc:Axis>
                        </lvc:CartesianChart.AxisX>
                        <lvc:CartesianChart.AxisY>
                            <lvc:Axis MinValue="0" MaxValue="600" Foreground="Transparent">
                                <lvc:Axis.Separator>
                                    <lvc:Separator StrokeThickness="1" Stroke="#DDD" Step="760"/>
                                </lvc:Axis.Separator>
                            </lvc:Axis>
                        </lvc:CartesianChart.AxisY>
                    </lvc:CartesianChart>
                    <Border Background="#FF3BBAFF" VerticalAlignment="Top" HorizontalAlignment="Left" Margin="2">
                        <TextBlock Text="故障统计" Foreground="White" FontSize="10" Margin="5,1"/>
                    </Border>
                </Grid>

                <!--第5行,数据报表-->
                <Grid Grid.Row="4" Background="#FFF0F4F8" Margin="0,5">
                    <lvc:PieChart  InnerRadius="40" Width="110" Height="110"  DisableAnimations="True" StartingRotationAngle="0" HoverPushOut="0"  >
                        <!--以下是静态显示-->
                        <lvc:PieChart.Series>
                            <lvc:PieSeries  Values="23"  Fill="#2BBF6E" StrokeThickness="2" DataLabels="True" Foreground="Black" FontSize="11" LabelPosition="OutsideSlice" Title="锻烧车间"></lvc:PieSeries>
                            <lvc:PieSeries  Values="37" Fill="#3DDFEE" StrokeThickness="2" DataLabels="True" Foreground="Black" FontSize="11" LabelPosition="OutsideSlice" Title="模具车间"></lvc:PieSeries>
                            <lvc:PieSeries  Values="80" Fill="Red" StrokeThickness="2" DataLabels="True" Foreground="Black" FontSize="11" LabelPosition="OutsideSlice" Title="电噴车间"></lvc:PieSeries>
                            <lvc:PieSeries  Values="60" Fill="Blue" StrokeThickness="2" DataLabels="True" Foreground="Black" FontSize="11" LabelPosition="OutsideSlice" Title="组装车间"></lvc:PieSeries>
                        </lvc:PieChart.Series>
                    </lvc:PieChart>
                    <Border Background="#FF3BBAFF" VerticalAlignment="Top" HorizontalAlignment="Left" Margin="2">
                        <TextBlock Text="数据报表" Foreground="White" FontSize="10" Margin="5,1"/>
                    </Border>
                </Grid>

            </Grid>
        </Border>

        <!--右上区域,控制模式-->
        <Border Height="80" DockPanel.Dock="Top" Background="White" Margin="0,10,20,0" CornerRadius="3">
            <Border.Effect>
                <DropShadowEffect BlurRadius="10" ShadowDepth="0" Color="LightGray" Opacity="0.3"/>
            </Border.Effect>
            <UniformGrid Rows="1">
                <!--<Button Content="连接PLC" Width="60" Height="40" Click="Button_Click_1" ></Button>-->
                <StackPanel VerticalAlignment="Center" HorizontalAlignment="Center">
                    <RadioButton Content="手动模式" IsChecked="True" Style="{StaticResource ModeButtonStyle}"/>
                    <RadioButton Content="自动模式" Style="{StaticResource ModeButtonStyle}"/>
                </StackPanel>
                <!--补水泵1-->
                <Grid Background="#88F0F4F8" VerticalAlignment="Center" HorizontalAlignment="Center">
                    <Grid.RowDefinitions>
                        <RowDefinition/>
                        <RowDefinition/>
                    </Grid.RowDefinitions>
                    <TextBlock Text="No.1 补水泵" Margin="20,3" HorizontalAlignment="Center"/>
                    <Grid Grid.Row="1" Margin="10,0">
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition/>
                            <ColumnDefinition Width="15"/>
                            <ColumnDefinition/>
                        </Grid.ColumnDefinitions>
                        <RadioButton Grid.Column="0" IsChecked="True"  Command="{Binding StartCommand}" CommandParameter="1" Grid.ColumnSpan="2"  Style="{StaticResource LeftSwitchButtonStyle}" Name="rb"/>
                        <RadioButton Grid.Column="1" Grid.ColumnSpan="2" Command="{Binding StopCommand}"  CommandParameter="1" Style="{StaticResource RightSwitchButtonStyle}"/>
                    </Grid>
                </Grid>
                <!--补水泵2-->
                <Grid Background="#88F0F4F8" VerticalAlignment="Center" HorizontalAlignment="Center">
                    <Grid.RowDefinitions>
                        <RowDefinition/>
                        <RowDefinition/>
                    </Grid.RowDefinitions>
                    <TextBlock Text="No.2 补水泵" Margin="20,3" HorizontalAlignment="Center"/>
                    <Grid Grid.Row="1" Margin="10,0">
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition/>
                            <ColumnDefinition Width="15"/>
                            <ColumnDefinition/>
                        </Grid.ColumnDefinitions>
                        <RadioButton IsChecked="True" Grid.ColumnSpan="2" Command="{Binding StartCommand}" CommandParameter="2" Style="{StaticResource LeftSwitchButtonStyle}"/>
                        <RadioButton Grid.Column="1" Grid.ColumnSpan="2" Command="{Binding StopCommand}"  CommandParameter="2" Style="{StaticResource RightSwitchButtonStyle}"/>
                    </Grid>
                </Grid>
                <!--补水泵3-->
                <Grid Background="#88F0F4F8" VerticalAlignment="Center" HorizontalAlignment="Center">
                    <Grid.RowDefinitions>
                        <RowDefinition/>
                        <RowDefinition/>
                    </Grid.RowDefinitions>
                    <TextBlock Text="No.3 补水泵" Margin="20,3" HorizontalAlignment="Center"/>
                    <Grid Grid.Row="1" Margin="10,0">
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition/>
                            <ColumnDefinition Width="15"/>
                            <ColumnDefinition/>
                        </Grid.ColumnDefinitions>
                        <RadioButton IsChecked="True" Grid.ColumnSpan="2" Command="{Binding StartCommand}" CommandParameter="3" Style="{StaticResource LeftSwitchButtonStyle}"/>
                        <RadioButton Grid.Column="1" Grid.ColumnSpan="2" Command="{Binding StopCommand}"  CommandParameter="3" Style="{StaticResource RightSwitchButtonStyle}"/>
                    </Grid>
                </Grid>

                <!--故障切换--> 
                <Grid Background="#88F0F4F8" VerticalAlignment="Center" HorizontalAlignment="Center">
                    <Grid.RowDefinitions>
                        <RowDefinition/>
                        <RowDefinition/>
                    </Grid.RowDefinitions>
                    <CheckBox Content="循环变频故障" Grid.Row="0" Style="{StaticResource WarningButtonStyle}" IsChecked="True"/>
                    <CheckBox Content="补水变频故障" Grid.Row="1" Style="{StaticResource WarningButtonStyle}"/>
                </Grid>
            </UniformGrid>
        </Border>

        <!--右中区域,系统运行-->
        <Border Background="White" Margin="0,10,20,10" CornerRadius="3" >
            <Border.Effect>
                <DropShadowEffect BlurRadius="10" ShadowDepth="0" Color="LightGray" Opacity="0.3"/>
            </Border.Effect>
            <Canvas>
                <!--管道--> 
                <c:PipeLine Height="7" Width="839" Direction="EW" HorizontalAlignment="Left" VerticalAlignment="Center" Canvas.Left="10" Canvas.Top="44"/>
                <c:PipeLine x:Name="middle" Panel.ZIndex="3" Canvas.Left="234" Canvas.Top="49"   Direction="EW"   Height="7" Width="182" CapRadius="3">
                    <c:PipeLine.RenderTransform>
                        <TransformGroup>
                            <RotateTransform Angle="90" ></RotateTransform>
                        </TransformGroup>
                    </c:PipeLine.RenderTransform>
                </c:PipeLine>
                <c:PipeLine Height="7" Width="619" Direction="EW" HorizontalAlignment="Left" VerticalAlignment="Center" Canvas.Left="230" Canvas.Top="224"/>
                <c:PipeLine x:Name="middle2" Panel.ZIndex="3" Canvas.Left="164" Canvas.Top="139.5"   Direction="{Binding WaterDirection2}"   Height="7" Width="185" CapRadius="3">
                    <c:PipeLine.RenderTransform>
                        <TransformGroup>
                            <RotateTransform Angle="90" ></RotateTransform>
                        </TransformGroup>
                    </c:PipeLine.RenderTransform>
                </c:PipeLine>
                <c:PipeLine Height="7" Width="399" Direction="{Binding WaterDirection2}" HorizontalAlignment="Left" VerticalAlignment="Center" Canvas.Left="450" Canvas.Top="296"  />
                <c:PipeLine x:Name="right" Panel.ZIndex="3" Margin="0" Canvas.Left="223" Canvas.Top="302" Width="131" Direction="{Binding WaterDirection32}"  Height="7" CapRadius="1">
                    <c:PipeLine.RenderTransform>
                        <TransformGroup>
                            <TranslateTransform X="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Canvas}, Path=ActualHeight}" Y="0"></TranslateTransform>
                            <RotateTransform Angle="90" CenterX="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Canvas}, Path=ActualHeight}" CenterY="0"></RotateTransform>
                        </TransformGroup>
                    </c:PipeLine.RenderTransform>
                </c:PipeLine>
                <c:PipeLine Height="7" Width="79" Direction="{Binding WaterDirection3}" HorizontalAlignment="Left" VerticalAlignment="Center" Canvas.Left="640" Canvas.Top="426"  />
                <c:PipeLine Height="7" Width="79" Direction="{Binding WaterDirection3}" HorizontalAlignment="Left" VerticalAlignment="Center" Canvas.Left="540" Canvas.Top="447"  />
                <c:PipeLine Height="7.5"  Width="409" Direction="{Binding WaterDirection1}"  HorizontalAlignment="Left" VerticalAlignment="Center" Canvas.Left="10" Canvas.Top="137"/>
                <c:PipeLine Height="7.5"  Width="259" Direction="{Binding WaterDirection2}" HorizontalAlignment="Left" VerticalAlignment="Center" Canvas.Left="158" Canvas.Top="317"/>
                <c:PipeLine Height="7.5"  Width="459" Direction="{Binding WaterDirection3}" HorizontalAlignment="Left" VerticalAlignment="Center" Canvas.Left="10" Canvas.Top="447"/>
                <c:PipeLine Height="7.5" Width="399" Direction="{Binding WaterDirection1}" HorizontalAlignment="Left" VerticalAlignment="Center" Canvas.Left="450" Canvas.Top="116"/>
                <!--图片-->
                <Image Source="../Assets/Images/d1.jpg" Canvas.Left="35" Canvas.Top="29" Height="39" Width="61" HorizontalAlignment="Center" VerticalAlignment="Top"/>
                <Image Source="../Assets/Images/d1.jpg" Canvas.Left="755" Canvas.Top="29" Height="39" Width="61" HorizontalAlignment="Center" VerticalAlignment="Top"/>
                <Image Source="../Assets/Images/d1.jpg" Canvas.Left="755" Canvas.Top="279" Height="39" Width="61" HorizontalAlignment="Center" VerticalAlignment="Top"/>
                <Image Source="../Assets/Images/d1.jpg" Panel.ZIndex="3" Canvas.Left="95" Canvas.Top="429" Height="39" Width="61" HorizontalAlignment="Center" VerticalAlignment="Top"/>
                <Image Source="../Assets/Images/heat_exchange.jpg" Panel.ZIndex="2" Canvas.Left="264" Canvas.Top="20" Height="156" Width="80" HorizontalAlignment="Center" VerticalAlignment="Top"/>
                <Image Source="../Assets/Images/heat_exchange.jpg" Panel.ZIndex="2" Canvas.Left="264" Canvas.Top="200" Height="156" Width="80" HorizontalAlignment="Center" VerticalAlignment="Top"/>
                <Image Source="../Assets/Images/i2.jpg" Canvas.Left="164" Canvas.Top="13" Height="31" Width="25" HorizontalAlignment="Left" VerticalAlignment="Top"/>
                <Image Source="../Assets/Images/i2.jpg" Canvas.Left="424" Canvas.Top="13" Height="31" Width="25" HorizontalAlignment="Left" VerticalAlignment="Top"/>
                <Image Source="../Assets/Images/i2.jpg" Canvas.Left="524" Canvas.Top="85" Height="31" Width="25" HorizontalAlignment="Left" VerticalAlignment="Top"/>
                <Image Source="../Assets/Images/i2.jpg" Canvas.Left="684" Canvas.Top="193" Height="31" Width="25" HorizontalAlignment="Left" VerticalAlignment="Top"/>
                <Image Source="../Assets/Images/i2.jpg" Canvas.Left="584" Canvas.Top="265" Height="31" Width="25" HorizontalAlignment="Left" VerticalAlignment="Top"/>
                <Image Source="../Assets/Images/f2.jpg" Panel.ZIndex="2" Canvas.Left="64" Canvas.Top="115" Height="33" Width="34" HorizontalAlignment="Left" VerticalAlignment="Top"/>
                <Image Source="../Assets/Images/f2.jpg" Panel.ZIndex="2" Canvas.Left="224" Canvas.Top="425" Height="33" Width="34" HorizontalAlignment="Left" VerticalAlignment="Top"/>
                  <!--3个水泵-->
                <c:Pump Width="42" Height="38" IsRunning="{Binding Pump1State}" Canvas.Left="411" Canvas.Top="111" HorizontalAlignment="Center" VerticalAlignment="Top"/>
                <c:Pump Width="42" Height="38" IsRunning="{Binding Pump2State}" Canvas.Left="411" Canvas.Top="291" HorizontalAlignment="Center" VerticalAlignment="Top"/>
                <c:Pump Width="42" Height="38" IsRunning="{Binding Pump3State}" Canvas.Left="611" Canvas.Top="421" HorizontalAlignment="Center" VerticalAlignment="Top"/>
                 <!--数据看板-->
                <c:DataBoard Width="75" Height="40" Canvas.Left="30" Canvas.Top="71" ItemsSource="{Binding MainData.MomentDataList1}"/>
                <c:DataBoard Width="75" Height="40" Canvas.Left="135" Canvas.Top="56" ItemsSource="{Binding MainData.MomentDataList1}"/>
                <c:DataBoard Width="75" Height="40" Canvas.Left="545" Canvas.Top="71" ItemsSource="{Binding MainData.MomentDataList1}"/>
                <c:DataBoard Width="75" Height="40" Canvas.Left="495" Canvas.Top="252" ItemsSource="{Binding MainData.MomentDataList2}"/> 
                <c:DataBoard Width="75" Height="40" Canvas.Left="595" Canvas.Top="178" ItemsSource="{Binding MainData.MomentDataList2}"/> 
                <c:DataBoard Width="75" Height="40" Canvas.Left="90" Canvas.Top="383" ItemsSource="{Binding MainData.MomentDataList3}"/>
                <c:CoolingTower  RunningState="Normal" Width="140" Height="150"  Canvas.Left="415" Canvas.Top="347"></c:CoolingTower>
            </Canvas>
        </Border>
    </DockPanel>

</Window>

 5、运行效果

程序启动后,暂时没有数据

5秒后,数据实时显示,温度压力状态数据与监控表中的数据一致的 

关闭水泵1,观察管道和风扇情况及监控表数值

 

 

开启水泵1,管道流动了,风扇转动了 ,PLC数据改变了

 至此,PLC与系统完美对接,实现了全场监控管理。

走过路过不要错过,点赞关注收藏又圈粉,共同致富,为财务自由作出贡献

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/731697.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

常见的Wi-Fi蓝牙模组

在嵌入式领域&#xff0c;常见的Wi-Fi蓝牙模组确实包括多个知名品牌&#xff0c;如乐鑫、安信可和移远等&#xff0c;以前可能你听的最多的是ESP8266&#xff0c;不过今天讨论的是Wi-Fi蓝牙模组&#xff0c;而8266本身并不内置蓝牙功能&#xff0c;不在介绍范围。而拿到模块之后…

graalvm jdk和openjdk

下载地址:https://github.com/graalvm/graalvm-ce-builds/releases 官网: https://www.graalvm.org

设计模式4-模版方法

设计模式 重构获得模式重构的关键技法1. 静态转动态2. 早绑定转晚绑定3. 继承转组合4. 编译时依赖转运行时依赖5. 紧耦合转松耦合 组件协助动机模式定义结构 要点总结。 例子示例解释&#xff1a; 重构获得模式 设计模式的目的是应对变化&#xff0c;提高复用 设计模式的要点…

数据通信与网络(五)

交换机功能&#xff1a; 地址学习&#xff08;端口/MAC地址映射表&#xff09; 通信过滤&#xff08;基于端口/MAC地址映射表&#xff09; 生成树协议&#xff08;断开环路&#xff09; 隔离冲突域 生成树协议 隔离冲突域 交换机配置模式(用不同级别的命令对交换机进行配置) 普…

Zookeeper原理

Zookeeper监听原理 监听原理详解 &#xff08;1&#xff09;首先要有一个main()线程 &#xff08;2&#xff09;在main线程中创建Zookeeper客户端&#xff0c;这时就会创建两个线程&#xff0c;一个负责网络连接通信(connet)&#xff0c;一个负责监听(listener) 。 &#xf…

PHP转Go系列 | ThinkPHP与Gin的使用姿势

大家好&#xff0c;我是码农先森。 安装 使用 composer 进行项目的创建。 composer create-project topthink/think thinkphp_demo使用 go mod 初始化项目。 go mod init gin_demo目录 thinkphp_demo 项目目录结构。 thinkphp_demo ├── LICENSE.txt ├── README.md …

【STM32】时钟树系统

1.时钟树简介 1.1五个时钟源 LSI是低速内部时钟&#xff0c;RC振荡器&#xff0c;频率为32kHz左右。供独立看门狗和自动唤醒单元使用。 LSE是低速外部时钟&#xff0c;接频率为32.768kHz的石英晶体。这个主要是RTC的时钟源。 HSE是高速外部时钟&#xff0c;可接石英*/陶瓷谐振…

Ubuntu 22.04安装 docker

安装过程和指令 # 1.升级 apt sudo apt update # 2.安装docker sudo apt install docker.io docker-compose # 3.将当前用户加入 docker组 sudo usermod -aG docker ${USER} # 4. 重启 # 5. 查看镜像 docker ps -a 或者 docker images # 6. 下载镜像 docker pull hello-world …

动态创建接口地址

和SpringBoot版本有关系 这里用的boot 2.2.2

嵌入式学习——数据结构(队列)——day49

1. 队列 1. 先进先出 2. 缓冲区——先进先出的队列 高速设备和低速设备利用缓冲区进行协调匹配 3. 串口数据的通信利用队列进行协调 4. 顺序队列——循环队列&#xff08;非重点&#xff09; 5. 链式队列 5.1 创建队列 5.2 入队 5.3 出队 5.4 清空队列 5.5 销毁指针 6.…

[FlareOn5]Ultimate Minesweeper

一切题目&#xff0c;可以运行的&#xff0c;首先就要自己运行一次 运行完毕你会发现这是个扫雷游戏 net dnspy打开 一般没有特别的 我们都是点这花括号 这有个getkey 一眼加加密 然后可以三个方向&#xff1a;动调&#xff0c;改文件&#xff0c;静态找数据写加密脚本 简…

Web渗透:XSS-DOM-based XSS

DOM-based XSS&#xff08;基于DOM的跨站脚本攻击&#xff09;是一种XSS攻击类型&#xff0c;其特点是恶意脚本通过操作文档对象模型&#xff08;DOM&#xff09;直接在客户端执行&#xff0c;而无需经过服务器的处理。这种攻击主要利用客户端JavaScript代码中的漏洞&#xff0…

C++入门超详细解释

C入门 文章目录 C入门框架命名空间 namespace &#xff08;不常用&#xff09;命名空间的使用方式&#xff08;三种&#xff09;using namespace std;\<iostream>coutendlcincout的使用命名冲突缺省参数&#xff08;省钱的省&#xff09;缺省参数分类全缺省参数半缺省参数…

使用阿里开源的Spring Cloud Alibaba AI开发第一个大模型应用

背景 前段时间看到Spring推出了SpringAI&#xff0c;可以方便快速的接入ChatGPT等国外的大模型&#xff0c;现在阿里巴巴也紧追脚步推出了Spring Cloud Alibaba AI&#xff0c;Spring Cloud Alibaba AI 目前基于 Spring AI 0.8.1 版本 API 完成通义系列大模型的接入。通义接入…

Golang | Leetcode Golang题解之第172题阶乘后的零

题目&#xff1a; 题解&#xff1a; func trailingZeroes(n int) (ans int) {for n > 0 {n / 5ans n}return }

Linux系统开机自启动脚本(案例:Raspberry Pi 4B脚本)

前言&#xff1a;本篇博客为手把手教学的 Linux 系统开机自启动脚本教程&#xff0c;且额外包含有 Raspberry Pi 4B 的开机自启动案例。日常工程项目中往往需要 Linux 系统能够自启动一些代码程序&#xff0c;本篇博客利用虚拟机下的 Ubuntu 自启动脚本来进行教学&#xff0c;且…

【PS】提取手写签名

准备工具&#xff1a; 纸张&#xff1a;用于承载签名&#xff1b; 笔&#xff1a;用于签名&#xff1b; 手机&#xff1a;用于拍摄签名&#xff1b; Adobe Photoshop 版本: 12.0.3 (12.0.3x20101211 [20101211.r.1222 2010/12/11:02:00:00 cutoff; r branch]) x32&#xff1a;用…

多路h265监控录放开发-(8)完成摄像机管理的修改和删除功能

xviewer.h public:XViewer(QWidget* parent Q_NULLPTR);//编辑摄像机void SetCam(int index);//121 public slots:void AddCam(); //新增摄像机配置120void SetCam(); //121void DelCam(); //121 private:Ui::XViewerClass ui;QMenu left_menu_; xviewer.cpp void XView…

React的State和setState

如何确地使用 State 不要直接修改 State.修改State应该使用 setState():构造函数是唯一可以给 this.state 赋值的地方 State 与 props 类似&#xff0c;但是 state 是私有的&#xff0c;并且完全受控于当前组件 我们可以在我们的自定义组件中添加私有的State jcode class C…

web-原生Ajax

概念: Asynchronous JavaScript And XML&#xff0c;异步的JavaScript和XML。 作用: 数据交换:通过Ajax可以给服务器发送请求&#xff0c;并获取服务器响应的数据。 异步交互:可以在不重新加载整个页面的情况下&#xff0c;与服务器交换数据并更新部分网页的技术&#xff0c;如…