嵌套MultiBinding(s)

Lou*_*ann 18 c# wpf multibinding

我已经玩了很长一段时间的WPF,但今天我第一次需要MultiBinding在另一个内部嵌套,类似于:

<MultiBinding>
   <Binding />       
   <MultiBinding>
      <Binding />
      <Binding />
   </MultiBinding>
</MultiBinding>
Run Code Online (Sandbox Code Playgroud)

我得到一个异常,表明框架不允许它:

XamlParseException未处理:向类型'System.Collections.ObjectModel.Collection(System.Windows.Data.BindingBase)'的集合添加值引发异常.

InnerException更明确的是:

BindingCollection不支持MultiBinding类型的项.只允许绑定.

所以挖掘网络以获取更多信息,我偶然发现了这个Microsoft Connect问题,这正是我的问题所在.

感谢您的反馈.WPF今天不支持这一点.多年来一直要求使用此功能(最近一次是本月早些时候 - 请参阅https://connect.microsoft.com/WPF/feedback/details/650164/nested-multibinding).我们将继续考虑将来的版本.

现在我已经平静下来,我不会轻松.我仍然需要这个,我如何嵌套MultiBindings

小智 8

我知道这是一个老问题,但我认为这是一个更好的方法:

<FrameworkElement x:Name="IsBuyAndAmountInReference">
    <FrameworkElement.Tag>
        <MultiBinding Converter="{StaticResource LogicAndToBool}">
            <Binding Path="OrderData.IsBuy" />
            <Binding Path="OrderData.AmountInReference" />
        </MultiBinding>
    </FrameworkElement.Tag>
</FrameworkElement>
<FrameworkElement x:Name="IsSellAndAmountInBase">
    <FrameworkElement.Tag>
        <MultiBinding Converter="{StaticResource LogicAndToBool}">
            <Binding Path="OrderData.IsBuy" Converter="{StaticResource BooleanToBooleanInvert}" />
            <Binding Path="OrderData.AmountInReference" Converter="{StaticResource BooleanToBooleanInvert}" />
        </MultiBinding>
    </FrameworkElement.Tag>
</FrameworkElement>

<Slider Grid.Row="2" Grid.ColumnSpan="4">
    <Slider.Visibility>
        <MultiBinding Converter="{StaticResource LogicOrToVisibility}">
            <Binding ElementName="IsBuyAndAmountInReference" Path="Tag" />
            <Binding ElementName="IsSellAndAmountInBase" Path="Tag" />
        </MultiBinding>
    </Slider.Visibility>
</Slider>
Run Code Online (Sandbox Code Playgroud)


Mat*_*mas 7

其他建议的替代方法是使用附加属性将嵌套的MultiBinding值保存为中间值。

例如,代替:

<Element>
  <Element.Property>
    <MultiBinding>
      <Binding Path="A" />       
      <MultiBinding>
        <Binding Path="B" />
        <Binding Path="C" />
      </MultiBinding>
    </MultiBinding>
  </Element.Property>
</Element>
Run Code Online (Sandbox Code Playgroud)

...做这个:

<Element Name="ElementName">
  <ElementProperties.AttachedProperty>
    <MultiBinding>
      <Binding Path="B" />
      <Binding Path="C" />
    </MultiBinding>
  </ElementProperties.AttachedProperty>
  <Element.Property>
    <MultiBinding>
      <Binding Path="A" />       
      <Binding ElementName="ElementName" Path="(ElementProperties.AttachedProperty)" />
    </MultiBinding>
  </Element.Property>
</Element>
Run Code Online (Sandbox Code Playgroud)

我知道这个问题已经有六年多了,但我遇到了这个问题,所以其他人也会遇到。


Dan*_*zey 5

如果您有一个带有参数的转换器,您可以执行以下操作:

  • 创建一个类,用于将“固定”数据传递给转换器
  • 添加DependencyProperties到类中(以便可以绑定Xaml中的值)
  • 在您的 xaml 中,使用带有转换器的绑定而不是多重绑定,如下所示:

    <MultiBinding>
        <Binding Source="SomeObject" Path="CoreValue" Converter="{StaticResource YourNewConverter}">
            <Binding.ConverterParameter>
                <ns:ParameterClass Value1="{Binding Parameter1}" Value2="{Binding Parameter1}" />
            </Binding.ConverterParameter>
        </Binding>
     .... 
    
    Run Code Online (Sandbox Code Playgroud)

限制是(据我所知)该值仅在CoreValue发生变化时才会重新计算 - 如果转换器参数发生变化,它不会自动重新绑定。

(对任何错误表示歉意,我在没有使用 VS 进行测试的情况下输入此内容...)


Wol*_*ead 5

我意识到这是一个老问题了,但我刚刚遇到了与OP完全相同的问题。幸运的是,在我的例子中,我可以绑定到一个子元素,其中多重绑定的结果已经被计算出来,但这让我思考......

一个(虽然诚然不是很干净)的解决方案是将多值绑定的值写入“备用”属性,例如元素的“标签”,然后您可以通过指定“在其他多值绑定中引用它”元素名称' 属性。

如果您需要多个嵌套多值绑定,那么您可以创建一个带有一些依赖属性的“假”对象来存储多个中间结果。

遗憾的是微软没有实现正确的嵌套系统......


bli*_*eis 0

只需使用一个多重绑定和一个多重转换器即可。

或者我更喜欢在视图模型/数据上下文的一个属性中公开您的条件。

  • 是的,但这违背了它的全部目的,如果我需要创建一个仅结合其他转换器的新转换器,并且因为我有大约一百个转换器......那是很多样板文件。 (12认同)