0

I want to create a row of ToggleButtons for Enum values. The buttons must show current value of a property of MyEnumType (by their state) and change the property's value when pressed.

I've found a solution for binding a bunch of separate CheckBoxes to their corresponding enum values (one for each) here, but I'm trying to create the ToggleButtons by ItemsControl (from the Enum type's values) so I wont have to remember to add a ToggleButton every time I add another value to my enum type (and also for shorter XAML code that creates the buttons). The problem is that I can't bind a ConverterParameter. Is there a clean and proper way to do this? Or am I doing everything wrong?

Here is my code now:

<ItemsControl ItemsSource="{Binding Source={local:EnumValues {x:Type local:MyEnumType}}}">
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <StackPanel Orientation="Horizontal"/>
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <ToggleButton Content="{Binding Converter={StaticResource MyEnumToNiceStringConverter}}" 
                IsChecked="{Binding Source=mySourceObject, Path=SelectedMyEnumValue, Converter={StaticResource EnumBooleanConverter}, ConverterParameter={Binding}}">
            </ToggleButton>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

The local:EnumValues is a MarkupExtension that returns a list of values from given Enum type. The EnumBooleanConverter is a value converter from the above link that returns true if the bound enum value is equal to its ConverterParameter and supports ConvertBack from bool to enum value. SelectedMyEnumValue is the property that the buttons are to reflect and modify.

This is a repeating problem for me (that some property cannot be bound) so if you are about to give me a totally different approach for the ToggleButtons, please also write how to work around the problem of such binding. It doesn't have to be bound forever, I just need to set the value once (without a bunch of Style-and-Triggers kind of code in XAML). Maybe another Markup Extension can do this?

Thanks!

Community
  • 1
  • 1
P.W.
  • 657
  • 8
  • 15
  • PS: I've also tried a MultiBinding that was comparing the binding value with the property value and it almost worked. The correct button was down at first, but when you clicked on another button, the previous one was not going up (even though the MultiBinding was getting values from every button to compare and was returning false - I've checked that out by a breakpoint). Maybe you know why? – P.W. Oct 23 '14 at 21:48

1 Answers1

1

I have found out that my question is a duplicate of this one (I got confused by its title and missed it). Sorry for this. I'm attaching a solution for my specific case based on answers from that post (using ListBox instead of ItemsControl and binding IsChecked to IsSelected). The main trick here is the style for hiding the selected item's blue background.

<ListBox ItemsSource="{Binding Source={local:EnumValues {x:Type local:MyEnumType}}}"
         SelectedItem="{Binding Source=mySourceObject, Path=SelectedMyEnumValue}">
    <ListBox.ItemsPanel>
        <ItemsPanelTemplate>
            <StackPanel Orientation="Horizontal"/>
        </ItemsPanelTemplate>
    </ListBox.ItemsPanel>
    <ListBox.Resources>
        <Style TargetType="{x:Type ListBoxItem}">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type ListBoxItem}">
                        <ContentPresenter />
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </ListBox.Resources>
    <ListBox.ItemTemplate>
        <DataTemplate>
            <ToggleButton Content="{Binding Converter={StaticResource MyEnumToNiceStringConverter}}" 
                IsChecked="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ListBoxItem}, Path=IsSelected}">
            </ToggleButton>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

Anyway, this only solves one of my 2 questions, so if you know how to make binding of such properties as the ConverterParameter possible, please leave an answer. Thanks.

Community
  • 1
  • 1
P.W.
  • 657
  • 8
  • 15