前言
工业自动化领域的不断发展,人机交互界面(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
声明:网络内容,仅供学习,尊重版权,侵权速删,歉意致谢!