我在扩展器的内容模板内有一个文本 block 。我想访问我的代码隐藏文件中的该文本 block 。这是我到目前为止所尝试过的
<Expander x:Name="myExp" Header="Whatever ...">
<Expander.ContentTemplate>
<DataTemplate>
<TextBlock x:Name="txtWhatever"/>
</DataTemplate>
</Expander.ContentTemplate>
</Expander>
我尝试查找扩展器的子元素,但以下方法返回 null,因为它没有找到扩展器的任何子元素。
ContentPresenter myContentPresenter = FindVisualChild<ContentPresenter>(myExp);
private childItem FindVisualChild<childItem>(DependencyObject obj) where childItem : DependencyObject
{
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++)
{
DependencyObject child = VisualTreeHelper.GetChild(obj, i);
if (child != null && child is childItem)
return (childItem)child;
else
{
childItem childOfChild = FindVisualChild<childItem>(child);
if (childOfChild != null)
return childOfChild;
}
}
return null;
}
正确的做法是什么?此外,Expander 还应用了一个控制模板。
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Expander}">
<Border SnapsToDevicePixels="true" BorderThickness="1,1,1,1" Margin="0,0,0,-2" BorderBrush="{DynamicResource DisabledBorderBrush}" >
<DockPanel>
<ToggleButton x:Name="HeaderSite" MinHeight="0" MinWidth="0" Style="{DynamicResource ToggleButtonGraphicsStyleLRUHeader}"
Content="{TemplateBinding Header}" ContentTemplate="{TemplateBinding HeaderTemplate}"
ContentTemplateSelector="{TemplateBinding HeaderTemplateSelector}" FontFamily="{TemplateBinding FontFamily}"
FontSize="{TemplateBinding FontSize}" FontStretch="{TemplateBinding FontStretch}"
FontStyle="{TemplateBinding FontStyle}" FontWeight="{TemplateBinding FontWeight}"
Foreground="{TemplateBinding Foreground}" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
Padding="{TemplateBinding Padding}" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"
IsChecked="{Binding IsExpanded, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}" DockPanel.Dock="Top"
Height="24"/>
<ContentPresenter x:Name="ExpandSite" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" Focusable="false" Visibility="Collapsed" DockPanel.Dock="Bottom"/>
</DockPanel>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsExpanded" Value="true">
<Setter Property="Visibility" TargetName="ExpandSite" Value="Visible"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
最佳答案
我已经尝试过你的代码,几乎没问题。我先尝试在按钮等上测试它,它工作正常。然而对于 Expander
来说,它更加复杂。这里有 2 个通知:
- 确保 Expander 已展开 (
IsExpanded = true
)。 - 确保布局已更新(您可以显式调用
UpdateLayout
)
所以代码应该是:
yourExpander.IsExpanded = true;
yourExpander.UpdateLayout();
//now use your method
var textBlock = FindVisualChild<TextBlock>(yourExpander);
您的代码可以像这样缩短:
private childItem FindVisualChild<childItem>(DependencyObject obj)
where childItem : DependencyObject
{
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++)
{
DependencyObject child = VisualTreeHelper.GetChild(obj, i);
if(child is childItem) return (childItem)child;
childItem childOfChild = FindVisualChild<childItem>(child);
if (childOfChild != null) return childOfChild;
}
return null;
}
请注意,child
永远不会是 null
。由于 GetChildrenCount()
已经限制了现有子项的范围,因此子项
应该存在于指定索引处我
。
关于c# - 访问扩展器控件的子级,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26422811/