WPF 实现 TIA WinCC三大功能(可见性、文本列表与输入输出域)

612 阅读5分钟

前言

工业自动化领域的不断发展,人机交互界面(HMI)的设计变得越来越重要。TIA Portal 中的 WinCC 作为一款强大的 HMI 软件,提供了丰富的功能来满足各种工业应用场景的需求。然而,在某些特定情况下,开发者可能希望使用 WPF来构建更为灵活和定制化的上位机软件。

本文将探讨如何在 WPF 应用程序中实现 WinCC 中常见的三大功能:可见性控制、文本列表展示以及输入输出域的实现。

通过这些功能的实现,WPF 上位机软件可以更好地适应现代工业控制系统的复杂需求。

正文

1、使用转换器实现TIA Wincc中的可见性和外观功能

在TIA Wincc 中有这样的功能,使用True or false 控制控件的可见性或者外观的情况。

在上位机中需要使用转换器这样对True or false 值转换为 需要的笔刷或者Visible属性。

using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Data;
using System.Windows.Media;

namespace SiemensAxisControl.Model.Converter
{
    public class BoolToBrushConverter : IValueConverter
    {
        public object Convert(object value , Type targetType, object parameter, CultureInfo culture)
        {
            if (value != null && bool.Parse(value.ToString()))
            {
                return new SolidColorBrush(Color.FromRgb(0,255,0));
            }
            return Brushes.White;
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
}

还有一种情况,不是True or false 的布尔值,而是根据整形值的情况改变控件的可见性或者外观。 如在TIA中以下的情况

变量值等于某一个值改变外观

变量值在某一个区间内改变外观

using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Data;
using System.Windows.Media;

namespace SiemensAxisControl.Model.Converter
{
    internal class IntToBrushConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            // 尝试将参数解析为两个整数值,分别代表下限和上限
            if (parameter != null && parameter.ToString().Split('-').Length == 2 &&
                int.TryParse(parameter.ToString().Split('-')[0], out int lowerBound) &&
                int.TryParse(parameter.ToString().Split('-')[1], out int upperBound))
            {
                    // 检查传入的值是否在指定的范围内
                    if (value is short intValue &&  intValue >= lowerBound && intValue <= upperBound)
                    {
                        return new SolidColorBrush(Color.FromRgb(0, 255, 0)); ;
                    }
            }
            // 如果不满足条件,则默认为白色
            return Brushes.White;
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
}

2、使用转换器实现TIA Wincc中的文本列表功能

TIA wincc中可以根据变量的值,显示出定义的文本。

在WPF中可以通过转换器实现。

使用哈希表存储变量和文本,根据变量值返回对应的文本显示在View 中

using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Data;

namespace SiemensAxisControl.Model.Converter
{
    internal class StringToStatusConverter : IValueConverter
    {
        private static readonly Dictionary<string, string> StatusDic = new Dictionary<string, string>()
        {
            {"7000", "STATUS_NO_CALL" },
            {"7001", "STATUS_FB_FIRST_CALL" },
            {"7002", "STATUS_SUBSEQUENT_CALL" },
            {"8001", "ERR_INVALID_BASIC_MOTION_CMD" },
            {"8002", "ERR_INVALID_EXTENDED_CMD" },
            {"8200", "ERR_INVALID_CAM" },
            {"8201", "ERR_INVALID_JOG_MODE" },
            {"8202", "ERR_INVALID_HOMING_EXTENDED_MODE" },
            {"8203", "ERR_TORQUE_LIMITING_NOT_ALLOWED" },
            {"8204", "ERR_INVALID_JOG_DIR" },
            {"8205", "ERR_INVALID_POS_RELATIVE_DIR" },
            {"8206", "ERR_INVALID_POS_SUPERIMPOSED_DIR" },
            {"8207", "ERR_HOMING_MODE_NOT_ALLOWED" },
            {"8208", "ERR_MODULO_NOT_ALLOWED" },
            {"8209", "ERR_INVALID_TORQUE_LIMIT" },
            {"8210", "ERR_INVALID_VELOCITY" },
            {"8600", "ERR_MC_POWER" },
            {"8601", "ERR_MC_RESET" },
            {"8602", "ERR_MC_HOME" },
            {"8603", "ERR_MC_TORQUELIMITING" },
            {"8604", "ERR_MC_HALT" },
            {"8605", "ERR_MC_MOVEJOG" },
            {"8606", "ERR_MC_MOVEVELOCITY" },
            {"8607", "ERR_MC_MOVERELATIVE" },
            {"8608", "ERR_MC_MOVEABSOLUTE" },
            {"8609", "ERR_MC_MOVESUPERIMPOSED" },
            {"860A", "ERR_MC_GEARIN" },
            {"860B", "ERR_MC_PHASINGABSOLUTE"},
            {"860C", "ERR_MC_PHASINGRELATIVE" },
            {"860D", "ERR_MC_CAMIN" },
            {"860E", "ERR_MC_GEARINPOS" },
            {"860F", "ERR_MC_SYNCHRONIZEDMOTIONSIMULATION" },
            {"8700", "ERR_UNDEFINED_FB_STATE" },
            {"8701", "ERR_UNDEFINED_RESET_STATE" },
            {"8702", "ERR_UNDEFINED_BASIC_MOTION_STATE" },
            {"8703", "ERR_UNDEFINED_TORQUE_LIMITING_STATE" },
            {"8704", "ERR_UNDEFINED_INCREMENTAL_JOG_STATE" },
            {"8705", "ERR_UNDEFINED_INCREMENTAL_JOG_SUBSTATE" },
            {"8706", "ERR_UNDEFINED_EXTENDED_HOMING_STATE" },
            {"8707", "ERR_UNDEFINED_EXTENDED_HOMING_SUBSTATE" },
            {"8708", "ERR_UNDEFINED_SUPERIMPOSED_MOTION_STATE" },
            {"8709", "ERR_UNDEFINED_MOTION_SIMULATION_STATE" },
            {"8710", "ERR_UNDEFINED_MAIN_SELECTION_STATE" }
        };
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            string Status = "Last Command Ok";
            // 检查传入的值是否在指定的范围内
            if (value is string key)
            {

                if (StatusDic.ContainsKey(key))
                {
                    Status = StatusDic[key];
                }
            }

            return Status;
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
}

3、实现TIA Wincc中的输入输出域

在TIA Wincc中输入输出域可以显示PLC中的变量,同时可以改变PLC中的变量,而在上位机中,使用多线程实时读取数据,在输入数据的时候可能PLC数据改变使得上位机数据同时改变。

所以需要在文本框获取到焦点的时候断开绑定,失去焦点的时候重新绑定数据。

<TextBox
    Width="100"
    Margin="5,0,5,0"
    Text="{Binding InternalAxis.Velocity}">
    <behaviors:Interaction.Triggers>
        <behaviors:EventTrigger EventName="GotFocus">
            <behaviors:InvokeCommandAction Command="{Binding VelocityFoucsCommand}" CommandParameter="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=TextBox}}" />
        </behaviors:EventTrigger>
        <behaviors:EventTrigger EventName="LostFocus">
            <behaviors:InvokeCommandAction Command="{Binding VelocityChangedCommand}" CommandParameter="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=TextBox}}" />
        </behaviors:EventTrigger>
    </behaviors:Interaction.Triggers>
</TextBox>
private void TargetValueFocus(TextBox control, string property)
{
    Binding binding = new Binding(property);
    binding.Mode = BindingMode.OneWay;
    if(control != null)
    {
        control.SetBinding(TextBox.TextProperty, binding);
    }
}

private void TargetValueChange(TextBox control, string property, int startByteAdr)
{
    Binding binding = new Binding(property);
    binding.Mode = BindingMode.TwoWay;

    var value = Convert.ToDouble(control.Text);

    SiemensPlc.Instance.AxisController.Write(DataType.DataBlock, SiemensPlc.Instance.InterfaceDB, startByteAdr, value);

    control.SetBinding(TextBox.TextProperty, binding);
}

[RelayCommand]
private void VelocityFoucs(object o)
{
    var control = o as TextBox;

    TargetValueFocus(control, "InternalAxis.Velocity");
}
[RelayCommand]
private void VelocityChanged(object o)
{
    var startByteAdrMode = (AxisId * 730) + 130;
    var control = o as TextBox;

    TargetValueChange(control, "InternalAxis.Velocity", startByteAdrMode);
}

总结

通过本文的介绍,我们详细讲解了如何在 WPF 上位机软件中实现 WinCC 中的关键功能,包括控件的可见性控制、动态文本列表的展示以及输入输出域的实现。

这些技术不仅增强了 WPF 应用程序的灵活性和可定制性,还使得开发者能够更加高效地构建符合工业标准的人机交互界面。

最后

如果你觉得这篇文章对你有帮助,不妨点个赞支持一下!你的支持是我继续分享知识的动力。如果有任何疑问或需要进一步的帮助,欢迎随时留言。

也可以加入微信公众号 [DotNet技术匠] 社区,与其他热爱技术的同行一起交流心得,共同成长!

优秀是一种习惯,欢迎大家留言学习!

作者:4LPH4_αX

出处:cnblogs.com/Tristan998/p/18171524

声明:网络内容,仅供学习,尊重版权,侵权速删,歉意致谢!