none
为什么找不到子控件? RRS feed

  • 问题

  • 在网上找到一个找子控件的函数,修改了一下,想实现类似于jquery的selector

     

            public List<T> GetChildren<T>(DependencyObject obj) where T : FrameworkElement

            {

                DependencyObject child = null;

                List<T> childList = new List<T>();

     

                for (int i = 0; i <= VisualTreeHelper.GetChildrenCount(obj) - 1; i++)

                {

                    child = VisualTreeHelper.GetChild(obj, i);

     

                    if (child is T)

                    {

                        childList.Add((T)child);

                    }

     

                    childList.AddRange(GetChildren<T>(child));

                }

     

                return childList;

     

            }

     

     

    为什么有的子控件找不到.

    我自己定义控件

     

    <UserControl x:Class="Donata_DineClient.TabItemDishes"

                 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

                 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 

                 xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 

                 mc:Ignorable="d" 

                 d:DesignHeight="300" d:DesignWidth="300">

        <Grid>

            <ItemsControl Name="dishItems" ItemsSource="{Binding Path=所属餐品}">

                <ItemsControl.Template>

                    <ControlTemplate TargetType="ItemsControl">

                        <Border CornerRadius="5" BorderBrush="Blue" BorderThickness="3">

                            <ScrollViewer>

                                <ItemsPresenter />

                            </ScrollViewer>

                        </Border>

                    </ControlTemplate>

                </ItemsControl.Template>

                <ItemsControl.ItemsPanel>

                    <ItemsPanelTemplate>

                        <WrapPanel />

                    </ItemsPanelTemplate>

                </ItemsControl.ItemsPanel>

                <ItemsControl.ItemTemplate>

                    <DataTemplate>

                        <Button Width="auto" AllowDrop="True"  IsEnabled="{Binding Path=启用}" Click="Button_Click">

                            <Button.Template>

                            <ControlTemplate>

                                <Border CornerRadius="5"  BorderBrush="Black" BorderThickness="2" Margin="5,5,5,5">

                                    <StackPanel Orientation="Vertical">

                                        <Label Content="{Binding Path=名称}" Width="100" HorizontalContentAlignment="Center"  Background="{Binding Path=颜色}"/>

                                        <Label Content="{Binding Path=单价}"  Width="100" HorizontalContentAlignment="Center"   Background="{Binding Path=颜色}"/>

                                    </StackPanel>

                                </Border>

                            </ControlTemplate>

                            </Button.Template>

                        </Button>

                    </DataTemplate>

                </ItemsControl.ItemTemplate>

            </ItemsControl>

        </Grid>

    </UserControl>

     

     

     

    窗体里有个TabControl控件,运行的时候会动态添加TabItem,每个TabItem的ControlPresent就是自定义的控件

    下面是添加TabItem的代码

     

    dishService=new CHessianProxyFactory().Create<IDishService>(string.Format("http://{0}:8081/ssDishService",config.堂食服务器地址));

     orderService=new CHessianProxyFactory().Create<IOrderService>(string.Format("http://{0}:8081/ssOrderService",config.堂食服务器地址));

     

                var list=dishService.getAllDishTypes();

                list.ForEach(item =>

                    {

                        var tabItem = new TabItem

                        {

                            Header = item.名称

                        };

                        tabItem.Content = new TabItemDishes

                        {

                            ButtonClick = (bs, be) =>

                            {

     

                            }

                        };

                        item.service = dishService;

                        tabItem.DataContext = item;

                        // item.DataContext = dishService.getDishesByTypeId(t.编号);

                        dishTypeTabs.Items.Add(tabItem); //为TabControl添加TabItem

                    }

                );

     

    为什么通过GetChildren<TabItem>(this)可以找到所有的TabItem

    但是用GetChildren<Button>(某个TabItem)却什么也找不到

     

     


    skytouch
    2011年5月16日 14:44

答案

  • 当一个Element的Visibility为Collapsed时,  他的Template不会被应用.. Child也不会被加载到视觉树上..

    所以从非当前TabItem查找Button是找不到的...因为这是Button还没被加载到视觉树上..

    你可以用Snoop看看


    just another day.
    2011年5月17日 11:01
  • 你好,

    对KA_KA07的建议有点小补充:

    TabControl中不仅仅是Visibility的问题。TabItem的Content并不存在于TabItem的VisualTree中。 TabItem本身只加载Header. 只有当一个TabItem在TabControl中被选中时,才会由TabControl把这个TabItem的Content加载到TabControl的VisualTree中。 所以只有当前被选中的TabItem的Content才会出现在VisualTree中。


    Min Zhu [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    2011年5月19日 5:02
    版主

全部回复

  • 当一个Element的Visibility为Collapsed时,  他的Template不会被应用.. Child也不会被加载到视觉树上..

    所以从非当前TabItem查找Button是找不到的...因为这是Button还没被加载到视觉树上..

    你可以用Snoop看看


    just another day.
    2011年5月17日 11:01
  • 你好,

    对KA_KA07的建议有点小补充:

    TabControl中不仅仅是Visibility的问题。TabItem的Content并不存在于TabItem的VisualTree中。 TabItem本身只加载Header. 只有当一个TabItem在TabControl中被选中时,才会由TabControl把这个TabItem的Content加载到TabControl的VisualTree中。 所以只有当前被选中的TabItem的Content才会出现在VisualTree中。


    Min Zhu [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    2011年5月19日 5:02
    版主
  • 原来如此,只能找当前的选中的tabitem 中的button,看来要改变程序的思路啊
    skytouch
    2011年5月19日 13:07