wpf VisualTreeHelper.GetChildrenCount 返回 0?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17894506/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
VisualTreeHelper.GetChildrenCount return 0?
提问by TTGroup
I'm using VisualTreeHelper.GetChildrenCount()to find child controls, but it always return 0.
我正在使用VisualTreeHelper.GetChildrenCount()查找子控件,但它总是返回 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:
C#代码:
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,
VisualTreeHelper.GetChildrenCount()总是返回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
电讯报
回答by Clemens
The problem is that when the ItemContainerGeneratorsignals the ContainersGeneratedstatus, 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.
问题是,当ItemContainerGenerator发出ContainersGenerated状态信号时,容器 (a ContentPresenter) 已创建,但尚未加载。特别是数据模板还没有应用到ContentPresenter,因此可视化树中没有任何内容。
You may get around this by adding a Loadedevent handler when looping over the generated containers.
您可以通过Loaded在循环生成的容器时添加事件处理程序来解决此问题。
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;
...
}
回答by raghava arr
If your using Caliburn.Micro this will help you. For your Viewmodel the base Class should be Screen then only VisualTreeHelper.GetChildrenCount() give no.of childs.(because Screen will Activate all childs
如果您使用 Caliburn.Micro,这将对您有所帮助。对于您的 Viewmodel,基类应该是 Screen 然后只有 VisualTreeHelper.GetChildrenCount() 给 no.of childs。(因为 Screen 将激活所有 childs
or otherwise (FrameworkElement)YourParent).ApplyTemplate() method
否则 (FrameworkElement)YourParent).ApplyTemplate() 方法

