【问题标题】:Moving a complicated XAML binding to a Style Setter将复杂的 XAML 绑定移动到样式设置器
【发布时间】:2018-06-14 19:43:00
【问题描述】:

我正在使用带有自定义样式和控件模板的复选框。我也想将高度和宽度绑定移到样式上,但我似乎无法正确处理。

这里是 XAML 复选框

<CheckBox Style="{StaticResource MyCheckStyle}"
      HorizontalAlignment="Center"
      Height="{Binding FontSize, 
                       Source={x:Static gap:Settings.Default},
                       Converter={StaticResource MyMathConverter},
                       ConverterParameter='x+10'}"
      Width="{Binding ActualHeight, RelativeSource={RelativeSource Self}}"
      IsChecked="{Binding ValueT, Mode=TwoWay, UpdateSourceTrigger=LostFocus}" 
      />
  • 我正在尝试实现一个复选框,其高度(以像素为单位)比当前字体大小(以点为单位)大 10(一个 hack,但现在请忽略它)。
  • 我将 Width 绑定到 ActualHeight 以便它们始终是方形的(否则我的自定义模板将允许任何尺寸)
  • 我正在使用转换器(Ivan Krivyakov 的MathConverter)来计算。
  • 我绑定的大小存储在从设置文件生成的设置类的静态实例中。

MyCheckStyle 目前如下:

<Style x:Key="MyCheckStyle" TargetType="{x:Type CheckBox}">
    <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
    <Setter Property="VerticalContentAlignment" Value="Stretch"/>
    <Setter Property="Template" Value="{StaticResource MyCheckBoxTemplate}" />
</Style>

到目前为止,这一切都完美无缺。但是我尝试将 Width 绑定移动到样式会使应用程序崩溃:

    <!-- WIDTH BINDING.  CAUSES A CRASH DUE TO ACCESS VIOLATION -->

    <Setter Property="Width">
        <Setter.Value>
            <Binding>
                <Binding.Source>
                    <RelativeSource Mode="Self"/>
                </Binding.Source>
                <Binding.Path>
                    <PropertyPath Path="ActualHeight"/>
                </Binding.Path>
            </Binding>
        </Setter.Value>
    </Setter>

我尝试移动 Height 绑定的尝试完全失败。我不知道如何在元素语法中复制“x:Static”标记扩展等。 Intellisense/ReSharper 对我帮助不大。

    <Setter Property="Height">
        <Setter.Value>
            <Binding>
            <!-- NO IDEA WHAT TO PUT HERE? -->
            </Binding>
        </Setter.Value>
    </Setter>

</Style>

任何人都可以设置我的权利吗?我正在做的事情可能吗?

【问题讨论】:

    标签: wpf xaml data-binding


    【解决方案1】:

    你做过吗

    Prop="{Binding Source={RelativeSouce ...}}"?
    

    不。这不是源,它是相对源。花括号标记扩展语法设置与 XML 元素语法相同的属性,但带有花括号。就这样。如果是带花括号的RelativeSource,则为带尖括号的RelativeSource。

    <Setter Property="Width">
        <Setter.Value>
            <Binding>
                <!-- RelativeSource, not Source -->
                <Binding.RelativeSource>
                    <RelativeSource Mode="Self"/>
                </Binding.RelativeSource>
                <Binding.Path>
                    <PropertyPath Path="ActualHeight"/>
                </Binding.Path>
            </Binding>
        </Setter.Value>
    </Setter>
    

    对于x:Static,这是另一个标记扩展(System.Windows.Markup.MarkupExtension 的子类)。如果标记扩展类名称具有 Extension 后缀,则 XAML 解析器允许您省略“扩展”部分。所以碰巧that class is actually named StaticExtension。如果你想要 local 命名空间中的静态成员 Foo.Bar,很简单:

    <x:StaticExtension Member="local:Foo.Bar" />
    

    The Binding class 是MarkupExtension 的子类(通过BindingBase),这就是您可以使用花括号语法的原因。但是,它没有“扩展”名称后缀。这是可选的。那里没有特别的一致性。

    关键点:每一件事都是一个类。 XAML 是一种用于实例化类实例并使用标量值或其他类实例初始化其属性的表示法。花括号标记扩展语法是一个有趣的小补充——但它很有用,正如您将上面的 XAML 与我将建议作为替代的 XAML 进行比较时看到的那样。

    现在,这一切都值得知道,但你在这里不需要任何东西。

    tl;博士

    <Setter 
        Property="Width" 
        Value="{Binding ActualHeight, RelativeSource={RelativeSource Self}}" 
        />
    <Setter
        Property="Height"
        Value="{Binding FontSize, 
                Source={x:Static gap:Settings.Default},
                Converter={StaticResource MyMathConverter},
                ConverterParameter='x+10'}"
        />
    

    完成。

    【讨论】:

    • Grrr.... (刘海头放在桌子上)。最后一点是正是我认为它应该是!我只在无法使其工作时才使用元素语法。我真的以为我已经尝试过您发布的内容。显然不是因为……嗯……我们到了。我把它搞砸了,走上了一条毫无意义的切线。我什至问了这个问题我都觉得很愚蠢。感谢您的宝贵时间和耐心的解释。
    • @Joe 那是 WPF。你得到了 99% 的正确性,但据你所知,它是 100% 错误的。
    猜你喜欢
    • 1970-01-01
    • 2013-07-23
    • 1970-01-01
    • 2011-02-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-02
    相关资源
    最近更新 更多