我的问题与此处描述的问题类似,但更进一步。
在 StackPanel 内有一个用于在 Elements 之间进行选择的 ListBox,以及一个呈现两个 RadioButtons 的 ContentPresenter。这些单选按钮绑定到选定元素的布尔属性 MemberA 和 MemberB,并在 ContentPresenter 的 ContentTemplate 中定义。RadioButtons 的 GroupName 也绑定到 Element 的 GroupName-Property。
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>
视图模型:
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));
}
如果您按下第一个元素的 MemberB 的 RadioButton 并在元素之间来回切换,那么 RadioButtons 始终代表正确的值。
有趣的部分来了:在 StackPanel 的顶部添加一个按钮:
...
<StackPanel Orientation="Vertical">
<Button />
<ListBox ItemsSource="{Binding Path=Elements, Mode=OneWay}"
...
这会导致意外行为:选择元素 1 的 MemberB,然后选择元素 2,然后再次选择元素 1 会导致未选择任何单选按钮。在 MemberB 的 Setter 上设置断点表明,只要在 ListBox 中选择了另一个 Element,它就会设置为 false。
如果没有 Button,或者没有 RadioButtons 在模板中,问题就不存在。为什么父面板中的附加按钮应该改变模板中单选按钮的行为有什么原因吗?
编辑:复制上传的最小应用程序