代码之家  ›  专栏  ›  技术社区  ›  user007

WPF TemplateBinding并不适用于所有属性

  •  0
  • user007  · 技术社区  · 7 年前

    我已经创建了自定义控件,但是 TemplateBinding 不是每一处房产都适用吗? 如果我使用只转发原始值的虚拟转换器,模板绑定就会开始工作。 具有相同问题的简化示例:

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

    调试转换器:

    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;
        }
    }
    
    2 回复  |  直到 7 年前
        1
  •  1
  •   mm8    7 年前

    {TemplateBinding} 是绑定的优化版本,有一些限制。

    在这种情况下,您需要更改 BarThickness 财产 string 能够将其直接绑定到 Text a的性质 TextBlock 使用 {TemplateBinding} .

        2
  •  0
  •   Thomas Flinkow    7 年前

    这个 docs state 那是 {TemplateBinding}

    模板场景绑定的优化形式,类似于使用 {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 .