Files
XplorePlane/XplorePlane/ViewModels/ImageProcessing/ProcessorParameterVM.cs
T
2026-04-20 11:13:40 +08:00

208 lines
6.7 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using Prism.Mvvm;
using System;
using System.Globalization;
using System.Linq;
using XP.ImageProcessing.Core;
namespace XplorePlane.ViewModels
{
public class ProcessorParameterVM : BindableBase
{
private object _value;
private bool _isValueValid = true;
public ProcessorParameterVM(ProcessorParameter parameter)
{
Name = parameter.Name;
DisplayName = parameter.DisplayName;
_value = parameter.Value;
MinValue = parameter.MinValue;
MaxValue = parameter.MaxValue;
Options = parameter.Options;
ParameterType = parameter.ValueType?.Name?.ToLowerInvariant() switch
{
"int32" or "int" => "int",
"double" => "double",
"boolean" or "bool" => "bool",
_ => "enum"
};
ValidateValue(_value);
}
public string Name { get; }
public string DisplayName { get; }
public object MinValue { get; }
public object MaxValue { get; }
public string[]? Options { get; }
public string ParameterType { get; }
public bool IsValueValid
{
get => _isValueValid;
private set => SetProperty(ref _isValueValid, value);
}
public object Value
{
get => _value;
set
{
var normalizedValue = NormalizeValue(value);
if (SetProperty(ref _value, normalizedValue))
ValidateValue(normalizedValue);
}
}
private void ValidateValue(object value)
{
if (value == null)
{
IsValueValid = false;
return;
}
if (ParameterType == "int")
{
IsValueValid = TryConvertToInt(value, out var intValue) && IsWithinRange(intValue);
return;
}
if (ParameterType == "double")
{
IsValueValid = TryConvertToDouble(value, out var doubleValue) && IsWithinRange(doubleValue);
return;
}
if (ParameterType == "bool")
{
IsValueValid = TryConvertToBool(value, out _);
return;
}
if (Options is { Length: > 0 })
{
var stringValue = Convert.ToString(value, CultureInfo.InvariantCulture) ?? string.Empty;
IsValueValid = Options.Contains(stringValue, StringComparer.OrdinalIgnoreCase);
return;
}
IsValueValid = true;
}
private object NormalizeValue(object value)
{
if (value == null)
return value;
if (ParameterType == "int" && TryConvertToInt(value, out var intValue))
return intValue;
if (ParameterType == "double" && TryConvertToDouble(value, out var doubleValue))
return doubleValue;
if (ParameterType == "bool" && TryConvertToBool(value, out var boolValue))
return boolValue;
return value;
}
private bool IsWithinRange(double value)
{
if (MinValue != null && TryConvertToDouble(MinValue, out var minValue) && value < minValue)
return false;
if (MaxValue != null && TryConvertToDouble(MaxValue, out var maxValue) && value > maxValue)
return false;
return true;
}
private static string NormalizeNumericText(string value)
{
return value.Trim().TrimEnd('、', '', ',', '。', '.', ';', '', ':', '');
}
private static bool TryConvertToInt(object value, out int result)
{
switch (value)
{
case int intValue:
result = intValue;
return true;
case string stringValue:
stringValue = NormalizeNumericText(stringValue);
return int.TryParse(stringValue, NumberStyles.Integer, CultureInfo.InvariantCulture, out result)
|| int.TryParse(stringValue, NumberStyles.Integer, CultureInfo.CurrentCulture, out result);
default:
try
{
result = Convert.ToInt32(value, CultureInfo.InvariantCulture);
return true;
}
catch
{
result = default;
return false;
}
}
}
private static bool TryConvertToDouble(object value, out double result)
{
switch (value)
{
case double doubleValue:
result = doubleValue;
return true;
case float floatValue:
result = floatValue;
return true;
case int intValue:
result = intValue;
return true;
case long longValue:
result = longValue;
return true;
case string stringValue:
stringValue = NormalizeNumericText(stringValue);
return double.TryParse(stringValue, NumberStyles.Float | NumberStyles.AllowThousands, CultureInfo.InvariantCulture, out result)
|| double.TryParse(stringValue, NumberStyles.Float | NumberStyles.AllowThousands, CultureInfo.CurrentCulture, out result);
default:
try
{
result = Convert.ToDouble(value, CultureInfo.InvariantCulture);
return true;
}
catch
{
result = default;
return false;
}
}
}
private static bool TryConvertToBool(object value, out bool result)
{
switch (value)
{
case bool boolValue:
result = boolValue;
return true;
case string stringValue:
return bool.TryParse(stringValue.Trim(), out result);
default:
try
{
result = Convert.ToBoolean(value, CultureInfo.InvariantCulture);
return true;
}
catch
{
result = default;
return false;
}
}
}
}
}