在查看将enum
绑定到一组RadioButton
的解决方案时,我发现Sam的post来自一年半前。
Lars'答案正是我所寻找的:简单有效。
直到我开始更改绑定到RadioButton
组的对象。一个简单的版本如下。
XAML:
<Window x:Class="RadioEnum.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:re="clr-namespace:RadioEnum"
Height="200" Width="150">
<Window.DataContext>
<re:ViewModel />
</Window.DataContext>
<Window.Resources>
<re:EnumBooleanConverter x:Key="enumBooleanConverter" />
</Window.Resources>
<DockPanel>
<ComboBox DockPanel.Dock="Top" IsSynchronizedWithCurrentItem="True"
ItemsSource="{Binding Things}" DisplayMemberPath="Name" />
<GroupBox>
<StackPanel>
<RadioButton IsChecked="{Binding Path=Things/Choice, Converter={StaticResource enumBooleanConverter}, ConverterParameter=First}">First</RadioButton>
<RadioButton IsChecked="{Binding Path=Things/Choice, Converter={StaticResource enumBooleanConverter}, ConverterParameter=Second}">Second</RadioButton>
<RadioButton IsChecked="{Binding Path=Things/Choice, Converter={StaticResource enumBooleanConverter}, ConverterParameter=Third}">Third</RadioButton>
</StackPanel>
</GroupBox>
</DockPanel>
</Window>
现在,C#:
namespace RadioEnum
{
public class ViewModel {
public ObservableCollection<Thing> Things { get; set; }
public ViewModel() {
Things = new ObservableCollection<Thing> {
new Thing{ Name = "Thing1", Choice = Choice.First, },
new Thing{ Name = "Thing2", Choice = Choice.Second, },
};
}
}
public class Thing {
public string Name { get; set; }
public Choice Choice { get; set; }
}
public enum Choice { None, First, Second, Third, }
public class EnumBooleanConverter : IValueConverter {
// Yes, there are slight differences here from Lars' code, but that
// was to ease debugging. The original version has the same symptom.
public object Convert(object value, Type targetType, object parameter, CultureInfo culture) {
object ret = DependencyProperty.UnsetValue;
var parameterString = parameter as string;
if (parameterString != null && Enum.IsDefined(value.GetType(), value)) {
object parameterValue = Enum.Parse(value.GetType(), parameterString);
ret = parameterValue.Equals(value);
}
return ret;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) {
object ret = DependencyProperty.UnsetValue;
var parameterString = parameter as string;
if (parameterString != null && !value.Equals(false))
ret = Enum.Parse(targetType, parameterString);
return ret;
}
}
}
当应用程序使用ComboBox
中的 Thing1 加载时,会在广播组中选择正确的选择。从ComboBox
中选择 Thing2 会正确更新选择。但是,从这一点开始,切换不再更新绑定到 Second RadioButton
,因此不再调用Convert
方法,parameter
设置为“第二”。
换句话说,虽然 Thing2 的值没有改变,但是从那一点开始,所有RadioButton
都被清除了。但是, Thing1 继续有效。
没有看到错误 - “输出”窗口中既没有异常也没有消息。我试过以不同的方式绑定。我也试过选择一个DependencyProperty
(和Thing
然后是DependencyObject)。
有任何见解吗?
答案 0 :(得分:1)
原始回复: 不确定这是否能解决您的问题...因为我认为绑定的中断可能在您的组合框中...但是要改进您的EnumConverter并确保它正常工作......我建议看看在我对这个问题的回答中:
How to bind RadioButtons to an enum?
(不是选定的答案......但是我使用通用转换器的响应而不是转换字符串值)
修改: 我刚接过你的代码并试了一下,一切似乎都很棒! (使用visual studio 2010 .net 4)
你有一个物品清单(在你的组合框中),可以通过单选按钮设置当前选择的东西的选择。我可以修改每个Thing的选择,当我在Things之间切换时,它会正确地为我更新单选按钮!
如果我对所需的功能有误,请纠正我:
App Loads - ComboBox:Thing1 RadioButton:First
选择Thing2 - ComboBox:Thing2 RadioButton:Second
选择Thing1 - ComboBox:Thing1 RadioButton:First
选择第三个 - ComboBox:Thing1 RadioButton:第三个
选择Thing2 - ComboBox:Thing2 RadioButton:Second
选择First - ComboBox:Thing2 RadioButton:First
选择Thing1 - ComboBox:Thing1 RadioButton:Third
选择Thing2 - ComboBox:Thing2 RadioButton:First
以上是使用您提供的代码(以及修改后的EnumConverter)运行应用程序时获得的功能。这似乎也是理想的结果。以上是否正确,这对你不起作用吗?
编辑2:我可以确认问题出在.NET 3.5上
我运行.NET 4客户端配置文件...一切正常工作...运行.NET 3.5客户端配置文件...我得到你说的结果。
答案 1 :(得分:0)
对于那些可能在.NET 3.5中坚持这样做的人,我确实有一些工作。它不像上面的代码那么优雅,但它起作用。
我也很高兴看到其他人对替代方法的反馈。以下示例代码适用于在.NET 3.5和4中均可运行的 ThingB 。
首先,按如下方式更改RadioButtons
上的XAML(请注意,每个组的名称必须不同):
<RadioButton GroupName="One" IsChecked="{Binding Path=Things/ChoiceOne}">First</RadioButton>
<RadioButton GroupName="Two" IsChecked="{Binding Path=Things/ChoiceTwo}">Second</RadioButton>
<RadioButton GroupName="Three" IsChecked="{Binding Path=Things/ChoiceThree}">Third</RadioButton>
其次, ThingB 代码:
public class ThingB : INotifyPropertyChanged {
public string Name { get; set; }
public Choice Choice {
get {
return choiceOne ? Choice.First
: choiceTwo ? Choice.Second
: choiceThree ? Choice.Third : Choice.None;
}
set {
choiceOne = Choice.First.Equals(value);
choiceTwo = Choice.Second.Equals(value);
choiceThree = Choice.Third.Equals(value);
}
}
private bool choiceOne;
public bool ChoiceOne {
get { return choiceOne; }
set {
if(value) {
Choice = Choice.First;
NotifyChoiceChanged();
}
}
}
private bool choiceTwo;
public bool ChoiceTwo {
get { return choiceTwo; }
set {
if (value) {
Choice = Choice.Second;
NotifyChoiceChanged();
}
}
}
private bool choiceThree;
public bool ChoiceThree {
get { return choiceThree; }
set {
if (value) {
Choice = Choice.Third;
NotifyChoiceChanged();
}
}
}
private void NotifyChoiceChanged() {
OnPropertyChanged("ChoiceOne");
OnPropertyChanged("ChoiceTwo");
OnPropertyChanged("ChoiceThree");
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string property) {
if (PropertyChanged != null) {
PropertyChanged(this, new PropertyChangedEventArgs(property));
}
}
}