嵌套MultiBinding(s)

时间:2012-04-23 12:23:03

标签: c# wpf multibinding

我已经玩了很长一段时间的WPF,但是今天我第一次需要将MultiBinding嵌入到另一个内部,例如:

<MultiBinding>
   <Binding />       
   <MultiBinding>
      <Binding />
      <Binding />
   </MultiBinding>
</MultiBinding>

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

  

未处理XamlParseException:向类型为“System.Collections.ObjectModel.Collection(System.Windows.Data.BindingBase)”的集合添加值时抛出异常。

InnerException更明确:

  

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

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

  

感谢您的反馈。 WPF今天不支持这一点。这个   功能已被要求多年(最近一个月早些时候    - 见https://connect.microsoft.com/WPF/feedback/details/650164/nested-multibinding)。   我们将继续考虑将来的版本。

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

6 个答案:

答案 0 :(得分:4)

如果你有一个带参数的转换器,你可以这样做:

  • 创建一个用于将“已修复”数据传递到转换器的类
  • 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>
     .... 
    

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

(对于任何错误道歉,我正在输入这个没有VS的好处来测试...)

答案 1 :(得分:4)

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

A(虽然不是很干净)解决方案是将多值绑定的值写入备用&#39;财产,如元素&#39;标记&#39;然后,您可以通过指定&#39; ElementName&#39;来引用其他多值绑定。属性。

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

可惜微软没有实现一个正确嵌套的系统......

答案 2 :(得分:1)

如果你绑定到一个字符串,你可以使用StringFormat,就像在这个例子中一样:

 <TextBlock>
   <TextBlock.Text>
     <MultiBinding StringFormat="{}{0:0.###}/{1:0.###}" Mode="OneWay">
                        <Binding ElementName="This" Path="AggregatedDocDetail.ConfirmedQty"></Binding>
                        <Binding ElementName="This" Path="AggregatedDocDetail.Qty">   </Binding>
       </MultiBinding>
     </TextBlock.Text>
   </TextBlock>

答案 3 :(得分:1)

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

<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>

答案 4 :(得分:0)

只需使用一个多重绑定和一个MultiConverter。

或者我更喜欢在viewmodel / datacontext的一个属性中公开你的条件。

答案 5 :(得分:0)

其他建议的替代方法是使用附加属性将嵌套的#!/bin/bash format='+%Y-%m-%d %H:%M:%S' date1='Wed 31 Oct 2018 08:42:00 AM UTC' date1=$(date -d "$date1" "$format") date2=$(date -r "$fname" "$format") if [[ $date1 < $date2 ]] ; then echo "$date1 goes before $date2" else echo "$date1 goes after $date2" fi 保留为中间值。

例如,代替:

MultiBinding

...执行此操作:

<Element>
  <Element.Property>
    <MultiBinding>
      <Binding Path="A" />       
      <MultiBinding>
        <Binding Path="B" />
        <Binding Path="C" />
      </MultiBinding>
    </MultiBinding>
  </Element.Property>
</Element>

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