我有一个viewtree是数据绑定到xml文档,当文档被保存时我在datacontext上调用refresh并且ViewTree崩溃了,我真的希望viewtree不会折叠,所以我正在尝试编写一个解包的函数它再次。 在这里,我试图使用xml元素的xpath来访问treeviewitems,但是我只能得到root对象,我怀疑是因为'ContainerFromItem'要求它们在那里可见而不是逻辑上存在? 但我不知道怎么做。
这是在刷新datacontext后调用的方法
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);
}
}
这是一个递归函数,它应该遍历所有以前打开的treeviewitems并在现在刷新的树中展开它们。
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);
}
}
答案 0 :(得分:0)
所以我设法解决了这个问题。 首先,我有一个所有当前文档的列表,为此我创建了以下类,它处理与它所代表的文档的节点有关的所有事情
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);
}
}
这些方法位于通用管理器脚本中,并确保在刷新之前打开的树视图中的所有节点随后再次打开。
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;
}
}