简体   繁体   English

WPF TemplateBinding不适用于每个属性

[英]WPF TemplateBinding does not work for every property

I have created custom control, but TemplateBinding does not work for every property? 我已经创建了自定义控件,但是TemplateBinding不适用于每个属性吗? Template Binding does start working if I use dummy Converter that just forwards original values. 如果我使用仅转发原始值的虚拟Converter,则模板绑定确实开始工作。 Simplified example that has the same issue: 具有相同问题的简化示例:

<Style TargetType="{x:Type controls:ElipticProgressBar}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type controls:ElipticProgressBar}">
                <ControlTemplate.Resources>
                    <converters:DebugConverter x:Key="DebugConverter"/>
                </ControlTemplate.Resources>
                <StackPanel>
                    <!--BarColor works always-->
                    <!--BarTickness works-->
                    <Label Background="{TemplateBinding BarColor}" Content="{TemplateBinding BarTickness}"/>
                    <!--BarTickness does not works-->
                    <TextBlock Background="{TemplateBinding BarColor}" Text="{TemplateBinding BarTickness}"/>
                    <!--BarTickness works-->
                    <TextBlock Background="{TemplateBinding BarColor}" Text="{Binding BarTickness, RelativeSource={RelativeSource TemplatedParent}, Mode=OneWay}"/>
                    <!--BarTickness works-->
                    <TextBlock Background="{TemplateBinding BarColor}" Text="{TemplateBinding BarTickness, Converter={StaticResource DebugConverter}}"/>
                </StackPanel>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

back code: 后面的代码:

public class ElipticProgressBar : Control
{
    static ElipticProgressBar()
    {
        DefaultStyleKeyProperty.OverrideMetadata(typeof(ElipticProgressBar), new FrameworkPropertyMetadata(typeof(ElipticProgressBar)));
    }

    public static readonly DependencyProperty BarTicknessProperty = DependencyProperty.Register(
        "BarTickness", typeof(int), typeof(ElipticProgressBar), new FrameworkPropertyMetadata(default(int)));

    public int BarTickness
    {
        get { return (int)GetValue(BarTicknessProperty); }
        set { SetValue(BarTicknessProperty, value); }
    }

    public static readonly DependencyProperty BarColorProperty = DependencyProperty.Register(
        "BarColor", typeof(Brush), typeof(ElipticProgressBar), new FrameworkPropertyMetadata(default(Brush)));

    public Brush BarColor
    {
        get { return (Brush)GetValue(BarColorProperty); }
        set { SetValue(BarColorProperty, value); }
    }
}

usage: 用法:

controls:ElipticProgressBar BarTickness="30" BarColor="Orange"

DebugConverter: DebugConverter:

public class DebugConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return value;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return value;
    }
}

{TemplateBinding} is an optimized version of a binding that has some limitations. {TemplateBinding}是绑定的优化版本,具有一些限制。

In this case you need to change the type of the BarThickness property to string to be able to bind it directly to the Text property of a TextBlock using a {TemplateBinding} . 在这种情况下,您需要将BarThickness属性的类型更改为string ,以便能够使用{TemplateBinding}将其直接绑定到TextBlockText属性。

The docs state that a {TemplateBinding} is 文档指出{TemplateBinding}

an optimized form of a Binding for template scenarios, analogous to a Binding constructed with {Binding RelativeSource={RelativeSource TemplatedParent}} 用于模板方案的Binding的优化形式,类似于使用{Binding RelativeSource={RelativeSource TemplatedParent}}构造的{Binding RelativeSource={RelativeSource TemplatedParent}}

with some limitations - most importantly that it works only within the visual tree! 有一些限制-最重要的是, 它仅在视觉树中起作用!


What that means for your specific case: while you cannot use 这对您的特定情况意味着什么:虽然您不能使用

<TextBlock Text="{TemplateBinding BarTickness}" />

you can (and have to) use 您可以(必须)使用

<TextBlock Text="{Binding BarTickness, RelativeSource={RelativeSource TemplatedParent}, Mode=OneWay}" />

because TextBlock.Text property is of type string while the BarTickness is not. 因为TextBlock.Text属性是string类型,而BarTickness不是。

{TemplateBinding} does not do that kind of converting; {TemplateBinding}不会进行这种转换; that's why you need to use the more generic {Binding} or a converter, whose both methods 这就是为什么您需要使用更通用的{Binding}或转换器,而这两种方法

public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
    return value;
}

public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
    return value;
}

both convert the actual value to an object . 两者都将实际值转换为object

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM