Initial Push
This commit is contained in:
@@ -0,0 +1,33 @@
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using System.Globalization;
|
||||
using System.Windows.Controls;
|
||||
|
||||
namespace HMIToolkit
|
||||
{
|
||||
public sealed partial class AnalogRangeValidator : ValidationRule
|
||||
{
|
||||
public float Min { get; set; }
|
||||
|
||||
public float Max { get; set; }
|
||||
|
||||
public override ValidationResult Validate(object value, CultureInfo cultureInfo)
|
||||
{
|
||||
float analogValue = 0;
|
||||
|
||||
try
|
||||
{
|
||||
if (((string)value).Length > 0)
|
||||
analogValue = float.Parse((string)value);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
return new ValidationResult(false, $"Illegal characters or {e.Message}");
|
||||
}
|
||||
|
||||
if ((analogValue < Min) || (analogValue > Max))
|
||||
return new ValidationResult(false, $"Please enter a value in the range: {Min}-{Max}.");
|
||||
|
||||
return ValidationResult.ValidResult;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
<UserControl x:Class="HMIToolkit.AnalogValue"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="clr-namespace:HMIToolkit"
|
||||
d:DataContext="{d:DesignInstance Type=local:AnalogValueVM, IsDesignTimeCreatable=True}"
|
||||
mc:Ignorable="d"
|
||||
Width="Auto"
|
||||
Height="Auto">
|
||||
<!-- :DataContext="{d:DesignInstance Type=local:AnalogValueVM, IsDesignTimeCreatable=True}" -->
|
||||
<!-- Style to see things in the designer-->
|
||||
<d:DesignerProperties.DesignStyle>
|
||||
<Style TargetType="UserControl">
|
||||
<!-- Property="Background" Value="White" /> -->
|
||||
<Setter Property="Height" Value="Auto" />
|
||||
<Setter Property="Width" Value="200" />
|
||||
</Style>
|
||||
</d:DesignerProperties.DesignStyle>
|
||||
<Grid Height="Auto">
|
||||
<Grid.ColumnDefinitions>
|
||||
<!-- <ColumnDefinition Width="Auto" /> -->
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<!-- <Label Grid.Column="0" Content="{Binding SName}" VerticalAlignment="Center" HorizontalAlignment="Left"/> -->
|
||||
|
||||
<TextBox x:Name="tbValue" Text="{Binding RValue, Mode=TwoWay, StringFormat=N2}" Grid.Column="0" MaxLines="1" Width="125" HorizontalContentAlignment="Right" VerticalContentAlignment="Center" IsReadOnly="{Binding Readonly}" />
|
||||
<Label Grid.Column="1" Content="{Binding SUnit}" VerticalAlignment="Center" HorizontalAlignment="Left"/>
|
||||
|
||||
</Grid>
|
||||
</UserControl>
|
||||
@@ -0,0 +1,32 @@
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Input;
|
||||
|
||||
namespace HMIToolkit
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaktionslogik für AnalogValue.xaml
|
||||
/// </summary>
|
||||
public partial class AnalogValue : UserControl
|
||||
{
|
||||
public bool IsReadonly { get; set; }
|
||||
|
||||
public AnalogValue()
|
||||
{
|
||||
InitializeComponent();
|
||||
// Unloaded += OnUnloaded;
|
||||
}
|
||||
|
||||
private void OnUnloaded(object? sender, EventArgs e)
|
||||
{
|
||||
var disposable = DataContext as IDisposable;
|
||||
disposable?.Dispose();
|
||||
}
|
||||
|
||||
private void NumberValidation(object sender, TextCompositionEventArgs e)
|
||||
{
|
||||
Regex regex = new("^[-+]?[0-9]*,?[0-9]+$");
|
||||
e.Handled = regex.IsMatch(e.Text);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,144 @@
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using TwinCAT.TypeSystem;
|
||||
using Heisig.HMI.AdsManager;
|
||||
|
||||
namespace HMIToolkit;
|
||||
|
||||
public sealed class InRangeAttribute(string propMin, string propMax) : ValidationAttribute
|
||||
{
|
||||
public string PropMin { get; } = propMin;
|
||||
public string PropMax { get; } = propMax;
|
||||
|
||||
protected override ValidationResult? IsValid(object? value, ValidationContext validationContext)
|
||||
{
|
||||
object instance = validationContext.ObjectInstance;
|
||||
float minValue = (float)(instance.GetType().GetProperty(PropMin)?.GetValue(instance) ?? 0.0f);
|
||||
float maxValue = (float)(instance.GetType().GetProperty(PropMax)?.GetValue(instance) ?? 0.0f);
|
||||
float tempValue = (float)(value ?? 0.0f);
|
||||
|
||||
if (tempValue <= maxValue && tempValue >= minValue)
|
||||
return ValidationResult.Success;
|
||||
|
||||
return new($"Value has to be greater than {minValue} and smaller then {maxValue}");
|
||||
}
|
||||
}
|
||||
|
||||
public sealed partial class AnalogValueVM : ObservableValidator, IDisposable
|
||||
{
|
||||
[ObservableProperty]
|
||||
private string sName;
|
||||
|
||||
// 1 = Ok; 2 = Error
|
||||
[ObservableProperty]
|
||||
private short iStatus;
|
||||
|
||||
private float rValue;
|
||||
|
||||
[InRangeAttribute(nameof(RMin), nameof(RMax))]
|
||||
public float RValue
|
||||
{
|
||||
get => rValue;
|
||||
set
|
||||
{
|
||||
SetProperty(ref rValue, value, true);
|
||||
if (value >= RMin && value <= RMax)
|
||||
{
|
||||
if (!Readonly)
|
||||
WriteValue(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void WriteValue(float value)
|
||||
{
|
||||
_adsManager?.WriteValue(_variableName + ".rValue", value);
|
||||
}
|
||||
|
||||
[ObservableProperty]
|
||||
private string sUnit;
|
||||
|
||||
[ObservableProperty]
|
||||
private float rMin;
|
||||
|
||||
[ObservableProperty]
|
||||
private float rMax;
|
||||
|
||||
public bool Readonly { get; private set; }
|
||||
|
||||
private IAdsManager? _adsManager;
|
||||
|
||||
private readonly string? _variableName;
|
||||
|
||||
public AnalogValueVM()
|
||||
{
|
||||
sName = "No Name:";
|
||||
iStatus = 2;
|
||||
rValue = 0.0f;
|
||||
sUnit = "";
|
||||
Readonly = true;
|
||||
rMin = 0.0f;
|
||||
rMax = 100.0f;
|
||||
}
|
||||
|
||||
public AnalogValueVM(IAdsManager adsManager, string variableName, bool isReadonly) : this()
|
||||
{
|
||||
_adsManager = adsManager;
|
||||
_variableName = variableName;
|
||||
Readonly = isReadonly;
|
||||
|
||||
_adsManager.Register(_variableName + ".sName", NameChanged);
|
||||
_adsManager.Register(_variableName + ".iStatus", StatusChanged);
|
||||
//if (isReadonly)
|
||||
_adsManager.Register(_variableName + ".rValue", ValueChanged);
|
||||
_adsManager.Register(_variableName + ".sUnit", UnitChanged);
|
||||
_adsManager.Register(_variableName + ".rMin", MinChanged);
|
||||
_adsManager.Register(_variableName + ".rMax", MaxChanged);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_adsManager?.Deregister(_variableName + ".sName", NameChanged);
|
||||
_adsManager?.Deregister(_variableName + ".iStatus", StatusChanged);
|
||||
_adsManager?.Deregister(_variableName + ".rValue", ValueChanged);
|
||||
_adsManager?.Deregister(_variableName + ".sUnit", UnitChanged);
|
||||
_adsManager?.Deregister(_variableName + ".rMin", MinChanged);
|
||||
_adsManager?.Deregister(_variableName + ".rMax", MaxChanged);
|
||||
|
||||
_adsManager = null;
|
||||
}
|
||||
|
||||
private void NameChanged(object? sender, ValueChangedEventArgs e)
|
||||
{
|
||||
string temp = (string)e.Value;
|
||||
if (temp != String.Empty)
|
||||
SName = temp + ":";
|
||||
else
|
||||
SName = "";
|
||||
}
|
||||
|
||||
private void StatusChanged(object? sender, ValueChangedEventArgs e)
|
||||
{
|
||||
IStatus = (short)e.Value;
|
||||
}
|
||||
|
||||
private void ValueChanged(object? sender, ValueChangedEventArgs e)
|
||||
{
|
||||
RValue = (float)e.Value;
|
||||
}
|
||||
|
||||
private void UnitChanged(object? sender, ValueChangedEventArgs e)
|
||||
{
|
||||
SUnit = (string)e.Value;
|
||||
}
|
||||
|
||||
private void MinChanged(object? sender, ValueChangedEventArgs e)
|
||||
{
|
||||
RMin = (float)e.Value;
|
||||
}
|
||||
|
||||
private void MaxChanged(object? sender, ValueChangedEventArgs e)
|
||||
{
|
||||
RMax = (float)e.Value;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user