为什么在多绑定中转换值时会得到一个DependencyProperty.UnsetValue?

34

我有一个非常简单的IMultiValueConverter,只是将两个值进行OR运算。在下面的示例中,我想使用一个同样简单的布尔反转器来反转第一个值。

<MultiBinding Converter="{StaticResource multiBoolToVis}">
    <Binding Path="ConditionA" Converter="{StaticResource boolInverter}"/>
    <Binding Path="ConditionB"/>
</MultiBinding>

以及逆变器:

public class BoolInverterConverter : IValueConverter
{
    #region IValueConverter Members
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        if (value is bool)
        {
            return !((bool)value);
        }
        return null;
    }
    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
    #endregion
}

当我使用boolInverter时,MultiValueConverter中的第一个值变为“DependencyProperty.UnsetValue”。如果不使用转换器,则没有问题(当然,这并不是我想要的逻辑)。

我有什么遗漏吗?通过调试器逐步执行显示InverseBoolConverter正确地对我传递给它的值进行了反转,但该值没有被“发送”到MultiValueConverter。


请查看此链接:https://dev59.com/XHRB5IYBdhLWcg3wN1EQ - mkb
3个回答

40

来自MSDN:

UnsetValue是一个标志值,用于WPF属性系统无法确定请求的DependencyProperty值的情况。使用UnsetValue而不是null引用(Visual Basic中的Nothing),因为null引用可能是有效的属性值,也可能是有效的(并且经常使用的)DefaultValue。

这意味着以下之一:

  • 您使用模板(ControlTemplate或DataTemplate),并且在加载时未设置数据源。 因此,它将两次命中您的转换器,首先是UnsetValue,第二次是布尔值;所以不用担心;
  • 您的Binding不正确,意味着Binding无法确定值,从而导致UnsetValue。 您应该会看到警告..

此外,您不能像现在这样组合转换器。 所以可能就是这个问题。

请删除内部绑定中的转换器,然后问题就解决了! :)

希望这可以帮助到您!


1
我该如何检查转换器中的特定“值”是否具有DependencyProperty.UnsetValue依赖项属性?我的意思是,如果我想将该值强制转换为Int,则会抛出错误,例如(Int32)value - 因为该值是DependencyProperty.UnsetValue。有什么想法吗? - Rohit
3
找到了答案 :) .. 通过使用“is”可以进行检查。 - Rohit
今天我遇到了一个问题,当我创建控件模板时,忘记将“Background”的绑定设置为“TemplateBinding Background”。这会在设计时显示错误。 - Thai Anh Duc
1
@Rohit 我知道我晚了几年,但你可以直接将其与属性进行比较。if (value == DependencyProperty.UnsetValue) {// Do Stuff}这种方法有什么缺点吗? - Tyler StandishMan
也许你可以尝试转换为布尔类型:bool outTest; if (bool.TryParse(value.ToString(), out outTest) { var a = (bool) value; .... } 这样 DependencyProperty.UnsetValue 就不会被转换了。 - Fer R
显示剩余4条评论

5

除了其他答案之外,我通常会在Convert方法的开头添加以下这些行:

    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        if (values.Any(x => x == DependencyProperty.UnsetValue))
            return DependencyProperty.UnsetValue;

        ...

    }

为了确保没有任何一个值未设置(这通常发生在具有 CanUserAddRows="True"DataGrid 中)。

0

如果在数据网格中出现问题,请尝试将 CanUserAddRows="False"。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接