c# - 访问扩展器控件的子级

标签 c# wpf xaml c#-4.0

我在扩展器的内容模板内有一个文本 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/

相关文章:

xaml - Xamarin Forms InitializeComponent 不存在

c# - ado.net 中的 where 子句中的空值参数

c# - 如何防止 .NET XML 解析器扩展 XML 中的参数实体?

c# - 反复按下按钮时,ColorAnimation 停留在颜色上

wpf - 如何将数据模板分配给文本框 wpf

wpf treeviewitem鼠标双击

c# - 用于保留空格的 XAML 等效代码是什么?

c# - 检测何时滚动 ListView "up"或 "down"? Windows Phone 8.1 ListView

c# - 移动虚线进行裁剪

xaml - 根据 bool 值更改 Xamarin 表单标签的文本