0

Because I need to display a huge amount of bit information in the UI, so I'm trying to have a data structure that can expose an array of different properties based on individual bits (32bit for each int). What I come up with is a bit clumsy and doesn't work in binding. So I'm wondering is there a better way to achieve the goal.

What I have at the moment: I declare several different interfaces each with a [] operator property.

public interface IProperty1
{
    string this[int index] { get; }
}

The main class not only implements this interface, but expose a property based on this interface and implement each interface thus the index operator explicitly.

public class BitData: IProperty1, IProperty2, IProperty3
{
    public IProperty1 Property1 => this;
    public IProperty2 Property2 => this;
    public IProperty3 Property3 => this;
  
    string IPropert1.this[int index]
    {
        get { //logic here; }
    }
}

In unit test, if I have an BitData object, I can access individual properties for individual bits using syntax such as data.Property1[0] like Assert.AreEqual(xxxxx, data.Property1[i]).

However, when I use the object as a data context and "Property[0]" as binding path, WPF complains about "[] property not found on object of type BitData".

<DataTemplate DataType="{x:Type BitData }">
    <TextBlock Text="{Binding Path=Property1[0]}" Foreground="{Binding Path=Property2[0]}" Background="{Binding Path=Property3[0]}"/>
</DataTemplate>

1 Answers1

0

In my UI I also have an integer value representing a number of relays that are either on or off.

In binding, I just use the integer value with this IConverter

/// <summary>
/// returns true, if the bit designated by bitNumber (starting at 0 from the right) is set
/// </summary>
public class BitMaskToBooleanConverter : IValueConverter
{
    #region Implementation of IValueConverter
    public object Convert(object bittedValue, Type voidTargedType, object bitNumber, CultureInfo voidCulture)
    {
        if (bittedValue == null)
            return false;
        if (bitNumber == null)
            return false;

        var nValue = System.Convert.ToInt64(bittedValue);
        var nBit = System.Convert.ToByte(bitNumber);

        var maskedValue = nValue & (1 << nBit);

        return maskedValue != 0;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }

    #endregion
}

The use in Xaml looks like this

...
<UserControl.Resources>
    <ResourceDictionary>
        ...
        <converters:BitMaskToBooleanConverter x:Key="BitMaskToBooleanConverter" 
        ...
    <ResourceDictionary>
</UserControl.Resources>
...
<CheckBox "Relay 1" IsChecked="{Binding RelayInteger, ConverterParameter=0, Converter={StaticResource BitMaskToBooleanConverter}, UpdateSourceTrigger=PropertyChanged}" IsEnabled="False" /
ThomasB
  • 161
  • 6