Knuhl
Knuhl

Reputation: 1

TwoWay-Binding of RadioButtons in a Template bugged if a Button is in the Parent Panel

My Problem is similar to the one described in here, but goes one step further.

Inside a StackPanel are a ListBox to select between Elements, and a ContentPresenter rendering two RadioButtons. These RadioButtons are bound to the Boolean Properties MemberA and MemberB of the selected Element and are defined inside the ContentTemplate of the ContentPresenter. The GroupName of the RadioButtons are also bound to the GroupName-Property of the Element.

XAML:

<Window x:Class="WpfRadioButtonBugTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:WpfRadioButtonBugTest"
        Title="MainWindow" Height="450" Width="800">
    <Window.DataContext>
        <local:TestViewModel />
    </Window.DataContext>

    <StackPanel Orientation="Vertical">
        <ListBox ItemsSource="{Binding Path=Elements, Mode=OneWay}"
                 SelectedItem="{Binding Path=SelectedElement, Mode=TwoWay}">
            <ListBox.ItemTemplate>
                <DataTemplate DataType="{x:Type local:Element}">
                    <TextBlock Text="{Binding Path=GroupName, Mode=OneWay}" />
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>

        <ContentPresenter Content="{Binding Path=SelectedElement, Mode=OneWay}">
            <ContentPresenter.ContentTemplate>
                <DataTemplate DataType="{x:Type local:Element}">
                    <StackPanel Orientation="Vertical">

                        <RadioButton GroupName="{Binding Path=GroupName, Mode=OneWay}"
                                     IsChecked="{Binding Path=MemberA, Mode=TwoWay}"
                                     Content="MemberA" />
                        <RadioButton GroupName="{Binding Path=GroupName, Mode=OneWay}"
                                     IsChecked="{Binding Path=MemberB, Mode=TwoWay}"
                                     Content="MemberB" />

                    </StackPanel>
                </DataTemplate>
            </ContentPresenter.ContentTemplate>
        </ContentPresenter>
    </StackPanel>
</Window>

ViewModel:

public class TestViewModel : PropertyChangedBase
{
    public ObservableCollection<Element> Elements { get; }
        = new ObservableCollection<Element>(Enumerable.Range(0, 2).Select(x => new Element(x + 1)));

    private Element _selectedElement;
    public Element SelectedElement
    {
        get => _selectedElement ?? (_selectedElement = Elements.First());
        set
        {
            _selectedElement = value;
            OnPropertyChanged();
        }
    }
}

public class Element : PropertyChangedBase
{
    private bool _memberA = true;
    public bool MemberA
    {
        get => _memberA;
        set
        {
            _memberA = value;
            OnPropertyChanged();
        }
    }

    private bool _memberB;
    public bool MemberB
    {
        get => _memberB;
        set
        {
            _memberB = value;
            OnPropertyChanged();
        }
    }

    public string GroupName { get; }

    public Element(int i) => GroupName = i.ToString();
}

public class PropertyChangedBase : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
        => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}

If you press the RadioButton for MemberB of the First Element and switch back and forth between the Elements, the RadioButtons always represent the correct values.

Here comes the fun part: Add a Button to the top of the StackPanel:

...
<StackPanel Orientation="Vertical">
    <Button />

    <ListBox ItemsSource="{Binding Path=Elements, Mode=OneWay}"
...

This leads to unexpected behavior: Selecting MemberB of Element 1, then Selecting Element 2, then Selecting Element 1 again results in no RadioButtons being selected. Setting a Breakpoint on the Setter of MemberB shows that it is set to false as soon as the other Element is selected in the ListBox.

The problem is not present without the Button, or without the RadioButtons being in a Template. Is there any Reason why an additional Button in a Parent Panel should change the behavior of RadioButtons in a Template?

EDIT: Minimal Application to reproduce uploaded here

Upvotes: 0

Views: 37

Answers (0)

Related Questions