首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >WPF无法使ItemContainerGenerator.ContainerFromItem工作

WPF无法使ItemContainerGenerator.ContainerFromItem工作
EN

Stack Overflow用户
提问于 2013-12-31 22:06:55
回答 2查看 5.1K关注 0票数 2

我看过herehere以及许多其他地方,但我似乎无法让ItemContainerGenerator.ContainerFromItem方法在WPF TreeView上工作!我试图传递我想要看到的实际项目,但是没有取得任何进展,我只是尝试在我的TreeView中获得第一个项目。下面是我的示例代码:

代码语言:javascript
复制
private static bool ExpandAndSelectItem(ItemsControl parentContainer, object itemToSelect)
{
    // This doesn't work.
    parentContainer.BringIntoView();
    // May be virtualized, bring into view and try again.
    parentContainer.UpdateLayout();
    parentContainer.ApplyTemplate();

    TreeViewItem topItem = (TreeViewItem)parentContainer.ItemContainerGenerator.ContainerFromItem(parentContainer.Items[0]);

    // Can't find child container unless the parent node is Expanded once
    if ((topItem != null) && !topItem.IsExpanded) 
    {
        topItem.IsExpanded = true;
        parentContainer.UpdateLayout();
    }
}

如您所见,我试图调用许多“更新”方法,以使TreeView成为“可见的”和“可访问的”。问题是,除非第一个ContainerFromItem()是展开的,否则您就不能使用TreeViewItem,但是在ContainerFromItem()工作之前,我无法抓取TreeViewItem来扩展它!

另一件有趣的事情是:当我打开这个窗口(它是一个UserControl)时,ContainerFromItem()返回空,但是如果我关闭窗口并重新打开它,ContainerFromItem()将开始返回非空。有什么事件我应该寻找或强迫开火吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-01-02 23:07:45

原来我要找的那件事是“装好的”。我只是在XAML中将一个事件处理程序附加到我的treeview上,并在该事件处理程序中调用了我的逻辑。

代码语言:javascript
复制
<TreeView x:Name="MyTreeView"
          Margin="0,5,0,5"
          HorizontalAlignment="Left"
          BorderThickness="0"
          FontSize="18"
          FontFamily="Segoe WP"
          MaxWidth="900"
          Focusable="True"
          Loaded="MyTreeView_Load">
    ...
</TreeView>

事件处理程序:

代码语言:javascript
复制
private void MyTreeView_Load(object sender, RoutedEventArgs e)
{
    ShowSelectedThing(MyTreeView, ThingToFind);
}
// Gotta call the TreeView an ItemsControl to cast it between TreeView and TreeViewItem
// as you recurse
private static bool ShowSelectedThing(ItemsControl parentContainer, object ThingToFind)
{
    // check current level of tree
    foreach (object item in parentContainer.Items)
    {
        TreeViewItem currentContainer = (TreeViewItem)parentContainer.ItemContainerGenerator.ContainerFromItem(item);
        if ((currentContainer != null) && (item == ThingToFind)
        {
            currentContainer.IsSelected = true;
            currentContainer.BringIntoView();
            return true;
        }
    }
    // item is not found at current level, check the kids
    foreach (object item in parentContainer.Items)
    {
        TreeViewItem currentContainer = (TreeViewItem)parentContainer.ItemContainerGenerator.ContainerFromItem(item);
        if ((currentContainer != null) && (currentContainer.Items.Count > 0))
        {
            // Have to expand the currentContainer or you can't look at the children
            currentContainer.IsExpanded = true;
            currentContainer.UpdateLayout();
            if (!ShowSelectedThing(currentContainer, ThingToFind))
            {
                // Haven't found the thing, so collapse it back
                currentContainer.IsExpanded = false;
            }
            else
            {
                // We found the thing
                return true;
            }
        }
    }
    // default
    return false;
}

希望这能帮上忙。有时候在现实世界里,有着苛刻的客户,奇怪的要求和很短的截止时间,你必须要黑!

票数 4
EN

Stack Overflow用户

发布于 2017-07-18 08:27:15

当容器生成器的状态为“NotStarted”或“ContainersGenerating”时,您将找不到容器。

使用此方法查找数据项的容器。

代码语言:javascript
复制
    private static async Task<TreeViewItem> FindItemContainer(ItemsControl itemsControl, object item)
    {
        var generator = itemsControl.ItemContainerGenerator;
        if (generator.Status != GeneratorStatus.ContainersGenerated)
        {
            var tcs = new TaskCompletionSource<object>();
            EventHandler handler = null;
            handler = (s, e) =>
            {
                if (generator.Status == GeneratorStatus.ContainersGenerated)
                {
                    generator.StatusChanged -= handler;
                    tcs.SetResult(null);
                }
                else if (generator.Status == GeneratorStatus.Error)
                {
                    generator.StatusChanged -= handler;
                    tcs.SetException(new InvalidOperationException());
                }
            };
            generator.StatusChanged += handler;
            if (itemsControl is TreeViewItem tvi)
                tvi.IsExpanded = true;
            itemsControl.UpdateLayout();
            await tcs.Task;
        }

        var container = (TreeViewItem)generator.ContainerFromItem(item);
        if(container == null)
        {
            foreach (var parentItem in itemsControl.Items)
            {
                var parentContainer = (TreeViewItem)generator.ContainerFromItem(parentItem);
                container = await FindItemContainer(parentContainer, item);
                if (container != null)
                    return container;
            }
        }
        return container;
    }
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20863666

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档