Question

I have two enums:

public enum MyEnumA
{
    OptionA1 = 1,
    OptionA2 = 2,
    OptionA3 = 3,
}

public enum MyEnumB
{
    OptionB1 = 1,
    OptionB2 = 2,
    OptionB3 = 3,
}

and a class containing both enums

public class AB
{
    public MyEnumA A { get; set; }
    public MyEnumB B { get; set; }
}

I want to have a matrix of checkboxes of both enums. The data is read from and saved to a List. This list is the actual junction table. For the time being I filled the list by hand:

    private List<AB> ABList = new List<AB>();

    ABList.Add(new AB { A = MyEnumA.OptionA2, B = MyEnumB.OptionB1 });
    ABList.Add(new AB { A = MyEnumA.OptionA3, B = MyEnumB.OptionB3 });

The matrix now should look like this:

            OptionA1 OptionA2 OptionA3
OptionB1                 X
OptionB2
OptionB3                          X

I have found a WinForm solution where everything is done in code-behind: http://social.msdn.microsoft.com/Forums/eu/winformsdatacontrols/thread/33fae605-902a-40e3-9bbb-60b77fc33b9b But can't it be done in xaml with data binding?

Was it helpful?

Solution 2

Thanks for your solution, Grafix. It is very nice. I thought it would be neater to place it in a Converter, so I did it like this:

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        var abList = value as List<AB>;

        if (abList == null)
            return null;

        var retVal = Enum.GetValues(typeof (MyEnumB)).Cast<MyEnumB>().Select(
                b =>
                new ABViewModel()
                    {
                        Name = b,
                        OptionA1 = abList.Any(ab => ab.B == b && ab.A == MyEnumA.OptionA1),
                        OptionA2 = abList.Any(ab => ab.B == b && ab.A == MyEnumA.OptionA2),
                        OptionA3 = abList.Any(ab => ab.B == b && ab.A == MyEnumA.OptionA3)
                    }).ToList();
        return retVal;
    }

And the DataGrid:

    <DataGrid Height="215" HorizontalAlignment="Left" Margin="91,12,0,0" Name="dataGrid1" 
            VerticalAlignment="Top" Width="299" 
            ItemsSource="{Binding ABList, Converter={StaticResource listToDataTableConverter}}"
            d:DataContext="{d:DesignData }" />

And I set the DataContext like this:

    public MainWindow()
    {
        InitializeComponent();

        ABList.Add(new AB { A = MyEnumA.OptionA2, B = MyEnumB.OptionB1 });
        ABList.Add(new AB { A = MyEnumA.OptionA3, B = MyEnumB.OptionB3 });

        DataContext = this;
    }

OTHER TIPS

If you want to use a WPF DataGrid with databinding, I see no other way than to transform the the data.

        public MainWindow()
    {
        InitializeComponent();

        DataContext = Enum.GetValues(typeof(MyEnumB)).Cast<MyEnumB>().Select(b => new ABViewModel() { Name = b.ToString(), A1 = ABList.Any(ab => ab.B == b && ab.A == MyEnumA.OptionA1), A2 = ABList.Any(ab => ab.B == b && ab.A == MyEnumA.OptionA2), A3 = ABList.Any(ab => ab.B == b && ab.A == MyEnumA.OptionA3) }).ToList();
    }


public class ABViewModel
{
    public string Name { get; set; }
    public bool A1 { get; set; }
    public bool A2 { get; set; }
    public bool A3 { get; set; }
}

The Xaml is straight forward now:

<DataGrid ItemsSource="{Binding}" IsReadOnly="True"/>
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top