如何解决如何在Path.Data中使用TemplateBinding?
如何将Path.Data
中的属性绑定到TemplateBinding
?我注意到在下面的示例中,属性SegmentColor
和strokeThickness
的设置和更新正确,但属性TargetPoint
却没有正确设置和更新。进一步的测试似乎可以确认问题似乎与嵌套在Path.Data
元素中的属性有关。以下代码试图简化为自定义控件创建模板时遇到的上下文。
C#:
public class TestProgressBar : ProgressBar
{
public Brush SegmentColor
{
get { return (Brush)GetValue(SegmentColorProperty); }
set { SetValue(SegmentColorProperty,value); }
}
public double strokeThickness
{
get { return (double)GetValue(strokeThicknessProperty); }
set { SetValue(strokeThicknessProperty,value); }
}
public Point TargetPoint
{
get { return (Point)GetValue(TargetPointProperty); }
set { SetValue(TargetPointProperty,value); }
}
public static readonly DependencyProperty strokeThicknessProperty =
DependencyProperty.Register(nameof(strokeThickness),typeof(double),typeof(TestProgressBar),new PropertyMetadata());
public static readonly DependencyProperty SegmentColorProperty =
DependencyProperty.Register(nameof(SegmentColor),typeof(Brush),new PropertyMetadata(new SolidColorBrush(Colors.Red)));
public static readonly DependencyProperty TargetPointProperty =
DependencyProperty.Register(nameof(TargetPoint),typeof(Point),new PropertyMetadata());
}
Xaml:
<c:TestProgressBar strokeThickness="15"
TargetPoint="100,0">
<c:TestProgressBar.Style>
<Style targettype="{x:Type c:TestProgressBar}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate targettype="{x:Type c:TestProgressBar}">
<Grid>
<Path
stroke="{TemplateBinding SegmentColor}"
strokeThickness="{TemplateBinding strokeThickness}"
Width="100" Height="100">
<Path.Data>
<PathGeometry>
<Pathfigure>
<Linesegment Point="{TemplateBinding TargetPoint}"/>
</Pathfigure>
</PathGeometry>
</Path.Data>
</Path>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</c:TestProgressBar.Style>
</c:TestProgressBar>
解决方法
问题是关于TemplateBinding
(do not work on properties Freezable
s)的鲜为人知的细节。实际上,正如您在其继承层次结构中看到的,LineSegment
是间接从Freezable
派生的。
Object-> DispatcherObject-> DependencyObject-> Freezable -> Animatable-> PathSegment-> LineSegment
但是,Path
无效,这就是其属性上的TemplateBinding
起作用的原因。由于模板绑定只是Binding
的优化的但受限制的版本,因此您可以始终use its binding syntax equivalent不受任何限制,并且可以在{{1} } s。
Freezable
请注意,此处<LineSegment Point="{Binding TargetPoint,RelativeSource={RelativeSource TemplatedParent},Mode=OneWay}"/>
设置为Mode
,以指出OneWay
始终是单向的,这等效于TemplateBinding
,但是绑定更强大,并支持任何绑定模式。
我使用的是只读依赖项属性,因此该问题无法链接到TwoWay绑定问题(因为我很难做到TemplateBinding的情况)。
依赖项属性声明必须是只读的,但这不会使依赖项属性本身成为只读,这是通过声明依赖项属性键并使用Binding
方法来完成的。
似乎在Path.Data中使用TemplateBindings会导致此问题。将其替换为TemplatedParent绑定可解决此问题:
<LineSegment Point="{Binding TargetPoint,RelativeSource={RelativeSource TemplatedParent}}"/>
不过,我不能完全解释为什么。在我的原始代码中,我使用的是只读依赖项属性,因此该问题无法链接到TwoWay绑定问题(因为我对TemplateBinding很难做到)。
我知道,使用TemplatedParent进行绑定是在运行时评估的,而不是TemplateBinding的编译时,因此也许可以通过某些方式来修复绑定。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。