RaisePropertyChanged 会将单选按钮的值设置回原来的值。
RaisePropertyChanged 会将单选按钮的值设置回原来的值。
当我使用RaisePropertyChanged更新我的UI时,我遇到了一个奇怪的行为。我使用这篇帖子中的第二个解决方案(由Johnathan1提供):我实现了RadioBoolToIntConverter。我的VM如下所示:
public int myFilterRadioButtonInt { get { return _Filter.FilterMyProperty ? 1 : 2; } set { if (value == 1) _Filter.FilterMyProperty = true; else if (value == 2) _Filter.FilterMyProperty = false; else return; RaisePropertyChanged("myFilterRadioButtonInt"); } }
Converter如下所示(来自这篇帖子中的Jonathan1):
public class RadioBoolToIntConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { int integer = (int)value; if (integer==int.Parse(parameter.ToString())) return true; else return false; } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { return parameter; } }
为了理解,_Filter.FilterMyProperty
是模型的一个bool值,负责决定是否显示要过滤的值。这与两个使用RadioBoolToIntConverter绑定的RadioButton相关联:
显示 不显示
绑定和切换RadioButton都正常工作。问题是,如果我通过代码设置_Filter.FilterMyProperty = true
(设置一个应该被过滤的标准过滤器),然后执行RaisePropertyChanged("myFilterRadioButtonInt")
,_Filter.FilterMyProperty
将被设置为false
。
编辑:
通过调用VM中Filter属性的setter,RaisePropertyChanged("myFilterRadioButtonInt")
会再次调用myFilterRadioButtonInt
的setter,它会将RadioBox的当前值设置回去(在我的情况下,value
是2
,所以setter会将_Filter.FilterMyProperty
设置为false
)。使用这种方法无法通过代码更改RadioBox的值。我原以为只有在调用RaisePropertyChanged("myFilterRadioButtonInt")
时会调用getter。
我该如何解决这个问题,并且为什么RaisePropertyChanged("myFilterRadioButtonInt")
会调用setter?
编辑:
在ConvertBack()中返回参数是问题的原因。以下是我的解决方案:
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { bool val; if (!bool.TryParse(value.ToString(), out val)) return 0; int iParam; if (!int.TryParse(parameter.ToString(), out iParam)) return 0; return val ? iParam : 0; }
问题的原因是在ConvertBack方法中,返回的值是parameter参数,而不是正确的值。这导致在设置单选按钮的值时出现问题。
解决方法是根据value和parameter参数的值来确定返回的值。首先将value转换为Bool类型,将parameter转换为Int类型。如果parameter的值大于2或小于0,则返回false。如果vBool为true,则返回iParam的值。如果vBool为false,并且iParam的值为2,则返回1;否则返回2。
此外,在设置值时,如果当前值已经是正确的,则应立即返回,而不是调用RaisePropertyChanged方法。
解决问题的方法是删除返回parameter的代码,并根据上述逻辑返回正确的值。
整理成的文章如下:
在ConvertBack方法中,返回parameter参数的值是导致问题的原因。下面是出现问题的代码:
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { return parameter; }
为了解决这个问题,我们需要根据value和parameter的值来确定返回的值。首先,将value转换为Bool类型,将parameter转换为Int类型。如果parameter的值大于2或小于0,则返回false。如果vBool为true,则返回iParam的值。如果vBool为false,并且iParam的值为2,则返回1;否则返回2。下面是修改后的代码:
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { Bool vBool = Bool.Parse(value); Int iParam = IntParse(parameter); if(iParm > 2 || iParem < 0) return false; if(vBool) return iParam; else if (iParam == 2) return 1; else return 2; }
另外,在设置值时,如果当前值已经是正确的,则应立即返回,而不是调用RaisePropertyChanged方法。
以上是解决问题的方法,删除了返回parameter的代码,并根据上述逻辑返回正确的值。
问题出现的原因是在ViewModel中使用了RaisePropertyChanged来设置单选按钮的值,但是在某些情况下,这样设置的值无法正确地反映在界面上。
解决方法是修改ConvertBack方法的实现,将其改为以下代码:
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { return value.Equals(false) ? DependencyProperty.UnsetValue : parameter; }
这个解决方法在上述文章中提供,并且经过实际测试,可以解决单选按钮值无法正确反映的问题。感谢作者提供的解决方案,让我避免了因这个问题而烦恼的困扰。