wpf

ToggleButtuons ItemsControl only one will be Checked at a time


I have this ItemsControl that every item is ToggleButton.

public List<string> MyList { get; set; } = new() {"A", "B", "C", "D"};

<ItemsControl ItemsSource="{Binding MyList}">
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <ToggleButton Content="{Binding}"/>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

How is it possible that only one item will be checked at a time?

I want to avoid this situation

enter image description here


Solution

  • Instead of an ItemsControl, you may use a ListBox with a ListBoxItem Style that declares the ToggleButton in its ControlTemplate.

    Bind the IsChecked property of the ToggleButton to the IsSelected property of the ListBoxItem. The default SelectionMode of a ListBox is Single, so only one item will ever be selected and hence checked.

    Be aware that you can not use a TemplateBinding because it is inherently one-way.

    <ListBox ItemsSource="{Binding MyList}">
        <ListBox.ItemContainerStyle>
            <Style TargetType="ListBoxItem">
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="ListBoxItem">
                            <ToggleButton
                                Content="{Binding}"
                                IsChecked="{Binding IsSelected,
                                    RelativeSource={RelativeSource TemplatedParent}}"/>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
        </ListBox.ItemContainerStyle>
    </ListBox>
    

    An alternative may be RadioButtons that share a GroupName. You would have to style them to look like ToggleButtons.

    <ItemsControl ItemsSource="{Binding MyList}">
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <RadioButton
                    Style="{StaticResource ResourceKey={x:Type ToggleButton}}"
                    Content="{Binding}"
                    GroupName="Buttons"/>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>