繁体   English   中英

WPF TemplateBinding不适用于每个属性

[英]WPF TemplateBinding does not work for every property

我已经创建了自定义控件,但是TemplateBinding不适用于每个属性吗? 如果我使用仅转发原始值的虚拟Converter,则模板绑定确实开始工作。 具有相同问题的简化示例:

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

后面的代码:

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); }
    }
}

用法:

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

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}是绑定的优化版本,具有一些限制。

在这种情况下,您需要将BarThickness属性的类型更改为string ,以便能够使用{TemplateBinding}将其直接绑定到TextBlockText属性。

文档指出{TemplateBinding}

用于模板方案的Binding的优化形式,类似于使用{Binding RelativeSource={RelativeSource TemplatedParent}}构造的{Binding RelativeSource={RelativeSource TemplatedParent}}

有一些限制-最重要的是, 它仅在视觉树中起作用!


这对您的特定情况意味着什么:虽然您不能使用

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

您可以(必须)使用

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

因为TextBlock.Text属性是string类型,而BarTickness不是。

{TemplateBinding}不会进行这种转换; 这就是为什么您需要使用更通用的{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;
}

两者都将实际值转换为object

暂无
暂无

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

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