C#C
C#2y ago
10 replies
Nacho Man Randy Cabbage

WPF: Bind to each value of a property generated via reflection in ObservableCollection

I have a large list of objects, we'll call the object SpecialData, with ~60 properties on it. I created a class to represent each property in the UI like so (using MVVM toolkit hence the attributes):

public partial class CheckableProperty : ObservableObject
{
    public string DisplayName { get; set; } = string.Empty;
    public string PropertyName { get; set; } = string.Empty;

    [ObservableProperty]
    private bool _isSelected;

    [ObservableProperty]
    private string _propertyValue = string.Empty;
}


In my viewmodel, I get all the attributes of the SpecialData class and map them to a collection of CheckableProperty objects like so:

ObservableCollection AvailableProperties = new ObservableCollection<CheckableProperty>(
    typeof(SpecialData).GetProperties()
        .Select(prop => new CheckableProperty
        {
            DisplayName = ((DisplayNameAttribute?)prop.GetCustomAttributes(typeof(DisplayNameAttribute)).FirstOrDefault())?.DisplayName ?? prop.Name,
            PropertyName = prop.Name,
            IsSelected = true
        }));


Now in the UI, I want to show each property and its corresponding value for whatever my selected item is in the list of SpecialData objects. Right now I am doing this every time I select a different item to show the properties of:

private void UpdateSelectedProperties(SpecialData obj)
{
    AvailableProperties = new ObservableCollection<PropertySelection>(
        typeof(SpecialData).GetProperties()
            .Where(prop => prop.GetCustomAttribute<CsvIgnoreAttribute>() == null && prop.GetSetMethod() != null) // Check for ignore attribute and setter
            .Select(prop => new PropertySelection
            {
                DisplayName = ((DisplayNameAttribute?)prop.GetCustomAttributes(typeof(DisplayNameAttribute)).FirstOrDefault())?.DisplayName ?? prop.Name,
                Value = prop.GetValue(obj)?.ToString() ?? ""
            }));
}
Was this page helpful?