【问题标题】:Storing ValueConverter to variable将 ValueConverter 存储到变量
【发布时间】:2014-01-20 19:28:25
【问题描述】:

我有一个用于在 StoryBoard 动画中绑定“To”值的 ValueConverter,类似于答案 - 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 中使用时它不会获取值。即,如果我使用正常的方式来使用 Converter 它可以工作,但它不会拾取变量。

<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 转换时不会创建变量?

【问题讨论】:

  • 那个更新应该是另一个问题,这里的答案应该被接受。否则只会令人困惑。

标签: c# wpf xaml ivalueconverter


【解决方案1】:

正如错误提示您无法与 Double 绑定绑定只能通过依赖属性来完成

改为在资源中使用 FrameworkElement 并像这样绑定它的 Width(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}}"/>

【讨论】:

  • 你能用DependencyObject 和一些附加属性来代替FrameworkElement.Width吗?
【解决方案2】:

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

本地资源的问题在于它们的实例化:它们无法看到托管名称范围,因为它们是在外部实例化的。所以不会绑定任何内容,并且绑定返回 DependancyProperty.UnsetValue。

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

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

System.Windows.Data 警告:4:找不到与引用“ElementName=ExpanderContent”进行绑定的源。绑定表达式:路径=实际高度;数据项=空;目标元素是'FrameworkElement'(名称='');目标属性是“宽度”(类型“双”)

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

【讨论】:

    猜你喜欢
    • 2018-04-04
    • 2016-05-10
    • 1970-01-01
    • 2019-03-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多