ToggleButton group: Ensuring one item is always selected in a ListBox
Asked Answered
B

3

6

I am trying to duplicate the left/center/right alignment toolbar buttons in Word. When you click the "Left Alignment" button the Center and Right buttons uncheck. I am using a WPF ListBox with ToggleButtons.

The problem is the user can click the Left Alignment button twice. The second click causes the button to uncheck and sets the underlying value to null. I'd like the second click to do nothing.

Ideas? Force the ListBox to always have one selected item? Prevent the null in the view model (need to refresh the ToggleButton binding)?

    <ListBox ItemsSource="{x:Static domain:FieldAlignment.All}" SelectedValue="{Binding Focused.FieldAlignment}">
      <ListBox.ItemTemplate>
        <DataTemplate>
          <ToggleButton IsChecked="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type ListBoxItem}},Path=IsSelected}">
            <TextBlock Text="{Binding Description}" />
          </ToggleButton>
        </DataTemplate>
      </ListBox.ItemTemplate>
    </ListBox>
Blinnie answered 28/7, 2010 at 18:50 Comment(0)
T
4

yeah, i would prefer the radiobutton too for this case, but if you want to use togglebutton then maybe you can bind the isenabled property to ischecked so it cannot be cliked when it's checked

Tortosa answered 29/7, 2010 at 6:53 Comment(2)
Thanks. In the OnClick event: if (toggleButton.IsChecked == false) toggleButton.IsChecked = true;Blinnie
err actually i was thinking more about like this <ToggleButton IsChecked="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type ListBoxItem}},Path=IsSelected}" IsEnabled="{Binding Converter={StaticResource boolConverter},RelativeSource={x:Static RelativeSource.Self},Path=IsChecked}"> <TextBlock Text="{Binding Description}" /> </ToggleButton>Tortosa
V
2

create custom control from ToggleButton, in *.xaml.cs file, declare and define control

    public class ToggleButton2 : ToggleButton
{
    public bool IsNotCheckable
    {
        get { return (bool)GetValue(IsNotCheckableProperty); }
        set { SetValue(IsNotCheckableProperty, value); }
    }

    // Using a DependencyProperty as the backing store for IsNotCheckable.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty IsNotCheckableProperty =
        DependencyProperty.Register("IsNotCheckable", typeof(bool), typeof(ToggleButton2), new FrameworkPropertyMetadata((object)false));

    protected override void OnToggle()
    {
        if(!IsNotCheckable)
        {
            base.OnToggle();
        }
    }
}

in *.xaml, replace ToggleButton with my:ToggleButton2, then you can bind IsNotCheckable to IsChecked, just like below,

              <my:ToggleButton2 IsChecked="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type ListBoxItem}},Path=IsSelected}"  IsNotCheckable="{Binding RelativeSource={RelativeSource Self}, Path=IsChecked, Mode=OneWay}">           
Vaduz answered 7/8, 2011 at 12:46 Comment(0)
S
1

Rather than implementing this as ToggleButtons, I would use RadioButtons with custom templates. It would probably save you a lot of headache.

Strongbox answered 28/7, 2010 at 19:38 Comment(1)
The RadioButton has other problems with data binding: geekswithblogs.net/claraoscura/archive/2008/10/17/125901.aspx. The ListBox lets you bind the possible choices rather than hard code.Blinnie

© 2022 - 2024 — McMap. All rights reserved.