RaisePropertyChanged 会将单选按钮的值设置回原来的值。

6 浏览
0 Comments

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的当前值设置回去(在我的情况下,value2,所以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;
}

0
0 Comments

问题的原因是在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的代码,并根据上述逻辑返回正确的值。

0
0 Comments

问题出现的原因是在ViewModel中使用了RaisePropertyChanged来设置单选按钮的值,但是在某些情况下,这样设置的值无法正确地反映在界面上。

解决方法是修改ConvertBack方法的实现,将其改为以下代码:

public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
    return value.Equals(false) ? DependencyProperty.UnsetValue : parameter;
}

这个解决方法在上述文章中提供,并且经过实际测试,可以解决单选按钮值无法正确反映的问题。感谢作者提供的解决方案,让我避免了因这个问题而烦恼的困扰。

0