| @av.AttributeName |
- @av.Value |
+ @ValueFormatter.FormatDisplayValue(av.Value) |
@av.Quality
|
diff --git a/src/ScadaLink.Commons/Types/ValueFormatter.cs b/src/ScadaLink.Commons/Types/ValueFormatter.cs
new file mode 100644
index 0000000..58258b4
--- /dev/null
+++ b/src/ScadaLink.Commons/Types/ValueFormatter.cs
@@ -0,0 +1,59 @@
+using System.Collections;
+using System.Reflection;
+
+namespace ScadaLink.Commons.Types;
+
+///
+/// Formats attribute values for display. Handles scalar types directly
+/// and uses reflection to extract array contents from complex types
+/// (e.g., LmxProxy ArrayValue) rather than showing the type name.
+///
+public static class ValueFormatter
+{
+ ///
+ /// Formats a value for display as a string. Returns the value's natural
+ /// string representation for scalars, and comma-separated elements for
+ /// array/collection types.
+ ///
+ public static string FormatDisplayValue(object? value)
+ {
+ if (value is null) return "";
+ if (value is string s) return s;
+ if (value is IFormattable) return value.ToString() ?? "";
+
+ // Check if it's an array-like container with typed sub-collections
+ // (e.g., LmxProxy ArrayValue with BoolValues, Int32Values, etc.)
+ var type = value.GetType();
+ if (type.Namespace?.Contains("LmxProxy") == true || type.Name == "ArrayValue")
+ {
+ return FormatArrayContainer(value, type);
+ }
+
+ // Fallback for IEnumerable (generic collections, arrays)
+ if (value is IEnumerable enumerable)
+ {
+ return string.Join(",", enumerable.Cast