访问扩展器控件的子级 [英] Accessing the children of an expander control

查看:67
本文介绍了访问扩展器控件的子级的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在Expander的ContentTemplate中有一个文本块。我想在文件后面的代码中访问该文本块。这是我到目前为止尝试过的

I have a textblock inside the ContentTemplate of an Expander. I want to access that textblock in my code behind file. This is what I have tried so far

<Expander x:Name="myExp" Header="Whatever ...">
            <Expander.ContentTemplate>
                <DataTemplate>
                    <TextBlock x:Name="txtWhatever"/>
                </DataTemplate>
            </Expander.ContentTemplate>
</Expander>  

我尝试找到扩展器的子元素,但以下方法返回null,因为找不到

I try to find the child elements of the expander but the following method returns null as it does not find any children for the expander.

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;
} 

执行此操作的正确方法是什么?此外,扩展器上已应用了控制模板。

What is the correct way to do this.? Also, the Expander has a control template applied to it.

<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>


推荐答案

我已经尝试了您的代码,几乎可以了。我已经尝试过先在诸如Button上对其进行测试,但是效果很好。但是,对于 Expander 来说,它要复杂得多。这里有2条通知:

I've tried your code, it's almost fine. I've tried testing it on such as a Button first, it works OK. However for the Expander, it's more complex. There are 2 notices here:


  • 确保扩展器已扩展( IsExpanded = true )。

  • 确保布局已更新(可以显式调用 UpdateLayout

  • Be sure the Expander is expanded (IsExpanded = true).
  • Be sure the layout is updated (you can call UpdateLayout explicitly)

因此代码应为:

yourExpander.IsExpanded = true;
yourExpander.UpdateLayout();
//now use your method
var textBlock = FindVisualChild<TextBlock>(yourExpander);

您的代码可以缩短,例如:

Your code can be shorten more like this:

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;
}

请注意,孩子永远不会为<$​​ c $ c> null 。因为 GetChildrenCount()已经限制了 现有 子级的范围,所以 child 应该位于指定索引 i

Note that child will never be null. Because the GetChildrenCount() already limits the range of existing children, so the child should exist at the specified index i.

这篇关于访问扩展器控件的子级的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆