内联MultiBinding无法按预期工作

时间:2016-05-05 18:27:49

标签: c# .net wpf

我使用this post作为参考创建了内联MultiBinding。更具体地说,我正在使用Christian Myksvoll的答案来创建自定义绑定。我的班级看起来像这样:

   public class MultiBinder : MultiBinding
   {

      public MultiBinder(BindingBase[] bindings, object converter)
      {
         foreach (BindingBase b in bindings)
         {
            Bindings.Add(b);
         }

         Converter = converter as IMultiValueConverter;
      }

      public MultiBinder(BindingBase b1, BindingBase b2, object converter)
      {
         Bindings.Add(b1);
         Bindings.Add(b2);

         Converter = converter as IMultiValueConverter;
      }

      public MultiBinder(BindingBase b1, BindingBase b2, BindingBase b3, object converter)
      {
         Bindings.Add(b1);
         Bindings.Add(b2);
         Bindings.Add(b3);

         Converter = converter as IMultiValueConverter;
      }

      public MultiBinder(BindingBase b1, BindingBase b2, BindingBase b3, BindingBase b4, object converter)
      {
         Bindings.Add(b1);
         Bindings.Add(b2);
         Bindings.Add(b3);
         Bindings.Add(b4);

         Converter = converter as IMultiValueConverter;
      }
   }

我添加了第一个数组构造函数,只是为了看看我是否可以处理未知数量的绑定,但是我无法使调用工作。所以,我删除了它,现在我正在尝试使用3值构造函数:

<MyControl IsEnabled="{util:MultiBinder 
                         {Binding Path=IsRequestedPriceControlEnabled}, 
                         {Binding Path=IsIndicative}, 
                         {StaticResource MultiBoolConverter}
                      }" />

它给了我这个错误:

  

无法设置MultiBinding,因为必须指定MultiValueConverter。

我提供的转换器实现了IMultiValueConverter,并且在其他地方的样式块中正在使用。由于控制类型的数量和所需的可变条件,我无法在样式块中使用它。

班级宣言:public class MultiBoolToBoolConverter : IMultiValueConverter
资源:<util:MultiBoolToBoolConverter x:Key="MultiBoolConverter" />

我唯一可以想到的是,它无法识别第3个参数是转换器。我已经尝试修改IsEnabled内容以明确设置Converter,例如Discord的示例(以及修剪类只有一个带有2个参数的构造函数),但这不起作用,要么。这给出了这个错误:

  

解析标记扩展时遇到类型为“MS.Internal.Markup.MarkupExtensionParser + UnknownMarkupExtension”的未知属性“Converter”。

我的问题:

有没有人像这样制作内联多重绑定并知道我做错了什么?

注意:我使用的是.NET 4.6,因此如果需要,我可以使用任何其他功能。

编辑:

即使Evk默认为null并使用虚拟转换器,我仍然会在设计器中出现“无法设置[...]”错误。但它确实运行了。我正在测试它:

CommandParameter="{util:MultiBinder {Binding Path=IsExpiriesComboBoxEnabled}, {Binding Path=IsIndicative}, {StaticResource MultiBoolConverter}}"

如果我在MultiBinder中放置一个断点,它会正确进入3参数重载(b1,b2,转换器),我可以看到Converter被设置为MultiBoolConverter。所以,我不知道为什么它仍然给设计师错误。

解:

问题是一个非常非常愚蠢的问题。在将解决方案从VS2008迁移到VS2015之后的某个时刻,XAML设计人员给了我一个错误或者某些东西并建议禁用代码执行,所以我做了。因此,使用内联multibinder会让人感到困惑,因为转换器没有被传入。我很难找到重新启动代码执行的位置,但是一旦我这样做,它就可以工作了。因此,内联多绑定 DOES 工作 - 如果它正在执行。

如果你遇到同样的问题,这就是我没有找到的按钮:

Enable Project Code

2 个答案:

答案 0 :(得分:1)

首先,您的MultiBinder 正常工作,正如您在问题中提供的那样,没有任何修改。它在运行时不会产生任何错误,并且会调用正确的构造函数。

问题是WPF设计器,众所周知,它很多,并且在很多情况下会产生错误的错误,就像这个一样。当然你可以忽略你在设计师中看到的那个“错误”,但它很烦人,如果你忽视它们,你可能会错过真正的错误。

相反,我们可以找到设计师究竟做错了什么,并尝试解决这个问题。错误消息提供了一个线索,即在设计模式下传递给构造函数的转换器为null。然后我们可以像这样解决它:

public class MultiBinder : MultiBinding {
    public MultiBinder(BindingBase b1, BindingBase b2, object converter = null) {
        Bindings.Add(b1);
        Bindings.Add(b2);

        Converter = converter as IMultiValueConverter;
        CheckConverter();
    }

    public MultiBinder(BindingBase b1, BindingBase b2, BindingBase b3, object converter) {
        Bindings.Add(b1);
        Bindings.Add(b2);
        Bindings.Add(b3);

        Converter = converter as IMultiValueConverter;
        CheckConverter();
    }

    public MultiBinder(BindingBase b1, BindingBase b2, BindingBase b3, BindingBase b4, object converter) {
        Bindings.Add(b1);
        Bindings.Add(b2);
        Bindings.Add(b3);
        Bindings.Add(b4);

        Converter = converter as IMultiValueConverter;
        CheckConverter();
    }

    private void CheckConverter() {            
        if (Converter == null && DesignerProperties.GetIsInDesignMode(new DependencyObject())) {
            // if we are in design mode - feed dummy converter which cannot be called to wpf designer
            Converter = new DummyConverter();
        }
    }

    private class DummyConverter : IMultiValueConverter {
        public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) {
            throw new NotSupportedException();
        }

        public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) {
            throw new NotSupportedException();
        }
    }
}

此绑定器不会在设计者和运行时产生错误。

答案 1 :(得分:-2)

请参考以下代码..

<MyControl.IsEnabled>
      <util:MultiBinder Convertor="{StaticResource MultiBoolConverter}" >
          <Binding Path ="IsRequestedPriceControlEnabled"/> 
          <Binding Path ="IsIndicative"/> 
     </util:MultiBinder>
  </MyControl.IsEnabled>