将ValueConverter存储到变量

时间:2014-01-03 07:03:58

标签: c# wpf xaml ivalueconverter

我有一个ValueConverter用于在StoryBoard动画中绑定'To'Value,类似于答案 - WPF animation: binding to the “To” attribute of storyboard animation

问题是我在几个地方重复MultiBinding ValueConverter的下面一段代码。

    <MultiBinding Converter="{StaticResource multiplyConverter}">
       <Binding Path="ActualHeight" ElementName="ExpanderContent"/>
       <Binding Path="Tag" RelativeSource="{RelativeSource Self}" />
    </MultiBinding>

我希望通过将ValueConverter的结果存储到资源变量来删除此重复代码,以便将此本地变量直接绑定到故事板。

<system:Double x:Key="CalculatedWidth">
    <MultiBinding Converter="{StaticResource multiplyConverter}">
        <Binding Path="ActualHeight" ElementName="ExpanderContent"/>
        <Binding Path="Tag" RelativeSource="{RelativeSource Self}" />
    </MultiBinding>
</system:Double >

我收到以下错误:

  

“Double”类型不支持直接内容。

     

无法向“Double”类型的对象添加内容。

我觉得这是一个常见问题,但无法找到解决方案来消除这种冗余。

更新

谢谢Rohit,您的答案解决了问题。但我还有一个相关的问题,所以更新问题。此变量CalculatedWidth在正常情况下工作正常,但在RenderTransform中使用它时,它不会获取值。即如果我使用正常的方式使用转换器它可以工作,但它不会接收变量。

<StackPanel.RenderTransform>
    <TranslateTransform x:Name="SliderTransform">
        <TranslateTransform.X>
            <Binding Converter="{StaticResource PanelConverter}" ElementName="SliderPanel" Path="ActualWidth" /> // Works
            <Binding Path="Width" Source="{StaticResource CalculatedWidth}"/> // Doesn't Work
        </TranslateTransform.X>
    </TranslateTransform>
</StackPanel.RenderTransform>

我将变量保留为本地资源的一部分。这是否意味着在调用Render变换时不会创建变量?

2 个答案:

答案 0 :(得分:3)

由于错误提示您无法与Double 绑定。 绑定只能使用依赖属性

而是在资源中使用 FrameworkElement 并绑定其宽度( DP ),如下所示:

<FrameworkElement x:Key="CalculatedWidth">
    <FrameworkElement.Width>
        <MultiBinding Converter="{StaticResource multiplyConverter}">
            <Binding Path="ActualHeight" ElementName="ExpanderContent"/>
            <Binding Path="Tag" RelativeSource="{RelativeSource Self}" />
        </MultiBinding>
     </FrameworkElement.Width>
</FrameworkElement>

你可以像这个样本一样绑定这个资源:

<TextBlock Width="{Binding Width, Source={StaticResource CalculatedWidth}}"/>

答案 1 :(得分:3)

System.Double不实现INotifyPropertyChange(并且不显示要通知的Value属性),也不实现动态属性高级绑定机制。所以它无法通知它的变化。

本地资源的问题在于他们的实例:他们无法看到托管名称范围,因为它们是在其外部实现的。所以不绑定到任何东西,绑定返回DependancyProperty.UnsetValue。

相对于FrameworkElement资源本身并返回其Tag属性值:null。

如果您将VS2013与.NET 4.5一起使用(也许它也适用于VS2012 / .NET 4.0),请查看数据绑定跟踪的输出窗口:

System.Windows.Data警告:4:找不到引用'ElementName = ExpanderContent'的绑定源。 BindingExpression:路径=的ActualHeight;的DataItem = NULL; target元素是'FrameworkElement'(Name =''); target属性是'Width'(类型'Double')

为您提供了独特的解决方案:您可以将FrameworkElement移动到本地资源之外(请记住,您可能必须添加Horizo​​ntalAlign =“Left”以允许Width更改。另一种解决方案是向后面的代码添加dependancy属性。最后,您希望在多个控件(或多个属性)之间共享乘法器转换器的结果:最简单的方法是将第一个控件的第一个属性绑定到第一个属性,并将其他控件属性绑定到第一个属性。