[英]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}
将其直接绑定到TextBlock
的Text
属性。
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.