C#上位机与三菱PLC的通信11---开发自己的通讯工具软件(WPF版)

news2024/11/14 18:23:09

1、先看颜值

2、开始干

1、创建项目

2、引入前面的通讯库

 创建目录将前面生成的通讯库dll文件复制到项目的目录

本项目引入dll文件

 

 3、创建命令基类

RelayCommand.cs代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;

namespace MitsubishiMcToolWPF.Common
{
    /// <summary>
    /// 命令实现类
    /// </summary>
    public class RelayCommand : ICommand
    {
        public event EventHandler CanExecuteChanged;
        /// <summary>
        /// 要执行的操作
        /// </summary>
        private Action<object> executeActions;
        /// <summary>
        /// 是否可以执行的委托
        /// </summary>
        private Func<object, bool> canExecuteFunc;
        /// <summary>
        /// 构造函数 无参构造
        /// </summary>
        public RelayCommand() { }
        /// <summary>
        /// 通过执行的委托构造
        /// </summary>
        /// <param name="execute"></param>
        public RelayCommand(Action<object> execute) : this(execute, null)
        {

        }
        /// <summary>
        /// 通过执行的操作与是否可执行的委托
        /// </summary>
        /// <param name="execute">要执行的操作</param>
        /// <param name="canExecute">是否可以被执行</param>
        public RelayCommand(Action<object> execute, Func<object, bool> canExecute)
        {
            this.executeActions = execute;
            this.canExecuteFunc = canExecute;
        }

        /// <summary>
        /// 命令是否可以执行
        /// </summary>
        /// <param name="parameter"></param>
        /// <returns></returns>
        public bool CanExecute(object parameter)
        {
            if (canExecuteFunc != null)
                return this.canExecuteFunc(parameter);
            else
                return true;
        }

        /// <summary>
        /// 要执行的操作
        /// </summary>
        /// <param name="parameter"></param>
        public void Execute(object parameter)
        {
            if (executeActions == null)
                return;
            this.executeActions(parameter);
        }

        /// <summary>
        /// 执行CanExecuteChanged事件
        /// </summary>
        public void OnCanExecuteChanged()
        {
            this.CanExecuteChanged?.Invoke(this, new EventArgs());
        }
    }
}

 4、创建PLC实体类

PLCMemoryModel.cs代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MitsubishiMcToolWPF.Model
{
    /// <summary>
    /// PLC内存模型类
    /// </summary>
    public class PLCMemoryModel
    {
        /// <summary>
        /// 存储区
        /// </summary>
        public string Area { get; set; } = "";
        /// <summary>
        /// 地址
        /// </summary>

        public string Address { get; set; } = "";
        /// <summary>
        /// 数据类型
        /// </summary>

        public string DataType { get; set; } = "";
        /// <summary>
        /// 读取或写入数据
        /// </summary>

        public string Count { get; set; } = "";
    }
}

 5、添加资源字典,即样式文件

CommonResource.xaml完整代码

 <!--读取写入Button按钮样式--> 
 <Style x:Key="ButtonStyle" TargetType="Button">
     <Setter Property="Background" Value="#3F85FF"></Setter>
     <Setter Property="Foreground" Value="White"></Setter>
     <Setter Property="FocusVisualStyle" Value="{x:Null}"></Setter>
     <Setter Property="Margin" Value="5"></Setter>
     <Setter Property="Height" Value="90"></Setter>
     <Setter Property="FontSize" Value="16"></Setter>
     <!--模板的样式-->
     <Setter Property="Template">
         <Setter.Value>
             <!--Button单选按钮样式-->
             <ControlTemplate TargetType="Button">
                 <Grid >
                     <Border Background="{TemplateBinding Background}" CornerRadius="5" >
                         <TextBlock Margin="10 5 10 5" Text="{TemplateBinding Content}" FontSize="{TemplateBinding FontSize}" HorizontalAlignment="Center" VerticalAlignment="Center"></TextBlock>
                     </Border>
                 </Grid>
                 <ControlTemplate.Triggers>
                     <!--鼠标放上去时的触发器-->
                     <Trigger Property="IsMouseOver" Value="True">
                         <Setter Property="Background" Value="#1E5FD1" ></Setter>
                     </Trigger>
                 </ControlTemplate.Triggers>

             </ControlTemplate>
         </Setter.Value>
     </Setter>
 </Style>
 
 <!--连接断开按钮样式-->
 <Style x:Key="ConnStyle" TargetType="Button">
     <Setter Property="Background" Value="#3F8666"></Setter>
     <Setter Property="Foreground" Value="White"></Setter>
     <Setter Property="FocusVisualStyle" Value="{x:Null}"></Setter>
     <Setter Property="Margin" Value="5"></Setter>
     <Setter Property="Height" Value="60"></Setter>
     <Setter Property="FontSize" Value="16"></Setter>
     <!--模板的样式-->
     <Setter Property="Template">
         <Setter.Value>
             <!--Button单选按钮样式-->
             <ControlTemplate TargetType="Button">
                 <Grid >
                     <Border Background="{TemplateBinding Background}" CornerRadius="5" >
                         <TextBlock Margin="10 5 10 5" Text="{TemplateBinding Content}" FontSize="{TemplateBinding FontSize}" HorizontalAlignment="Center" VerticalAlignment="Center"></TextBlock>
                     </Border>
                 </Grid>
                 <ControlTemplate.Triggers>
                     <!--鼠标放上去时的触发器-->
                     <Trigger Property="IsMouseOver" Value="True">
                         <Setter Property="Background" Value="#1E5FD1" ></Setter>
                     </Trigger>
                 </ControlTemplate.Triggers>
             </ControlTemplate>
         </Setter.Value>
     </Setter>
 </Style>


 <!--TextBox默认样式-->
 <Style TargetType="{x:Type TextBox}" x:Key="txtTextBoxStyle">
     <Setter Property="Width" Value="150"/>
     <Setter Property="Height" Value="25"/>
     <Setter Property="BorderBrush" Value="#FF105190"/>
     <Setter Property="BorderThickness" Value="1"/>
     <Setter Property="Margin" Value="2,0"/>
     <Setter Property="VerticalContentAlignment" Value="Center"/>
     <Setter Property="Background">
         <Setter.Value>
             <LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,1">
                 <GradientStop Color="White" Offset="0"/>
                 <GradientStop Color="#FFE4E4E4" Offset="1"/>
             </LinearGradientBrush>
         </Setter.Value>
     </Setter>
 </Style>

 <!--TextBlock默认样式-->
 <Style TargetType="{x:Type TextBlock}" x:Key="txtTextBlockStyle">
     <Setter Property="Margin" Value="1"/>
     <Setter Property="Height" Value="15"/>
 </Style>

 <!--页面下拉框样式-->
 <LinearGradientBrush x:Key="ComboBox.Static.Background" EndPoint="0,1" StartPoint="0,0">
     <GradientStop Color="White" Offset="0"/>
     <GradientStop Color="#FFE4E4E4" Offset="1"/>
 </LinearGradientBrush>
 <SolidColorBrush x:Key="ComboBox.Static.Border" Color="#FF105190"/>

 <!--combox默认样式-->
 <Style x:Key="cboStyle" TargetType="{x:Type ComboBox}">
     <Setter Property="Background" Value="{StaticResource ComboBox.Static.Background}"/>
     <Setter Property="BorderBrush" Value="{StaticResource ComboBox.Static.Border}"/>
     <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.WindowTextBrushKey}}"/>
     <Setter Property="Width" Value="150"/>
     <Setter Property="Height" Value="25"/>
     <Setter Property="BorderThickness" Value="1"/>
     <Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Auto"/>
     <Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto"/>
     <Setter Property="Padding" Value="6,3,5,3"/>
     <Setter Property="ScrollViewer.CanContentScroll" Value="true"/>
     <Setter Property="ScrollViewer.PanningMode" Value="Both"/>
     <Setter Property="Stylus.IsFlicksEnabled" Value="False"/>
 </Style>

 

 6、创建viewmodel

viewmodel是视图模型,wpf采用的是mvvm的渲染模式,即控件绑定对象的属性,属性发生更改时,驱动控件的数据显示,而控件动作是由命令command执行

1、模型基类

ViewModelBase.cs代码

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
using static MitsubishiMcToolWPF.MsgBoxWindow;

namespace MitsubishiMcToolWPF.ViewModel
{
    /// <summary>
    /// 视图模型基类
    /// </summary>
    public class ViewModelBase : INotifyPropertyChanged
    {
        /// <summary>
        /// 属性值发生更改时触发
        /// </summary>
        public event PropertyChangedEventHandler PropertyChanged;



        /// <summary>
        /// 执行更改
        /// C#5.0中的新特性CallerMemberName
        /// </summary>
        /// <param name="propertyName"></param>
        protected void OnPropertyChanged([CallerMemberName] string propertyName = "")
        {
            if (PropertyChanged != null)
            {
                PropertyChanged.Invoke(this, new PropertyChangedEventArgs(propertyName));
            }
        }


        /// <summary>
        /// 成功消息提示
        /// </summary>
        /// <param name="message"></param>
        /// <param name="title"></param>
        /// <param name="buttons"></param>
        public void ShowMessage(string message, string title = "提示", CustomMessageBoxButton buttons = CustomMessageBoxButton.OK)
        {
            Show(message, title, buttons, CustomMessageBoxIcon.Infomation);
        }

        /// <summary>
        /// 错误消息框
        /// </summary>
        /// <param name="message"></param>
        /// <param name="title"></param>
        /// <param name="buttons"></param>
        public void ShowError(string message, string title = "错误", CustomMessageBoxButton buttons = CustomMessageBoxButton.OK)
        {
            Show(message, title, buttons, CustomMessageBoxIcon.Error);
        }

        /// <summary>
        /// 询问消息框
        /// </summary>
        /// <param name="message"></param>
        /// <param name="title"></param>
        /// <param name="buttons"></param>
        /// <returns></returns>
        public CustomMessageBoxResult ShowQuestion(string message, string title = "询问", CustomMessageBoxButton buttons = CustomMessageBoxButton.OKCancel)
        {
            return Show(message, title, buttons, CustomMessageBoxIcon.Question);
        }



    }
}

 2、主页模型mainviewmodel

MainViewModel.cs代码

 

using Mitsubishi.Communication.MC.Mitsubishi;
using MitsubishiMcToolWPF.Common;
using MitsubishiMcToolWPF.Model;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;

namespace MitsubishiMcToolWPF.ViewModel
{
    /// <summary>
    /// 视图模型
    /// </summary>
    public class MainViewModel : ViewModelBase
    {
        /// <summary>
        /// mctcp对象
        /// </summary>
        A3E mctcp;

        #region 属性

        PLCMemoryModel readPLCModel = SetInitModel();
        /// <summary>
        /// 读取PLC
        /// </summary>
        public PLCMemoryModel ReadPLCModel
        {
            get { return readPLCModel; }
            set
            {
                readPLCModel = ReadPLCModel;
                OnPropertyChanged();//属性通知
            }
        }

        PLCMemoryModel writePLCModel = SetInitModel();
        /// <summary>
        /// 写入PLC
        /// </summary>
        public PLCMemoryModel WritePLCModel
        {
            get { return writePLCModel; }
            set
            {
                writePLCModel = WritePLCModel;
                OnPropertyChanged();
            }
        }
        /// <summary>
        /// 初始化页面参数
        /// </summary>
        /// <returns></returns>
        private static PLCMemoryModel SetInitModel()
        {
            PLCMemoryModel model = new PLCMemoryModel();
            model.Area = "D";
            model.DataType = "short";
            model.Address = "100";
            model.Count = "1";
            return model;
        }

        private string hostName = "192.168.1.7";
        /// <summary>
        /// PLC地址
        /// </summary>
        public string HostName
        {
            get
            {
                return hostName;
            }
            set
            {
                hostName = value;
            }
        }

        private string hostPort = "6000";
        /// <summary>
        /// PLC端口
        /// </summary>
        public string HostPort
        {
            get { return hostPort; }
            set
            {
                hostPort = value;
            }
        }


        /// <summary>
        /// 存储区下拉框数据源
        /// </summary>
        public List<string> CboCustTypes
        {
            get
            {
                return new List<string>() { "D", "X", "Y", "M", "R", "S", "TS" };
            }
        }

        /// <summary>
        /// 数据类型
        /// </summary>
        public List<string> CboCustDatas
        {
            get
            {
                return new List<string>() { "short", "float", "bool" };
            }
        }

        private string readWords = "";
        /// <summary>
        /// 读数结果
        /// </summary>
        public string ReadWords
        {
            get { return readWords; }
            set
            {
                readWords = value;
                OnPropertyChanged();
            }
        }
        private string writeWords = "";
        /// <summary>
        /// 写入数据
        /// </summary>
        public string WriteWords
        {
            get { return writeWords; }
            set
            {
                writeWords = value;
                OnPropertyChanged();
            }
        }

        private string connectWords = "当前未连接";
        /// <summary>
        /// 连接状态
        /// </summary>
        public string ConnectWords
        {
            get { return connectWords; }
            set
            {
                connectWords = value;
                OnPropertyChanged();
            }
        }
        #endregion

        #region 命令

        /// </summary>
        /// <summary>
        ///连接按钮的命令 
        /// </summary>
        public ICommand ConnCommand
        {
            get
            {
                return new RelayCommand(o =>
                {
                    var name = HostName;
                    var port = HostPort;
                    mctcp = new A3E(name, short.Parse(port));// 创建连接 
                    var result = mctcp.Connect();// 开始连接PLC
                    if (!result.IsSuccessed)
                    {
                        ShowError(result.Message, "错误");
                        return;
                    }
                    ConnectWords = "PLC已连接";
                    ShowMessage("PLC连接成功", "提示");
                });
            }
        }


        /// </summary>
        /// <summary>
        ///断开按钮的命令 
        /// </summary>
        public ICommand CloseCommand
        {
            get
            {
                return new RelayCommand(o =>
                {
                    if (mctcp == null)
                    {
                        ShowError("PLC没有连接,不能断开", "错误");
                        return;
                    }
                    mctcp = null;
                    ConnectWords = "PLC已断开";
                });
            }
        }


        /// </summary>
        /// <summary>
        /// 读取按钮的命令 
        /// </summary>
        public ICommand ReadCommand
        {
            get
            {
                return new RelayCommand(o =>
                {
                    ReadWords = "";
                    var d = ReadPLCModel;
                    if (mctcp == null)
                    {
                        ShowError("PLC未连接,不能读取数据", "错误");
                        return;
                    }
                    //内存地址
                    string plcAddr = ReadPLCModel.Area + ReadPLCModel.Address;
                    //读取数量
                    short readCount = short.Parse(ReadPLCModel.Count);
                    //数据类型
                    string dataType = ReadPLCModel.DataType;
                    switch (dataType)
                    {
                        case "short":
                            var datas2 = mctcp.Read<short>(plcAddr, readCount);
                            if (!datas2.IsSuccessed)
                            {
                                ShowMessage(datas2.Message, "提示");
                                return;
                            }
                            ReadWords = string.Join(",", datas2.Datas);
                            break;
                        case "float":
                            var datas3 = mctcp.Read<float>(plcAddr, readCount);
                            if (!datas3.IsSuccessed)
                            {
                                ShowMessage(datas3.Message, "提示");
                                return;
                            }
                            ReadWords = string.Join(",", datas3.Datas);
                            break;
                        case "bool":
                            var datas4 = mctcp.Read<bool>(plcAddr, readCount);
                            if (!datas4.IsSuccessed)
                            {
                                ShowMessage(datas4.Message, "提示");
                                return;
                            }
                            ReadWords = string.Join(",", datas4.Datas);
                            break;
                    }
                });
            }
        }


        /// </summary>
        /// <summary>
        /// 写入按钮的命令处理
        /// </summary>
        public ICommand WriteCommand
        {
            get
            {
                return new RelayCommand(o =>
                {
                    if (mctcp == null)
                    {
                        ShowError("PLC未连接,不能写入数据", "错误");
                        return;
                    }
                    var d = WritePLCModel;
                    //内存地址
                    string plcAddr = WritePLCModel.Area + WritePLCModel.Address;
                    //写入数量 
                    ushort writeCount = ushort.Parse(WritePLCModel.Count);
                    //数据类型
                    string dataType = WritePLCModel.DataType;
                    //实际数量
                    string objWriteVals = WriteWords;
                    ushort objWCount = (ushort)objWriteVals.Split(',').Length;
                    //实际数量与要求数量不一致,不允许操作
                    if (writeCount != objWCount)
                    {
                        ShowError("写入值的数量不正确!");
                        return;
                    }
                    List<string> vals = objWriteVals.Split(',').ToList();
                    switch (dataType)
                    {
                        case "short":
                            //实际数值转换成list集合 short类型
                            List<short> objshort = new List<short>();
                            vals.ForEach((x) =>
                            {
                                objshort.Add(short.Parse(x));
                            });
                            var finish2 = mctcp.Write<short>(objshort, plcAddr);
                            if (finish2.IsSuccessed)
                            {
                                ShowMessage("写入成功", "提示");
                            }
                            break;
                        case "float":
                            //实际数值转换成list集合 float
                            List<float> objfloat = new List<float>();
                            vals.ForEach((x) =>
                            {
                                objfloat.Add(float.Parse(x));
                            });
                            var finish3 = mctcp.Write<float>(objfloat, plcAddr);
                            if (finish3.IsSuccessed)
                            {
                                ShowMessage("写入成功", "提示");
                            }
                            break;
                        case "bool":
                            //实际数值转换成list集合bool
                            List<bool> objbool = new List<bool>();
                            vals.ForEach((x) =>
                            {
                                if (x == "1")
                                {
                                    objbool.Add(true);
                                }
                                else
                                {
                                    objbool.Add(false);
                                }
                            });
                            var finish4 = mctcp.Write<bool>(objbool, plcAddr);
                            if (finish4.IsSuccessed)
                            {
                                ShowMessage("写入成功", "提示");
                            }
                            break;
                    }
                });
            }
        }
        #endregion

    }
}

7、主界面布局

MainWindow.xaml完整代码

<Window x:Class="MitsubishiMcToolWPF.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:MitsubishiMcToolWPF.ViewModel"
        mc:Ignorable="d"   
        FontSize="13" FontFamily="Microsoft YaHei"  ResizeMode="CanMinimize" Title="三菱PLC通讯工具" FontWeight="ExtraLight" WindowStartupLocation="CenterScreen"  Height="450" Width="880" Name="mainWin"  >
    <Window.DataContext>
        <local:MainViewModel/>
    </Window.DataContext>
    <Grid   ShowGridLines="true">
        <Grid.RowDefinitions>
            <RowDefinition Height="62"/>
            <RowDefinition/>
        </Grid.RowDefinitions>

        <!--第一行标题-->
        <Grid Grid.Row="0" Background="BlanchedAlmond">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="100" />
                <ColumnDefinition />
            </Grid.ColumnDefinitions>
            <Image Grid.Column="0" Source="/imgs/log1.png"  Width="60" Height="60" Margin="20,0" />
            <TextBlock Grid.Column="1"   Text="三菱MC协议通讯调试助手(Qna-3E模式)" FontSize="23" VerticalAlignment="Center"  FontWeight="Bold" />
        </Grid>

        <!--第二行信息-->
        <Grid Grid.Row="1" Margin="0 10 0 0">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="200"/>
                <ColumnDefinition Width="4"/>
                <ColumnDefinition/>
            </Grid.ColumnDefinitions>
            <!--第一列PLC参数-->
            <StackPanel Grid.Column="0" Margin="20">
                <TextBlock Text="PLC地址"/>
                <TextBox   Height="30" VerticalContentAlignment="Center" Padding="5,0" Margin="0,10" Text="{Binding HostName}"  />
                <TextBlock Text="端口号" Margin="0,10,0,0"/>
                <TextBox  Height="30" VerticalContentAlignment="Center" Padding="5,0" Margin="0,10" Text="{Binding HostPort}"  />
                <Button Content="连接" Margin="0,30,0,0" Height="30"   Command="{Binding ConnCommand}"  Style="{StaticResource ConnStyle}" />
                <Button Content="断开" Margin="0,10" Height="30"  Command="{Binding CloseCommand}"  Style="{StaticResource ConnStyle}"/>
                <TextBlock  Text="{Binding ConnectWords,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"  Margin="0,10,0,0"  Foreground="Blue"/>
            </StackPanel>
            <!--第二列分隔线-->
            <GridSplitter Grid.Column="1" Background="#4490AC" Width="2" Height="450" Margin="0 -11 0 0"></GridSplitter>
            <!--第三列操作区-->
            <Grid Grid.Column="2">
                <Grid.RowDefinitions>
                    <RowDefinition Height="60"/>
                    <RowDefinition Height="80"/>
                    <RowDefinition Height="30"/>
                    <RowDefinition Height="60"/>
                    <RowDefinition Height="80"/>
                </Grid.RowDefinitions>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition/>
                    <ColumnDefinition/>
                </Grid.ColumnDefinitions>
                <StackPanel Orientation="Horizontal" Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2" Margin="10">
                    <TextBlock     Text="存储区:"  Style="{StaticResource  txtTextBlockStyle}" Margin="0 0 0 0" ></TextBlock>
                    <ComboBox  ItemsSource="{Binding CboCustTypes}" SelectedValue="{Binding  ReadPLCModel.Area}"  Width="70"  Style="{StaticResource cboStyle}"></ComboBox>
                    <TextBlock   Text="数据类型:"  Style="{StaticResource  txtTextBlockStyle}" ></TextBlock>
                    <ComboBox     ItemsSource="{Binding CboCustDatas}" SelectedValue="{Binding ReadPLCModel.DataType}"  Width="70"  Style="{StaticResource cboStyle}"></ComboBox>
                    <TextBlock   Text="地址:" Style="{StaticResource  txtTextBlockStyle}" ></TextBlock>
                    <TextBox    Text="{Binding ReadPLCModel.Address}"  Width="100"  Style="{StaticResource  txtTextBoxStyle}" />
                    <TextBlock   Text="数量:" Style="{StaticResource  txtTextBlockStyle}" ></TextBlock>
                    <TextBox    Text="{Binding ReadPLCModel.Count}"  Width="60" Style="{StaticResource  txtTextBoxStyle}"  />
                    <Button Content="读取" Height="30" Width="100"  Command="{Binding ReadCommand}" CommandParameter="{Binding ElementName=loginWin}" Style="{StaticResource ButtonStyle}"  />
                </StackPanel>

                <StackPanel Orientation="Vertical" Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2"  Margin="10">
                    <TextBlock Text="读取结果(多个数据之间用逗号隔开)"  Style="{StaticResource  txtTextBlockStyle}" Margin="0 3 0 9"></TextBlock>
                    <TextBox   Text="{Binding ReadWords,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"  Width="616" Style="{StaticResource  txtTextBoxStyle}"  Margin="-23,0,0,0"   />
                </StackPanel>

                <StackPanel Orientation="Horizontal"  Grid.Row="2"  Grid.Column="0" Grid.ColumnSpan="2" Background="#4490AC" Width="706" Height="2" Margin="-1,0,0,0"></StackPanel>

                <StackPanel Orientation="Horizontal" Grid.Row="3" Grid.Column="0" Grid.ColumnSpan="2"  Margin="10">
                    <TextBlock     Text="存储区:" Style="{StaticResource  txtTextBlockStyle}" Margin="0 0 0 0"></TextBlock>
                    <ComboBox    ItemsSource="{Binding CboCustTypes}" SelectedValue="{Binding WritePLCModel.Area }"  Width="70"  Style="{StaticResource cboStyle}"></ComboBox>
                    <TextBlock   Text="数据类型:" Style="{StaticResource  txtTextBlockStyle}" ></TextBlock>
                    <ComboBox     ItemsSource="{Binding CboCustDatas}" SelectedValue="{Binding WritePLCModel.DataType }"  Width="70"  Style="{StaticResource cboStyle}"></ComboBox>
                    <TextBlock   Text="地址:" Style="{StaticResource  txtTextBlockStyle}" ></TextBlock>
                    <TextBox   Text="{Binding  WritePLCModel.Address }"  Width="100"  Style="{StaticResource  txtTextBoxStyle}"  />
                    <TextBlock   Text="数量:" Style="{StaticResource  txtTextBlockStyle}" ></TextBlock>
                    <TextBox    Text="{Binding WritePLCModel.Count}"  Width="60"   Style="{StaticResource  txtTextBoxStyle}"  />
                    <Button Content="写入" Height="30" Width="100"   Command="{Binding WriteCommand}" CommandParameter="{Binding ElementName=loginWin}" Style="{StaticResource ButtonStyle}" />
                </StackPanel>

                <StackPanel Orientation="Vertical" Grid.Row="4" Grid.Column="0" Grid.ColumnSpan="2"  Margin="10">
                    <TextBlock   Text="写入数据(多个数据之间用逗号隔开)" Style="{StaticResource  txtTextBlockStyle}"  Margin="0 3 0 9" ></TextBlock>
                    <TextBox    Text="{Binding WriteWords ,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"  Width="616" Style="{StaticResource  txtTextBoxStyle}"  Margin="-23,0,0,0"  />
                </StackPanel>

            </Grid>
        </Grid>
    </Grid>
</Window>

 

 8、启动MC服务器

 9、异常错误处理

 

10、操作测试

1、连接PLC

2、读取数据,short,float,bool

 

3、写入数据,short,float

 写入short

写入float

 

3、小结

 

走过路过不要错过,点赞关注收藏又圈粉,共同致富。

欢迎抄袭,复制,分享,转载,学习,截图..............

欢迎抄袭,复制,分享,转载,学习,截图..............

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

HEVC视频编解码标准学习笔记-1

视频编解码标准H.265/HEVC&#xff08;High Efficiency Video Coding&#xff09;通过将视频数据编码为更高效格式&#xff0c;大幅改善了视频流的压缩效率。这里主要介绍Tile、Slice和CTU的定义&#xff0c;以及介绍这些技术组件之间的相互关系。 CTU&#xff08;编码树单元&…

【数据结构】C语言实现二叉树的相关操作

树 定义 树&#xff08;Tree&#xff09;是 n (n > 0) 个结点的有限集 若 n 0&#xff0c;称为空树 若 n > 0&#xff0c;则它满足如下两个条件&#xff1a; 有且仅有一个特定的称为根&#xff08;Root&#xff09;的结点其余结点可分为 m(m>0) 个互不相交的有限…

云原生超融合八大核心能力|ZStack Edge云原生超融合产品技术解读

企业数字化转型的焦点正在发生变化&#xff0c;云基础设施由资源到应用&#xff0c;数据中心从核心到边缘。面向云原生趋势&#xff0c;围绕应用升级&#xff0c;新一代超融合产品——云原生超融合应运而生。 ZStackEdge云原生超融合是基于云原生架构研发的新一代IT基础设施 …

Docker基础篇(四) 容器数据卷 容器间传递共享(--volumes-from)

容器间传递共享 当前没有运行的容器 两个数据卷&#xff1a; containVolum-01 containVolum-02 docker run -it --name zenA zen/centos 上面生成了容器 zenA ctrl P Q docker run -it --name zenB1 --volumes-from zenA zen/centos ctrl P Q docker run -it --name zen…

07 Redis之持久化(RDB(Redis DataBase) + 写时复制 + AOF(Append Only File)+混合持久化)

4 Redis持久化 Redis 是一个内存数据库&#xff0c;然而内存中的数据是不持久的&#xff0c;若主机宕机或 Redis 关机重启&#xff0c;则内存中的数据全部丢失。 当然&#xff0c;这是不允许的。Redis 具有持久化功能&#xff0c;其会按照设置以快照或操作日志的形式将数据持…

GEE入门篇|遥感专业术语(实践操作2):空间分辨率(Spatial Resolution)

目录 空间分辨率&#xff08;Spatial Resolution&#xff09; 1.MODIS&#xff08;搭载在Aqua 和 Terra 卫星上&#xff09; 2. TM&#xff08;搭载在早期LandSat卫星上&#xff09; 3.MSI&#xff08;搭载在在Sentinel-2 卫星上&#xff09; 4.NAIP 空间分辨率&#xff0…

Unity中.Net与Mono的关系

什么是.NET .NET是一个开发框架&#xff0c;它遵循并采用CIL(Common Intermediate Language)和CLR(Common Language Runtime)两种约定&#xff0c; CIL标准为一种编译标准&#xff1a;将不同编程语言&#xff08;C#, JS, VB等&#xff09;使用各自的编译器&#xff0c;按照统…

C++ STL vector详解

1. vector简介 template<class T, class Alloc allocator<T>> class vector; vector是一个可以动态增长的数组&#xff0c;T是要存储的元素类型。vector可以像数组一样&#xff0c;用下标[]来访问元素&#xff0c;如&#xff1a; int arr[] {1,2,3,4}; for (i…

[极客挑战2019]HTTP

这道题考察的是http请求头字段的含义和使用&#xff1b; 具体如下 Referer:来源地址 User-Agent:客户端配置信息&#xff1a;浏览器类型、版本、系统类型等 X-Forwarded-For:代理地址&#xff0c;即数据发出的地址 开始解题&#xff1a;&#xff08;对我这初学者真的烧脑&a…

【机器学习】特征工程之特征选择

&#x1f388;个人主页&#xff1a;豌豆射手^ &#x1f389;欢迎 &#x1f44d;点赞✍评论⭐收藏 &#x1f917;收录专栏&#xff1a;机器学习 &#x1f91d;希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff0c;让我们共同学习、交流进…

抖音视频评论数据提取软件|抖音数据抓取工具

一、开发背景&#xff1a; 在业务需求中&#xff0c;我们经常需要下载抖音视频。然而&#xff0c;在网上找到的视频通常只能通过逐个复制链接的方式进行抓取和下载&#xff0c;这种操作非常耗时。我们希望能够通过关键词自动批量抓取并选择性地下载抖音视频。因此&#xff0c;为…

Pycharm服务器配置与内网穿透工具结合实现远程开发的解决方法

文章目录 一、前期准备1. 检查IDE版本是否支持2. 服务器需要开通SSH服务 二、Pycharm本地链接服务器测试1. 配置服务器python解释器 三、使用内网穿透实现异地链接服务器开发1. 服务器安装Cpolar2. 创建远程连接公网地址 四、使用固定TCP地址远程开发 本文主要介绍如何使用Pych…

STM32CubeMX FOC工程配置(AuroraFOC)

一. 简介 哈喽&#xff0c;大家好&#xff0c;今天给大家带来基于AuroraFOC开发板的STM32CubeMX的工程配置&#xff0c;主要配置的参数如下: 1. 互补PWM输出 2. 定时器注入中断ADC采样 3. SPI配置 4. USB CDC配置 5. RT Thread配置 大家如果对这几部分感兴趣的话&#xff0c…

C语言——实用调试技巧——第2篇——(第23篇)

坚持就是胜利 文章目录 一、实例二、如何写出好&#xff08;易于调试&#xff09;的代码1、优秀的代码2、示范&#xff08;1&#xff09;模拟 strcpy 函数方法一&#xff1a;方法二&#xff1a;方法三&#xff1a;有弊端方法四&#xff1a;对方法三进行优化assert 的使用 方法五…

浅析DPDK内存管理:Mempool

文章目录 前言Mempool工作机制Mempool数据结构rte_mempool_opsMempool操作接口rte_mempool_create&#xff1a;创建Mempoolrte_mempool_get&#xff1a;申请对象rte_mempool_put&#xff1a;释放对象 相关参考 前言 DPDK提供了一套内存池管理机制&#xff0c;以提供高效分配固…

了解人工智能的13个细分领域

人工智能&#xff08;Artificial Intelligence&#xff0c;简称AI&#xff09;作为当今最热门和前沿的技术之一&#xff0c;已经在各种领域发挥着越来越重要的作用。随着人工智能技术的不断进步和应用&#xff0c;AI的细分领域也越来越多。目前&#xff0c;根据AI的应用领域和特…

flink源码分析 - 获取调用位置信息

flink版本: flink-1.11.2 调用位置: org.apache.flink.streaming.api.datastream.DataStream#flatMap(org.apache.flink.api.common.functions.FlatMapFunction<T,R>) 代码核心位置: org.apache.flink.api.java.Utils#getCallLocationName() flink算子flatmap中调用了一…

【深度学习笔记】3_6 代码实现softmax-regression

注&#xff1a;本文为《动手学深度学习》开源内容&#xff0c;仅为个人学习记录&#xff0c;无抄袭搬运意图 3.6 softmax回归的从零开始实现 这一节我们来动手实现softmax回归。首先导入本节实现所需的包或模块。 import torch import torchvision import numpy as np import…

神经网络系列---权重初始化方法

文章目录 权重初始化方法Xavier初始化&#xff08;Xavier initialization&#xff09;Kaiming初始化&#xff0c;也称为He初始化LeCun 初始化正态分布与均匀分布Orthogonal InitializationSparse Initializationn_in和n_out代码实现 权重初始化方法 Xavier初始化&#xff08;X…

java面试题之SpringMVC篇

Spring MVC的工作原理 Spring MVC的工作原理如下&#xff1a; DispatcherServlet 接收用户的请求找到用于处理request的 handler 和 Interceptors&#xff0c;构造成 HandlerExecutionChain 执行链找到 handler 相对应的 HandlerAdapter执行所有注册拦截器的preHandler方法调…