0

ユーザーがボタンをクリックするだけですべてのノードを展開および折りたたむことができる機能を TreeView に追加しようとしています。ExpandSubTree を使用すると、Expand は適切に機能します。何らかの理由で、CollapseSubTree 関数はありません。どうすればこのタスクを成功させることができますか?

これが私の現在の機能です:

private void expand_collapse_children(TreeViewItem tvi, bool expand)
{
    if (tvi.Items.Count > 0)
    {
        foreach (TreeViewItem item in tvi.Items)
        {
            if (expand)
            {
                item.ExpandSubtree();
            }
            else
            {
                expand_collapse_children(item, expand);
                item.IsExpanded = false;
            }
        }
    }
}

注: isExpanded は役に立たない上に半歩です。true の場合は false に設定でき、選択された最高レベル以外は折りたたまれません。

ありがとう!

4

4 に答える 4

1
private static void CollapseRecursive(TreeViewItem item)
{
    // Collapse item if expanded.
    if (item.IsExpanded)
    {
        item.IsExpanded = false;
    }

    // If the item has sub items...
    if (item.Items.Count > 0)
    {
        // ... iterate them...
        foreach (TreeViewItem subItem in item.Items)
        {
            // ... and if they themselves have sub items...
            if (subItem.Items.Count > 0)
            {
                // ... collapse the sub item and its sub items.
                CollapseRecursive(subItem);
            }
        }
    }
}
于 2012-06-07T13:43:56.503 に答える
1

次のようにすべてのノードを展開できTreeViewます (すべてのノードを折りたたむ同様の機能があります)。

foreach (var treeViewItem in MyTreeView.FindVisualDescendants<TreeViewItem>(e => !e.IsExpanded, true)) {
  treeViewItem.IsExpanded = true;
}

FindVisualDescendants便利な拡張メソッドはどこにありますか:

public static IEnumerable<T> FindVisualDescendants<T>(this Visual parent, Func<T, bool> predicate, bool deepSearch) where T : Visual {
  var visualChildren = new List<Visual>();
  var visualChildrenCount = VisualTreeHelper.GetChildrenCount(parent);
  for (var childIndex = 0; childIndex < visualChildrenCount; childIndex++) {
    visualChildren.Add((Visual) VisualTreeHelper.GetChild(parent, childIndex));
  }

  foreach (var child in visualChildren) {
    var typedChild = child as T;
    if ((typedChild != null) && (predicate == null || predicate.Invoke(typedChild))) {
      yield return typedChild;
      if (deepSearch) {foreach (var foundVisual in FindVisualDescendants(child, predicate, true)) {
        yield return foundVisual;
      }
    } else {
      foreach (var foundVisual in FindVisualDescendants(child, predicate, deepSearch)) {
        yield return foundVisual;
      }
    }
  }

  yield break;
}
于 2012-05-17T19:38:43.273 に答える
0

ExpandSubTree興味がある場合は、実際にどのように記述されているかの (Reflector からの) 実装を次に示します。逆に行ってもいいと思います。

public void ExpandSubtree()
{
    ExpandRecursive(this);
}

private static void ExpandRecursive(TreeViewItem item)
{
    if (item != null)
    {
        if (!item.IsExpanded)
        {
            item.SetCurrentValueInternal(IsExpandedProperty, BooleanBoxes.TrueBox);
        }
        item.ApplyTemplate();
        ItemsPresenter presenter = (ItemsPresenter) item.Template.FindName("ItemsHost", item);
        if (presenter != null)
        {
            presenter.ApplyTemplate();
        }
        else
        {
            item.UpdateLayout();
        }
        VirtualizingPanel itemsHost = item.ItemsHost as VirtualizingPanel;
        item.ItemsHost.EnsureGenerator();
        int index = 0;
        int count = item.Items.Count;
        while (index < count)
        {
            TreeViewItem item2;
            if (itemsHost != null)
            {
                itemsHost.BringIndexIntoView(index);
                item2 = (TreeViewItem) item.ItemContainerGenerator.ContainerFromIndex(index);
            }
            else
            {
                item2 = (TreeViewItem) item.ItemContainerGenerator.ContainerFromIndex(index);
                item2.BringIntoView();
            }
            if (item2 != null)
            {
                ExpandRecursive(item2);
            }
            index++;
        }
    }
}
于 2012-05-17T18:59:52.770 に答える
0

ItemHost を取得し、EnsureGenerator を呼び出すには、これらは internal であるため、リフレクションが必要です。

var panel = (Panel)typeof(MultiSelector).InvokeMember("ItemsHost", BindingFlags.NonPublic | BindingFlags.GetProperty | BindingFlags.Instance, null, item, null);

typeof (Panel).InvokeMember("EnsureGenerator", BindingFlags.NonPublic | BindingFlags.InvokeMethod | BindingFlags.Instance, null, panel, null);
于 2013-01-30T15:11:15.833 に答える