C# VisualTreeHelper.GetChildrenCount返回0?

C# VisualTreeHelper.GetChildrenCount返回0?,c#,wpf,C#,Wpf,我正在使用VisualTreeHelper.GetChildrenCount()查找子控件,但它总是返回0 这是我的密码 <ScrollViewer x:Name="scrollViewerChannelsRecordTimeData"> <StackPanel x:Name="channelsRecordTimeData"> <ItemsControl x:Name="channelRecordTimeItems" ItemsSource=

我正在使用
VisualTreeHelper.GetChildrenCount()
查找子控件,但它总是返回0

这是我的密码

<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>   
我已经在论坛和互联网上搜索过了,但我不能解决它,有人能帮我吗

非常感谢


T&T

问题在于,当
ItemContainerGenerator
发出
ContainerGenerated
状态信号时,容器(一个
ContentPresenter
)已创建,但尚未加载。尤其是数据模板尚未应用于ContentPresenter,因此可视化树中没有任何内容

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

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;
    ...
}
private void ItemContainerGeneratorStatusChanged(对象发送方,事件参数e)
{
if(itemsControl.ItemContainerGenerator.Status
==生成器状态。容器已生成)
{
var containers=itemsControl.Items.Cast().Select(
item=>(FrameworkElement)itemsControl
.ItemContainerGenerator.ContainerFromItem(item));
foreach(容器中的var容器)
{
container.Loaded+=ItemContainerLoaded;
}
}
}
私有void ItemContainerLoaded(对象发送方,RoutedEventArgs e)
{
var元素=(FrameworkElement)发送方;
element.Loaded-=ItemContainerLoaded;
var grid=visualtreeheloper.GetChild(元素,0)作为网格;
...
}

如果您使用Caliburn.Micro,这将对您有所帮助。 对于您的Viewmodel,基类应该是Screen,然后只有VisualTreeHelper.GetChildrenCount()给出了Child的数量。(因为Screen将激活所有Child。)


否则(FrameworkElement)您的父级.ApplyTemplate()方法

您能解释这个绑定吗,ItemsSource=“{binding}”?我想你应该在这里绑定你的集合属性。谢谢,我已经为上面的项目添加了构建代码。你是否在XAML和code behind中绑定了ItemsControl两次?我尝试了你的代码,它对我来说非常有效。它会查找并返回网格小时线。@Nitesh:在哪里调用查找网格小时线的函数?如果我在按钮事件单击中调用它,它工作得很好。但是如果我在StatusChanged事件中调用它,那么它就找不到网格小时线。
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();
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;
    ...
}