简体   繁体   English

刷新后展开ViewTree

[英]expand ViewTree after refresh

I have a viewtree that's databound to an xml document, when the document is saved I call refresh on the datacontext and the ViewTree collapses, I really want the viewtree to not collaps, so I'm trying to write a function that unpacks it again. 我有一个与XML文档进行数据绑定的视图树,当文档被保存时,我在datacontext上调用refresh,并且ViewTree折叠,我真的希望视图树不折叠,所以我试图编写一个将其再次解压缩的函数。 Here I'm trying to use the xpath of the xml elements to reach the treeviewitems, however I can only get the root object, I suspect that's because 'ContainerFromItem' requires them to be visibly there rather than logically there? 在这里,我试图使用xml元素的xpath到达treeviewitems,但是我只能得到根对象,我怀疑这是因为'ContainerFromItem'要求它们在可见的位置而不是在逻辑的位置? But I don't know how else to do this. 但是我不知道该怎么做。

This is the method that gets called after the datacontext has been refreshed 这是刷新数据上下文后调用的方法

private void UnpackOpened(object sender, EventArgs e)
{
    foreach (var node in nodes)
    {
        var pathStrings = node.Path.Split('/').ToList();
        pathStrings.RemoveAll(string.IsNullOrEmpty);
        for (int i = 0; i < pathStrings.Count; i++)
        {
            pathStrings[i] = pathStrings[i].Replace("{", "").Replace("}", "");
            pathStrings[i] = pathStrings[i].Replace("[", "|").Replace("]", "");
        }

        ExpandTree(OutlineWindowInstance.TreeItems.ItemContainerGenerator, pathStrings, 0);
    }
}

This is a recursive function that's supposed to traverse all the previously open treeviewitems and expand them in the now refreshed tree. 这是一个递归函数,应该遍历所有先前打开的treeviewitem并将它们扩展到现在刷新的树中。

void ExpandTree(ItemContainerGenerator itemses, List<string> treeNodes, int step)
{
    var name = treeNodes[step].Split('|')[0];
    var number = int.Parse(treeNodes[step].Split('|')[1])-1;
    var selected = itemses.Items.Cast<XmlElement>().Where(x => x.LocalName == name).ToList()[number];
    var selectedItem =((TreeViewItem) 
    //this is the line that is failing to do what I had hoped it would do
    itemses.ContainerFromItem(selected)); 
    if(selectedItem == null) return;
    selectedItem.IsExpanded = true;

    step++; 
    if (treeNodes.Count > step)
    {
        ExpandTree(selectedItem.ItemContainerGenerator, treeNodes, step);
    }
}

So I managed to solve this. 所以我设法解决了这个问题。 First I have a list of all current documents, for this I created the following class, it handles all things that have to do with the nodes for the document it represents 首先,我拥有所有当前文档的列表,为此,我创建了以下类,它处理与它所代表的文档的节点有关的所有事情

public class OpennedDocument
{
    public string DocName { get; set; }
    public List<string> ExpandedNodes;
    public bool IsRefreshing { get; set; }

    public void AddExpandedNode(string path)
    {
        if (IsRefreshing) return; //This stops it from registering a node during automatic expansion (after a refresh)
        ExpandedNodes.RemoveAll(path.Contains);
        ExpandedNodes.Add(path);
    }

    public void RemoveExpandedNode(string path)
    {
        var index = path.LastIndexOf("/", StringComparison.Ordinal);

        if(IsRefreshing)return;
        ExpandedNodes.RemoveAll(x => x.Contains(path));

        path = path.Remove(index);
        if(!string.IsNullOrEmpty(path))
            ExpandedNodes.Add(path);
    }
}

These methods are in the general manager script and ensure that all nodes in the treeview that were open before the refresh is openned again afterwards. 这些方法在General Manager脚本中,并确保树视图中在刷新之前打开的所有节点都在以后再次打开。

private void UnpackOpened(object sender, EventArgs e)
{
    var currentDoc = Documents.SingleOrDefault(x => x.DocName == dte.ActiveDocument.FullName);
    if (currentDoc == null) return;
    currentDoc.IsRefreshing = true;

    for (var index = 0; index < currentDoc.ExpandedNodes.Count; index++)
    {
        var node = currentDoc.ExpandedNodes[index];
        var pathStrings = node.Split('/').ToList();
        pathStrings.RemoveAll(string.IsNullOrEmpty);
        for (int i = 0; i < pathStrings.Count; i++)
        {
            pathStrings[i] = pathStrings[i].Replace("{", "").Replace("}", "");
            pathStrings[i] = pathStrings[i].Replace("[", "|").Replace("]", "");
        }

        ExpandTree(OutlineWindowInstance.TreeItems.ItemContainerGenerator, pathStrings, 0,
            OutlineWindowInstance.TreeItems);
    }

    currentDoc.IsRefreshing = false;
}

void ExpandTree(ItemContainerGenerator itemses, List<string> treeNodes, int step, ItemsControl last)
{
    while (true)
    {
        last.UpdateLayout();
        var name = treeNodes[step].Split('|')[0];
        var number = int.Parse(treeNodes[step].Split('|')[1]) - 1;
        var selected = itemses.Items.Cast<XmlElement>().Where(x => x.LocalName == name).ToList()[number];
        var selectedItem = ((TreeViewItem) itemses.ContainerFromItem(selected));
        if (selectedItem == null) return;
        selectedItem.IsExpanded = true;

        step++;
        if (treeNodes.Count > step)
        {
            itemses = selectedItem.ItemContainerGenerator;
            last = selectedItem;
            continue;
        }
        break;
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM