【问题标题】:Inline MultiBinding not working as expected内联 MultiBinding 未按预期工作
【发布时间】:2026-01-09 15:25:11
【问题描述】:

我使用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
资源:&lt;util:MultiBoolToBoolConverter x:Key="MultiBoolConverter" /&gt;

我唯一能想到的是它无法识别第三个参数是转换器。我尝试修改IsEnabled 内容以显式设置Converter,就像Discord 的示例一样(同时将类缩减为只有一个带有2 个参数的构造函数),但这也不起作用。这给出了这个错误:

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

我的问题:

有没有人做过这样的内联多重绑定并且知道我做错了什么?

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


编辑:

即使 Evk 默认为 null 并使用虚拟转换器,我仍然在设计器中收到上述“无法设置 [...]”错误。但是,它确实运行。我正在用这个测试它:

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

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

解决方案:

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

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

【问题讨论】:

    标签: c# .net wpf


    【解决方案1】:

    请参考下面的代码..

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

    【讨论】:

    • 我试图避免这样的扩展符号。这是一个自定义选项卡内容控件,其中包含很多内容。 XAML 为 49KB,代码隐藏为 23KB。此外,这些控件还有一堆其他属性绑定(大多数都有超过 10 个)等等,所以我试图将每个属性绑定放在一行上。我的示例只是为了展示我如何尝试设置一个属性。注意:反对票不是我的。
    • 哦,好吧,我想我理解错了。如果答案没有帮助,您应该投反对票:)
    • 没问题。我不会投反对票,因为即使它没有直接适用于我的问题,其他人可能会发现它很有用。 :-)
    • 当问题明确要求“内联多重绑定”时,这怎么可能有用。如果没有内联部分,它将是一个普通的 MultiBinding,不需要专门的/派生类。这篇文章只是展示了 MultiBinding 在(然后是冗余的)派生的 MultiBinding 类上的标准 XAML 语法,因此不是问题的答案。 IMO 应该删除它,以避免给人留下问题已经有答案的印象。
    • 如果你好奇:我原来的方法奏效了。缺少的是项目代码执行。我编辑了我的帖子以显示解决方案。作为旁注:我也不会因为对我的代表惩罚而投反对票。 ;-)
    【解决方案2】:

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

    问题是 WPF 设计器,众所周知,它有很多错误并且在许多情况下会产生错误的错误,比如这个。当然,您可以忽略在设计器中看到的“错误”,但这很烦人,而且如果您忽略它们,您可能会错过真正的错误。

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

    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();
            }
        }
    }
    

    这个活页夹在设计器和运行时都不会产生错误。

    【讨论】:

    • 我不知道为什么,但我的在设计和构建期间仍然会出现转换器错误。但是,该应用程序确实运行。我正在寻找一个可以让我确认它在运行时是否正常工作的设置。一些布尔值目前不在我的控制范围内,因为它们来自服务器。
    • 好吧,我验证了上面的代码解决了这个问题。如果它不适合您 - 提供更多代码,我们可以解决。
    • 我想我知道问题出在哪里。在迁移到 VS2015 后的某个时间之前,它给了我一条关于由于错误而禁用代码执行的消息。现在它不会在任何设计师上运行转换器等。所以,这可能是原因。我想弄清楚如何重新打开它。这也将让我找到需要设计时防御性编码的内容。
    • 找到了。设计器“启用项目代码”下的非常小的按钮。你猜怎么了?错误消失了。
    • 很高兴你终于弄明白了。
    最近更新 更多