我创建了自定义控件,但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"
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;
}
}
答案 0 :(得分:1)
{TemplateBinding}
是绑定的优化版本,具有一些限制。
在这种情况下,您需要将BarThickness
属性的类型更改为string
才能将其直接绑定到Text
的{{1}}属性TextBlock
。
答案 1 :(得分:0)
cmd + v
模板场景的绑定的优化形式,类似于使用
构造的绑定{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
。