views:

336

answers:

2

I am having problems getting a databound radiobutton listbox in WPF to respond to user input and reflect changes to the data it's bound to (i.e., to making changes in the code). The user input side works fine (i.e., I can select a radiobutton and the list behaves as expected). But every attempt to change the selection in code fails. Silently (i.e., no exception).

Here's the relevant section of the XAML (I think):

<Setter Property="ItemContainerStyle">
<Setter.Value>
    <Style TargetType="{x:Type ListBoxItem}" >
        <Setter Property="Margin" Value="2" />
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type ListBoxItem}">
                    <Border Name="theBorder" Background="Transparent">
                    <RadioButton Focusable="False" IsHitTestVisible="False" 
                        IsChecked="{Binding Path=IsSelected, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}" >
                        <ContentPresenter />
                    </RadioButton>
                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</Setter.Value>

I bind the listbox to a List of SchoolInfo objects. SchoolInfo contains a property called IsSelected:

    public bool IsSelected
    {
        get { return isSelected; }

        set
        {
            if( value != isSelected )
            {
                isSelected = value;
                this.OnPropertyChanged("IsSelected");
            }
        }
    }

The OnPropertyChanged() stuff was something I put in during my experimentation. It doesn't solve the problem.

Things like the following fail:

((SchoolInfo) lbxSchool.Items[1]).IsSelected = true;
lbxSchool.SelectedIndex = 1;

They fail silently -- no exception is thrown, but the UI doesn't show the item being selected.

  • Mark
A: 

I would enable NotifyOnSourceUpdated in your RadioButton binding. Even though you are allowing a two-way binding (which is the default), notifications won't be picked up from code-behind changes unless you are explicitly listening for them.

<RadioButton Focusable="False" IsHitTestVisible="False" 
                    IsChecked="{Binding Path=IsSelected, RelativeSource={RelativeSource TemplatedParent}, NotifyOnSourceUpdated=True}" >
Jeff Wain
+1  A: 

The RadioButton is binding to the ListBoxItem IsSelected property, not to your SchoolInfo IsSelected property.

(It is confusing because ListBoxItem has an "IsSelected" property, and so also does your SchoolInfo object, which is why there were no binding errors).

To fix, ListBoxItem.IsSelected needs to be bound to your SchoolInfo IsSelected property.

i.e. You need an extra setter for the ListBoxItem to bind to SchoolInfo.IsSelected, and then the list box item will work as it should, and also the RadioButton can bind correctly to ListBoxItem.IsSelected.

<Style TargetType="{x:Type ListBoxItem}" >
    <Setter Property="IsSelected" Value="{Binding Path=IsSelected}" />
Edward