如何从代码访问资源的结构(在可视化树下)?
How to access the structure of a Resource (down the visual tree) from code?
我在 ResourceDictionary 中定义了一个 ControlTemplate:
<ControlTemplate x:Key="FacePositionSource">
<Grid>
<Image x:Name="imagem" Width="1028" Height="524" Source="/Miotec.AtlasControl;component/Image/face.png"/>
<Canvas>
<local:MusclePositionControl x:Name="frontal" Angle="22" Canvas.Left="571.5" Canvas.Top="108"/>
</Canvas>
<Line x:Name="line" X1="0" X2="0" Y1="0" Y2="{Binding Height, ElementName=imagem}" Margin="514,0,0,0"/>
</Grid>
</ControlTemplate>
在后面的代码中,我有:
void AtlasFace_Loaded(object sender, RoutedEventArgs e)
{
var r = Application.Current.FindResource("FacePositionSource") as ControlTemplate;
Console.WriteLine(r);
// how to get those properties from "r"?
}
我在"r"下了断点,其实是指控件,但是貌似不能"read from its entrails"?我应该制作元素 public 吗?我应该使用一些特殊的方法吗?
一些上下文:
创建它是为了让我可以直观地定位 CustomControl 的一些参考点,使用此 ControlTemplate 以编程方式读取位置。
具体来说,我想得到 imagem.Width
、imagem.Height
、frontal.Canvas.Left
、frontal.Canvas.Top
、frontal.Angle
和 line.Margin.Left
,这样我可以利用图像对称性以编程方式在 UserControl 上生成一组可点击形状。
var controlTemplate= Application.Current.FindResource("FacePositionSource") as ControlTemplate;
var controlTemplateContent = controlTemplate.LoadContent();
var img = GetChildOfType<Image>(controlTemplateContent);
和接收子元素的代码
public static T GetChildOfType<T>(DependencyObject depObj)
where T : DependencyObject
{
if (depObj == null) return null;
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++)
{
var child = VisualTreeHelper.GetChild(depObj, i);
var result = (child as T) ?? GetChildOfType<T>(child);
if (result != null) return result;
}
return null;
}
当要查找的 element
具有 name
时,执行此操作的最佳形式是:
在CodeBehind
中,例如找到Image
控件:
// mycontrol is the control which use the ControlTemplate
mycontrol.ApplyTemplate();
// here you have your image
var innerImage= mycontrol.Template.Findname("imagem", mycontrol) as Image;
我在 ResourceDictionary 中定义了一个 ControlTemplate:
<ControlTemplate x:Key="FacePositionSource">
<Grid>
<Image x:Name="imagem" Width="1028" Height="524" Source="/Miotec.AtlasControl;component/Image/face.png"/>
<Canvas>
<local:MusclePositionControl x:Name="frontal" Angle="22" Canvas.Left="571.5" Canvas.Top="108"/>
</Canvas>
<Line x:Name="line" X1="0" X2="0" Y1="0" Y2="{Binding Height, ElementName=imagem}" Margin="514,0,0,0"/>
</Grid>
</ControlTemplate>
在后面的代码中,我有:
void AtlasFace_Loaded(object sender, RoutedEventArgs e)
{
var r = Application.Current.FindResource("FacePositionSource") as ControlTemplate;
Console.WriteLine(r);
// how to get those properties from "r"?
}
我在"r"下了断点,其实是指控件,但是貌似不能"read from its entrails"?我应该制作元素 public 吗?我应该使用一些特殊的方法吗?
一些上下文:
创建它是为了让我可以直观地定位 CustomControl 的一些参考点,使用此 ControlTemplate 以编程方式读取位置。
具体来说,我想得到 imagem.Width
、imagem.Height
、frontal.Canvas.Left
、frontal.Canvas.Top
、frontal.Angle
和 line.Margin.Left
,这样我可以利用图像对称性以编程方式在 UserControl 上生成一组可点击形状。
var controlTemplate= Application.Current.FindResource("FacePositionSource") as ControlTemplate;
var controlTemplateContent = controlTemplate.LoadContent();
var img = GetChildOfType<Image>(controlTemplateContent);
和接收子元素的代码
public static T GetChildOfType<T>(DependencyObject depObj)
where T : DependencyObject
{
if (depObj == null) return null;
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++)
{
var child = VisualTreeHelper.GetChild(depObj, i);
var result = (child as T) ?? GetChildOfType<T>(child);
if (result != null) return result;
}
return null;
}
当要查找的 element
具有 name
时,执行此操作的最佳形式是:
在CodeBehind
中,例如找到Image
控件:
// mycontrol is the control which use the ControlTemplate
mycontrol.ApplyTemplate();
// here you have your image
var innerImage= mycontrol.Template.Findname("imagem", mycontrol) as Image;