如何访问元素的模板
本文关键字:元素 访问 何访问 | 更新日期: 2023-09-27 18:36:01
我有一个Control
,它的ControlTemplate
内(Style
内)有一个ScrollViewer
,我想访问该ScrollViewer
与ScrollSynchronizer
一起工作。
http://www.codeproject.com/Articles/39244/Scroll-Synchronization
下面是控件的Style
:
<!--ZoomControl-->
<Style TargetType="{x:Type local:ZoomBox}">
<Setter Property="ClipToBounds" Value="True"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:ZoomBox}">
<ScrollViewer x:Name="ScrollViewer" ClipToBounds="True"
Background="Transparent" SnapsToDevicePixels="True"
UseLayoutRounding="True"
VerticalScrollBarVisibility="Auto"
HorizontalScrollBarVisibility="Auto" >
<Grid x:Name="Grid" RenderTransformOrigin="0.5,0.5"
Background="Transparent" HorizontalAlignment="Center"
VerticalAlignment="Center" SnapsToDevicePixels="True"
UseLayoutRounding="True">
<Grid.LayoutTransform>
<TransformGroup>
<ScaleTransform x:Name="ScaleTransform"/>
</TransformGroup>
</Grid.LayoutTransform>
<Viewbox Grid.Column="0" Grid.Row="0" SnapsToDevicePixels="True"
UseLayoutRounding="True">
<Image Name="ImageCtrl" Source="{TemplateBinding ImageSource,
Converter={StaticResource UriToBitmapConverter}}"
SnapsToDevicePixels="True" UseLayoutRounding="True"/>
</Viewbox>
</Grid>
</ScrollViewer>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
我正在尝试这样做:
private static void OnScrollGroupChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var scrollViewer = d as ScrollViewer;
if (scrollViewer == null && d.GetType() == typeof (ZoomBox))
{
//FindResource always returns null.
scrollViewer = (ScrollViewer)(d as ZoomBox).FindResource("ScrollViewer");
}
//...
}
我还尝试在自定义控件中创建一个公共Getter
:
public ScrollViewer GetScrollViewer()
{
return Template.FindName("ScrollViewer", this) as ScrollViewer;
}
在 OnApplyTemplate()
方法中,相同的代码有效。但在这种情况下,Resources
为空或为空。
编辑:
ScrollSynchronization
类在使用AttachedProperty
对元素进行分组ScrollViewer
时工作:
<n:ZoomBox x:Name="ZoomBoxControl" util:ScrollSynchronizer.ScrollGroup="Group1"/>
<ScrollViewer x:Name="SideScrollViewer" util:ScrollSynchronizer.ScrollGroup="Group1"/>
因此,在触发OnScrollGroupChanged
之前,Zoombox
元素甚至没有初始化。这也许可以解释为什么Resource
总是空的。
编辑 2:
一种可能的解决方案是在窗口加载后通过代码设置AttachedProperty
。
编辑3:
这段代码有效,它在 Window_OnLoaded
事件中运行,我只是希望我可以使用 xaml 来附加属性。
ScrollSynchronizer.SetScrollGroup(ZoomBoxControl.GetScrollViewer(), "Canvas");
ScrollSynchronizer.SetScrollGroup(MainScrollViewer, "Canvas");
在调用OnGroupChanged
后,我查看了可视化树,看起来AttachedProperty
在解释ZoomBox
元素后立即解决,但在初始化之前。所以还没有加载Template
。
理解正确,您正在编写一个自定义控件,因此您在某处有一个派生自Control
或FrameworkElement
派生类的类:
刚刚测试过,这对我来说非常有效:
[TemplatePart(Name = "ScrollViewer", Type = typeof(ScrollViewer))]
public class ZoomBox : Control
{
private ScrollViewer _scrollViewerPart;
public override void OnApplyTemplate()
{
_scrollViewerPart = GetTemplateChild("ScrollViewer") as ScrollViewer;
}
public ScrollViewer GetScrollViewer()
{
return _scrollViewerPart;
}
}
正如 MSDN 文章所写的关于OnApplyTemplate
FrameworkElement 的派生类可以使用此方法作为各种可能方案的通知:
- 可以运行依赖于已应用模板中的可视化树的代码,例如获取对来自模板的命名元素的引用。