带有 PLC DDE 连接的 WPF 应用程序

问题描述

我正在使用 DDE App Nuget Library 连接到 PLC(目前使用模拟器)

我设法与 PLC 建立了连接,并且可以使用 RSLinx > DDE/OPC > DDE 客户端诊断查看 DDE 客户端...

但是,当我尝试戳标签(强制更改值)时,它不起作用。我尝试了各种输入组合。

以下是此应用程序的 C# 和 XAML 代码

C# 代码

using System;
using System.Text;
using System.Windows;
using NDde.Advanced;
using NDde.Client;

namespace PLC_Simulator
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        #region Fields

        private DdeClient client = null;

        #endregion
        
        #region Properties

        #region AppString
        /// <summary>
        /// Gets or Sets the AppString property.
        /// </summary>
        public string AppString
        {
            get { return (string)GetValue(AppStringProperty); }
            set { SetValue(AppStringProperty,value); }
        }

        /// <summary>
        /// Using a DependencyProperty as the backing store for AppString.  This enables animation,styling,binding,etc...
        /// </summary>
        public static readonly DependencyProperty AppStringProperty =
            DependencyProperty.Register(nameof(AppString),typeof(string),typeof(MainWindow));
        #endregion

        #region TopicString
        /// <summary>
        /// Gets or Sets the TopicString property.
        /// </summary>
        public string TopicString
        {
            get { return (string)GetValue(TopicStringProperty); }
            set { SetValue(TopicStringProperty,value); }
        }

        /// <summary>
        /// Using a DependencyProperty as the backing store for TopicString.  This enables animation,etc...
        /// </summary>
        public static readonly DependencyProperty TopicStringProperty =
            DependencyProperty.Register(nameof(TopicString),typeof(MainWindow));
        #endregion

        #region PokeString
        /// <summary>
        /// Gets or Sets the PokeString property.
        /// </summary>
        public string PokeString
        {
            get { return (string)GetValue(PokeStringProperty); }
            set { SetValue(PokeStringProperty,value); }
        }

        /// <summary>
        /// Using a DependencyProperty as the backing store for PokeString.  This enables animation,etc...
        /// </summary>
        public static readonly DependencyProperty PokeStringProperty =
            DependencyProperty.Register(nameof(PokeString),typeof(MainWindow));
        #endregion

        #region PokeData
        /// <summary>
        /// Gets or Sets the PokeData property.
        /// </summary>
        public string PokeData
        {
            get { return (string)GetValue(PokeDataProperty); }
            set { SetValue(PokeDataProperty,value); }
        }

        /// <summary>
        /// Using a DependencyProperty as the backing store for PokeData.  This enables animation,etc...
        /// </summary>
        public static readonly DependencyProperty PokeDataProperty =
            DependencyProperty.Register(nameof(PokeData),typeof(MainWindow));
        #endregion

        #endregion

        #region Constructors

        public MainWindow()
        {
            Closing += MainWindow_Closing;
            InitializeComponent();
        }

        #endregion

        #region Methods

        private bool CheckClient()
        {
            if (client == null)
            {
                MessageBox.Show("No Application Loaded","Error");
                return false;
            }
            if (!client.IsConnected)
            {
                MessageBox.Show("Application is not connected","Error");
                return false;
            }
            return true;
        }

        private void CloseClient()
        {
            client.disconnected -= Client_disconnected;

            if (client.IsConnected)
                client.disconnect();
            
            client.dispose();
            client = null;
        }

        #endregion

        #region Delegates,Events,Handlers

        private void MainWindow_Closing(object sender,System.ComponentModel.CancelEventArgs e)
        {
            if (client != null)
                CloseClient();
        }

        private void Select_DDE_Button_Click(object sender,RoutedEventArgs e)
        {
            try
            {
                if (client != null)
                    CloseClient();

                DdeContext context = new DdeContext()
                {
                    Encoding = Encoding.ASCII,};
                client = new DdeClient(AppString,TopicString,context);
                client.Connect();
                client.disconnected += Client_disconnected;
                MessageBox.Show("Application Loaded Successfully");
            }
            catch (Exception ex)
            {
                MessageBox.Show($"Application Failed to load:\n{ex.Message}","Error");
            }
        }

        private void Client_disconnected(object sender,DdedisconnectedEventArgs e)
        {
            MessageBox.Show("Application disconnected","Warning");
        }

        private void Poke_Button_Click(object sender,RoutedEventArgs e)
        {
            if (!CheckClient())
                return;

            try
            {
                client.Poke(PokeString,PokeData,60000);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message,"Error");
            }
        }

        private void Request_Button_Click(object sender,RoutedEventArgs e)
        {
            if (!CheckClient())
                return;

            client.BeginRequest(PokeString,1,OnRequestComplete,client);
        }

        private void OnRequestComplete(IAsyncResult ar)
        {
            try
            {
                DdeClient client = (DdeClient)ar.AsyncState;
                byte[] data = client.EndRequest(ar);
                Console.WriteLine("OnRequestComplete: " + Encoding.ASCII.GetString(data));
            }
            catch (Exception e)
            {
                Console.WriteLine("OnRequestComplete: " + e.Message);
            }
        }

        #endregion
    }
}

WPF XAML 代码

<Window x:Class="PLC_Simulator.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:PLC_Simulator"
        mc:Ignorable="d"
        DataContext="{Binding RelativeSource={RelativeSource Mode=Self}}"
        Height="450" 
        Width="800">
    <Grid>
        <Grid.ColumnDeFinitions>
            <ColumnDeFinition Width="100"/>
            <ColumnDeFinition />
        </Grid.ColumnDeFinitions>
        <Grid.RowDeFinitions>
            <RowDeFinition Height="30" />
            <RowDeFinition Height="30" />
            <RowDeFinition Height="30" />
            <RowDeFinition Height="30" />
            <RowDeFinition Height="30" />
            <RowDeFinition Height="30" />
            <RowDeFinition />
        </Grid.RowDeFinitions>
        <TextBlock Text="Application: "
                   Margin="5"
                   VerticalAlignment="Center" />
        <TextBox Grid.Column="1"
                 Height="25"
                 HorizontalAlignment="Left"
                 Text="{Binding Path=AppString}"
                 Width="150" />
        <TextBlock Text="Topic: "
                   Grid.Row="1"
                   Margin="5"
                   VerticalAlignment="Center" />
        <TextBox Grid.Column="1"
                 Grid.Row="1"
                 Height="25"
                 HorizontalAlignment="Left"
                 Text="{Binding Path=TopicString}"
                 Width="150"/>
        <Button Grid.Column="1"
                Grid.Row="1"
                Height="25"
                Width="112"
                Content="Load"
                Click="Select_DDE_Button_Click" />
        <TextBlock Grid.Row="2"
                   Text="Poke String:"
                   Margin="5" />
        <TextBox Grid.Column="1"
                 Grid.Row="2"
                 Height="25"
                 HorizontalAlignment="Left"
                 Width="150"
                 Text="{Binding Path=PokeString}" />
        <TextBlock Grid.Row="3"
                   Text="Poke Data:"
                   Margin="5" />
        <TextBox Grid.Column="1"
                 Grid.Row="3"
                 Height="25"
                 HorizontalAlignment="Left"
                 Width="150"
                 Text="{Binding Path=PokeData}" />
        <StackPanel Grid.Column="1"
                    Grid.Row="3"
                    HorizontalAlignment="Center"
                    Orientation="Horizontal">
            <Button Height="25"
                    Width="112"
                    Margin="5,5,0"
                    Content="Poke"
                    Click="Poke_Button_Click" />
            <Button Height="25"
                    Width="112"
                    Margin="5,0"
                    Content="Request"
                    Click="Request_Button_Click" />
        </StackPanel>
    </Grid>
</Window>

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)