考虑以下简化的应用程序,它允许您在两个元素之间进行选择,每个元素都具有绑定到单选按钮的A和B布尔属性。我们的想法是你应该能够为每个元素独立设置A / B,如果你在元素之间切换,单选按钮应该反映该元素的标志。但事实并非如此。
视图模型:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Documents;
namespace SandboxWpf
{
public sealed class Element : INotifyPropertyChanged
{
private bool _memberA;
public bool MemberA
{
get { return _memberA; }
set
{
if (value != _memberA)
{
_memberA = value;
OnPropertyChanged();
}
}
}
private bool _memberB;
public bool MemberB
{
get { return _memberB; }
set
{
if (value != _memberB)
{
_memberB = value;
OnPropertyChanged();
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
}
public sealed class MainViewModel : INotifyPropertyChanged
{
private readonly List<Element> _elements;
public MainViewModel()
{
_elements = new List<Element>();
_elements.Add(new Element());
_elements.Add(new Element());
}
public IEnumerable<Element> Elements
{
get { return _elements; }
}
private Element _selectedElement;
public Element SelectedElement
{
get { return _selectedElement; }
set
{
if (value != _selectedElement)
{
_selectedElement = value;
OnPropertyChanged();
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
Window XAML(后面没有代码):
<Window x:Class="SandboxWpf.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:SandboxWpf="clr-namespace:SandboxWpf"
Title="MainWindow" Height="350" Width="525">
<Window.DataContext>
<SandboxWpf:MainViewModel/>
</Window.DataContext>
<StackPanel Orientation="Horizontal">
<ListBox ItemsSource="{Binding Elements}"
SelectedItem="{Binding SelectedElement, Mode=TwoWay}" />
<ContentPresenter Content="{Binding SelectedElement}">
<ContentPresenter.Resources>
<DataTemplate DataType="{x:Type SandboxWpf:Element}">
<StackPanel Orientation="Horizontal">
<RadioButton Content="A" IsChecked="{Binding MemberA, Mode=TwoWay}"/>
<RadioButton Content="B" IsChecked="{Binding MemberB, Mode=TwoWay}"/>
</StackPanel>
</DataTemplate>
</ContentPresenter.Resources>
</ContentPresenter>
</StackPanel>
</Window>
您可以使用每个元素上的单选按钮切换A和B值。但是,如果将第一个元素和第二个元素设置为不同的值(一个A和一个B),则返回另一个选定元素,另一个元素现在将A和B都设置为false。当ContentEresenter上的SelectedElement属性发生变化时会发生某些事情,我认为它会以某种方式触发TwoWay绑定,导致它覆盖属性值,但我无法弄清楚为什么会发生这种情况或如何解决它。这是我在更大的应用程序中看到的故意简化版本。
知道这里发生了什么吗?
答案 0 :(得分:2)
因为它们属于同一个组,请参阅GroupName Property,您可以为每个元素设置单独的GroupName(每个元素都有不同的组)。
<DataTemplate DataType="{x:Type SandboxWpf:Element}">
<StackPanel Orientation="Horizontal">
<RadioButton GroupName="{Binding ElementGroupName}" Content="A" IsChecked="{Binding MemberA, Mode=TwoWay}"/>
<RadioButton GroupName="{Binding ElementGroupName}" Content="B" IsChecked="{Binding MemberB, Mode=TwoWay}"/>
</StackPanel>
</DataTemplate>