-
Notifications
You must be signed in to change notification settings - Fork 807
Expand file tree
/
Copy pathCollectionPropertyVisibilityConverter.cs
More file actions
90 lines (74 loc) · 3.03 KB
/
CollectionPropertyVisibilityConverter.cs
File metadata and controls
90 lines (74 loc) · 3.03 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Globalization;
using System.Reflection;
using System.Windows;
using System.Windows.Data;
using NETworkManager.Interfaces.ViewModels;
namespace NETworkManager.Converters
{
/// <summary>
/// A generic converter that checks a property of items in a collection.
/// If ANY item's property is considered "present" (not null, not empty), it returns Visible.
/// </summary>
/// <typeparam name="T">The type of item in the collection.</typeparam>
public class CollectionPropertyVisibilityConverter<T> : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
// 1. Validate inputs
if (value is not IEnumerable<T> collection)
return Visibility.Collapsed;
if (parameter is not string propertyName || string.IsNullOrEmpty(propertyName))
return Visibility.Collapsed;
// 2. Get PropertyInfo via Reflection or cache.
if (!Cache.TryGetValue(propertyName, out var propertyInfo))
{
propertyInfo = typeof(T).GetProperty(propertyName);
Cache.TryAdd(propertyName, propertyInfo);
}
if (propertyInfo == null)
return Visibility.Collapsed;
// 3. Iterate collection and check property
foreach (var item in collection)
{
if (item == null) continue;
var propValue = propertyInfo.GetValue(item);
if (HasContent(propValue))
{
return Visibility.Visible;
}
}
return Visibility.Collapsed;
}
private static bool HasContent(object value)
{
if (value == null) return false;
// Handle Strings
if (value is string str)
return !string.IsNullOrWhiteSpace(str);
// Handle Collections (Lists, Arrays, etc.)
if (value is ICollection col)
return col.Count > 0;
// Handle Generic Enumerable (fallback)
if (value is IEnumerable enumValue)
{
var enumerator = enumValue.GetEnumerator();
var result = enumerator.MoveNext(); // Has at least one item
(enumerator as IDisposable)?.Dispose();
return result;
}
// Default: If it's an object and not null, it's "True"
return true;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
private ConcurrentDictionary<string, PropertyInfo> Cache { get; } = new();
}
// Concrete implementation for XAML usage
public class FirewallRuleViewModelVisibilityConverter : CollectionPropertyVisibilityConverter<IFirewallRuleViewModel>;
}