VisualTreeHelper.GetChildrenCount返回0? [英] VisualTreeHelper.GetChildrenCount return 0?

查看:361
本文介绍了VisualTreeHelper.GetChildrenCount返回0?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我用 VisualTreeHelper.GetChildrenCount()找到的子控件,但它始终返回0。



这是我的代码

 <的ScrollViewer X:NAME =scrollViewerChannelsRecordTimeData> 
< StackPanel的X:名称=channelsRecordTimeData>
< ItemsControl的X:名称=channelRecordTimeItems的ItemsSource ={结合}>
< ItemsControl.ItemTemplate>
<&DataTemplate的GT;
<电网X:NAME =hoursLines>
//某些控件这里
< /网格和GT;
< / DataTemplate中>
< /ItemsControl.ItemTemplate>
< / ItemsControl的>
< / StackPanel的>
< /&的ScrollViewer GT;



C#代码:

  channelRecordTimeItems.ItemContainerGenerator.StatusChanged + = ChannelRecordTimeItemsStatusChangedEventHandler; 
私人无效ChannelRecordTimeItemsStatusChangedEventHandler(对象发件人,EventArgs五)
{
如果(channelRecordTimeItems.ItemContainerGenerator.Status == GeneratorStatus.ContainersGenerated)
{
如果(channelRecordTimeItems.HasItems )
{
的DependencyObject的DependencyObject = NULL;
电网gridHighlightRecordData = NULL;
的for(int i = 0; I< channelRecordTimeItems.Items.Count;我++)
{
的DependencyObject = channelRecordTimeItems.ItemContainerGenerator.ContainerFromIndex(I) !//的DependencyObject = NULL
如果(DependencyObject的!= NULL)
{
电网hoursLines = FindElement.FindChild<网格和GT;(DependencyObject的hoursLines); // hoursLines = NULL
}
}
}
}
}

公共静态牛逼FindChild< T>(DependencyObject的父母,串childName)
,其中T:DependencyObject的
{
//确认家长和childName是有效的。
如果(家长== NULL)返回NULL;
$ B $(B T)foundChild = NULL;

INT childrenCount = VisualTreeHelper.GetChildrenCount(父); //返回0这里
的for(int i = 0; I< childrenCount;我++)
{
VAR孩子= VisualTreeHelper.GetChild(父母,我);
//如果孩子要求孩子类型的子$ B $(B T)= childType孩子一样的T没有;
如果(childType == NULL)
{
//递归钻到树
foundChild = FindChild< T>(儿童,childName);

//如果孩子被发现,打破所以我们没有覆盖找到孩子。
如果(foundChild!= NULL)破;
}
,否则如果(string.IsNullOrEmpty(childName)!)
{
VAR FrameworkElement的=孩子一样FrameworkElement的;
//如果孩子的名字设置为搜索
如果(FrameworkElement的= NULL&放大器;!&安培; frameworkElement.Name == childName)
{
//如果孩子的名字是请求名称
foundChild =(T)的孩子;
中断;
}
}
,否则
{发现
//子元素。
foundChild =(T)的孩子;
中断;
}
}

返回foundChild;
}



VisualTreeHelper.GetChildrenCount()总是返回0,



在这里建造的项目的代码

 列表与LT; ChannelRecordTimeItemData> listChannelRecordTimeItemData =新的List< ChannelRecordTimeItemData>(); 
的for(int i = 0;我小于5;我++)
{
ChannelRecordTimeItemData项目=新ChannelRecordTimeItemData();
listChannelRecordTimeItemData.Add(ChannelRecordTimeItemData);
}
channelRecordTimeItems.ItemsSource = listChannelRecordTimeItemData;
channelRecordTimeItems.Items.Refresh();



我已经搜索论坛上和互联网,但我解决不了的,有人能帮助我吗?< !/ p>

非常感谢



T& T公司


解决方案

现在的问题是,当 ItemContainerGenerator 信号的 ContainersGenerated 状态,容器(一 ContentPresenter )已被创建,但尚未加载。尤其是数据模板还没有被应用到ContentPresenter,因此,没有任何可视化树。



您可以解决这个问题通过增加一个对生成的容器循环时加载事件处理程序。

 私人无效ItemContainerGeneratorStatusChanged(对象发件人,EventArgs E)
{
如果(itemsControl.ItemContainerGenerator.Status
== GeneratorStatus.ContainersGenerated)
{
VAR容器= itemsControl.Items.Cast<对象>() 。选择(
项=>(FrameworkElement的)的ItemsControl
.ItemContainerGenerator.ContainerFromItem(项目));

的foreach(集装箱变种容器)
{
container.Loaded + = ItemContainerLoaded;
}
}
}

私人无效ItemContainerLoaded(对象发件人,RoutedEventArgs E)
{
VAR元素=(FrameworkElement的)寄件人;
element.Loaded - = ItemContainerLoaded;

VAR电网= VisualTreeHelper.GetChild(元素,0)为网格;

}


I'm using VisualTreeHelper.GetChildrenCount() to find child controls, but it always return 0.

Here is my code

<ScrollViewer x:Name="scrollViewerChannelsRecordTimeData">
    <StackPanel x:Name="channelsRecordTimeData">
        <ItemsControl x:Name="channelRecordTimeItems" ItemsSource="{Binding}">
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <Grid x:Name="hoursLines">
                        //Some Controls here                            
                    </Grid>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>
    </StackPanel>
</ScrollViewer>   

C# code:

channelRecordTimeItems.ItemContainerGenerator.StatusChanged += ChannelRecordTimeItemsStatusChangedEventHandler;
private void ChannelRecordTimeItemsStatusChangedEventHandler(Object sender, EventArgs e)
{
    if (channelRecordTimeItems.ItemContainerGenerator.Status == GeneratorStatus.ContainersGenerated)
    {
        if (channelRecordTimeItems.HasItems)
        {
            DependencyObject dependencyObject = null;
            Grid gridHighlightRecordData = null;
            for (int i = 0; i < channelRecordTimeItems.Items.Count; i++)
            {
                dependencyObject = channelRecordTimeItems.ItemContainerGenerator.ContainerFromIndex(i); //dependencyObject != null
                 if (dependencyObject != null)
                 {
                    Grid hoursLines = FindElement.FindChild<Grid>(dependencyObject, "hoursLines"); //hoursLines = null
                 }
            }
        }
    }
}

public static T FindChild<T>(DependencyObject parent, string childName)
   where T : DependencyObject
{
    // Confirm parent and childName are valid. 
    if (parent == null) return null;

    T foundChild = null;

    int childrenCount = VisualTreeHelper.GetChildrenCount(parent); //Return 0 here
    for (int i = 0; i < childrenCount; i++)
    {
        var child = VisualTreeHelper.GetChild(parent, i);
        // If the child is not of the request child type child
        T childType = child as T;
        if (childType == null)
        {
            // recursively drill down the tree
            foundChild = FindChild<T>(child, childName);

            // If the child is found, break so we do not overwrite the found child. 
            if (foundChild != null) break;
        }
        else if (!string.IsNullOrEmpty(childName))
        {
            var frameworkElement = child as FrameworkElement;
            // If the child's name is set for search
            if (frameworkElement != null && frameworkElement.Name == childName)
            {
                // if the child's name is of the request name
                foundChild = (T)child;
                break;
            }
        }
        else
        {
            // child element found.
            foundChild = (T)child;
            break;
        }
    }

    return foundChild;
}

VisualTreeHelper.GetChildrenCount() always return 0,

The code for constructing for items here

List<ChannelRecordTimeItemData> listChannelRecordTimeItemData = new List<ChannelRecordTimeItemData>();
for(int i = 0; i < 5; i++)
{
    ChannelRecordTimeItemData item = new ChannelRecordTimeItemData();
    listChannelRecordTimeItemData.Add(ChannelRecordTimeItemData);
}
channelRecordTimeItems.ItemsSource = listChannelRecordTimeItemData;
channelRecordTimeItems.Items.Refresh();

I have searched on forum and internet, but i can not solve it, someone can help me?

Many thanks!

T&T

解决方案

The problem is that when the ItemContainerGenerator signals the ContainersGenerated status, the container (a ContentPresenter) has been created, but not yet loaded. Especially the data template has not yet been applied to the ContentPresenter, hence there is nothing in the visual tree.

You may get around this by adding a Loaded event handler when looping over the generated containers.

private void ItemContainerGeneratorStatusChanged(object sender, EventArgs e)
{
    if (itemsControl.ItemContainerGenerator.Status
        == GeneratorStatus.ContainersGenerated)
    {
        var containers = itemsControl.Items.Cast<object>().Select(
            item => (FrameworkElement)itemsControl
                .ItemContainerGenerator.ContainerFromItem(item));

        foreach (var container in containers)
        {
            container.Loaded += ItemContainerLoaded;
        }
    }
}

private void ItemContainerLoaded(object sender, RoutedEventArgs e)
{
    var element = (FrameworkElement)sender;
    element.Loaded -= ItemContainerLoaded;

    var grid = VisualTreeHelper.GetChild(element, 0) as Grid;
    ...
}

这篇关于VisualTreeHelper.GetChildrenCount返回0?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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