---编辑包含完整的代码示例---
我知道.NET 3.5 RadioButton存在很多问题,但我相信这是一个不同的问题,我在搜索中没有找到任何东西。我已经整理了一个非常小的代码示例来演示我正在观察的问题。
我的XAML中有一个ListView,它的SelectedItem绑定到我的ViewModel中的SelectedModel。这个相同的XAML包含一个StackPanel,它在浏览ListView中的项目时显示SelectedModel的RadioButton选项。一切都很好,直到我将一个RadioButton组添加到混合中。现在,如果我在ListView中选择了一个已选中其中一个RadioButton选项的记录,那么在ListView中选择另一个选中了不同选项的记录,现在再次选择ListView中的上一条记录,所有的RadioButtons都是ListView项目将被取消选中。如果我在ListView中上下移动足够长的时间,则每个RadioButton和基础布尔值都将设置为false。
型号代码:
public class Model
{
public string Name { get; set; }
public bool IsOne { get; set; }
public bool IsTwo { get; set; }
public bool IsThree { get; set; }
}
ViewModel代码:
public class ViewModel: INotifyPropertyChanged
{
private Model _selectedModel;
public event PropertyChangedEventHandler PropertyChanged;
public List<Model> ModelList { get; set; }
public Model SelectedModel
{
get { return _selectedModel; }
set
{
_selectedModel = value;
OnPropertyChanged("SelectedModel");
}
}
public ViewModel()
{
ModelList = new List<Model>();
ModelList.Add(new Model() {Name = "Florida"});
ModelList.Add(new Model() {Name = "Texas"});
ModelList.Add(new Model() {Name = "Arizona"});
ModelList.Add(new Model() {Name = "Washington"});
}
void OnPropertyChanged(string propName)
{
if (this.PropertyChanged != null)
this.PropertyChanged(
this, new PropertyChangedEventArgs(propName));
}
}
最后,XAML代码:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100"/>
<ColumnDefinition />
</Grid.ColumnDefinitions>
<ListView ItemsSource="{Binding Path=ModelList}"
SelectedItem = "{Binding SelectedModel}"
DisplayMemberPath="Model">
<ListView.View>
<GridView>
<GridViewColumn Header="Name"
DisplayMemberBinding="{Binding Name}"
Width="100"/>
</GridView>
</ListView.View>
</ListView>
<StackPanel Grid.Column="1">
<RadioButton x:Name="IsOne" Content="One" Margin="3"
IsChecked="{Binding Path=SelectedModel.IsOne}"
GroupName="{Binding Path=SelectedModel.Name}"/>
<RadioButton x:Name="IsTwo" Content="Two" Margin="3"
IsChecked="{Binding Path=SelectedModel.IsTwo}"
GroupName="{Binding Path=SelectedModel.Name}" />
<RadioButton x:Name="IsThree" Content="Three" Margin="3"
IsChecked="{Binding Path=SelectedModel.IsThree}"
GroupName="{Binding Path=SelectedModel.Name}" />
</StackPanel>
</Grid>
关于什么会导致绑定以这种方式表现的想法?
谢谢,
格伦
答案 0 :(得分:1)
如果RadioButton
的每一行都有ListView
个{},则需要为每个GroupName
中的RadioButton
提供唯一GridView
个行。我知道如何执行此操作的唯一方法是向Bind
中显示的数据类型类添加额外属性。只要集合中的每个项具有不同的值,那么该值是什么并不重要。
然后,您可以GroupName
将新项目属性设置为集合中每个RadioButton
的{{1}}属性:
<StackPanel>
<RadioButton Content="Demo" GroupName="{Binding GroupName}" ... />
<RadioButton Content="Screener" GroupName="{Binding GroupName}" ... />
<RadioButton Content="Vote" GroupName="{Binding GroupName}" ... />
<RadioButton Content="Vote Follow Up" GroupName="{Binding GroupName}" ... />
<RadioButton Content="Named Vote" GroupName="{Binding GroupName}" ... />
</StackPanel>
我发现了一篇很好地展示XAML示例的文章:
Grouped RadioButton for WPF Datagrid
更新&gt;&gt;&gt;
是的,在您的情况下,当您在某种容器面板中有一组RadioButton
时,您甚至不需要提供GroupName
,因为框架会为我们提供Binding
'掩护下'。我重构了你的XAML以使用不同的<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100"/>
<ColumnDefinition />
</Grid.ColumnDefinitions>
<ListView ItemsSource="{Binding ModelList}" IsSynchronizedWithCurrentItem="True" SelectedItem="{Binding SelectedModel}" DisplayMemberPath="Model">
<ListView.View>
<GridView>
<GridViewColumn Header="Name" DisplayMemberBinding="{Binding Name}" Width="100"/>
</GridView>
</ListView.View>
</ListView>
<StackPanel Grid.Column="1">
<RadioButton x:Name="IsOne" Content="One" Margin="3" IsChecked="{Binding ModelList/IsOne}" />
<RadioButton x:Name="IsTwo" Content="Two" Margin="3" IsChecked="{Binding ModelList/IsTwo}" />
<RadioButton x:Name="IsThree" Content="Three" Margin="3" IsChecked="{Binding ModelList/IsThree}" />
</StackPanel>
</Grid>
来查看是否有任何区别,但事实并非如此。你在那里发现了一个骨头怪物。这是我结束的XAML仍然表现出同样的问题:
CheckBox
我在您的问题中删除了代码示例中未使用的属性。我还建议您使用更准确的问题描述编辑您的问题...虽然我没有完全解决取消选中RadioButton
所需的点击模式,但我可以看到它与第三个{{1}}无关。它当然也发生在其他两个上。
可能值得将此报告为Microsoft Connect website上的错误...也许已经有解释或解决方法了吗?
答案 1 :(得分:1)
我已经确认这是一个已经存在的问题,一直持续到Framework 4.5。 Franklin Chen为我提供了一个很好的小解决方案,扩展了RadioButton类。
以下是指向answer的链接。
这是他的代码。现在只需绑定到IsCheckedReal属性,一切正常。
public class RadioButtonExtended : RadioButton
{
static bool m_bIsChanging = false;
public RadioButtonExtended()
{
this.Checked += new RoutedEventHandler(RadioButtonExtended_Checked);
this.Unchecked += new RoutedEventHandler(RadioButtonExtended_Unchecked);
}
void RadioButtonExtended_Unchecked(object sender, RoutedEventArgs e)
{
if (!m_bIsChanging)
this.IsCheckedReal = false;
}
void RadioButtonExtended_Checked(object sender, RoutedEventArgs e)
{
if (!m_bIsChanging)
this.IsCheckedReal = true;
}
public bool? IsCheckedReal
{
get { return (bool?)GetValue(IsCheckedRealProperty); }
set
{
SetValue(IsCheckedRealProperty, value);
}
}
// Using a DependencyProperty as the backing store for IsCheckedReal. This enables animation, styling, binding, etc...
public static readonly DependencyProperty IsCheckedRealProperty =
DependencyProperty.Register("IsCheckedReal", typeof(bool?), typeof(RadioButtonExtended),
new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.Journal |
FrameworkPropertyMetadataOptions.BindsTwoWayByDefault,
IsCheckedRealChanged));
public static void IsCheckedRealChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
m_bIsChanging = true;
((RadioButtonExtended)d).IsChecked = (bool)e.NewValue;
m_bIsChanging = false;
}
}