11

標準のWPFツリービューは、複数の選択をサポートしていません。

複数選択をサポートするツリービューをWPFアプリケーションに追加するにはどうすればよいですか?商用製品は問題ありません(私は現在、1つの商用実装を認識しています-http://www.telerik.com/products/wpf/treeview.aspx

4

2 に答える 2

14

以下のコードは問題なく動作し、はるかに単純です。ただし、ツリービュー クラスの非パブリック プロパティ IsSelectionChangeActive を使用するという欠点があります。以下のコード:

private static readonly PropertyInfo IsSelectionChangeActiveProperty 
  = typeof (TreeView).GetProperty
    (
      "IsSelectionChangeActive",
      BindingFlags.NonPublic | BindingFlags.Instance
    );

public static void AllowMultiSelection(TreeView treeView)
{
  if (IsSelectionChangeActiveProperty==null) return;

  var selectedItems = new List<TreeViewItem>();
  treeView.SelectedItemChanged += (a, b) =>
  {
    var treeViewItem = treeView.SelectedItem as TreeViewItem;
    if (treeViewItem == null) return;

    // allow multiple selection
    // when control key is pressed
    if (Keyboard.IsKeyDown(Key.LeftCtrl) || Keyboard.IsKeyDown(Key.RightCtrl))
    {
      // suppress selection change notification
      // select all selected items
      // then restore selection change notifications
      var isSelectionChangeActive = 
        IsSelectionChangeActiveProperty.GetValue(treeView, null);

      IsSelectionChangeActiveProperty.SetValue(treeView, true, null);
      selectedItems.ForEach(item => item.IsSelected = true);

      IsSelectionChangeActiveProperty.SetValue
      (
        treeView, 
        isSelectionChangeActive, 
        null
      );
    }
    else
    {
      // deselect all selected items except the current one
      selectedItems.ForEach(item => item.IsSelected = (item == treeViewItem) );
      selectedItems.Clear();
    }

    if (!selectedItems.Contains(treeViewItem))
    {
      selectedItems.Add(treeViewItem);
    }
    else
    {
      // deselect if already selected
      treeViewItem.IsSelected = false;
      selectedItems.Remove(treeViewItem);
    }
  };

}
于 2011-07-13T16:05:47.577 に答える
0

希望する正確なセマンティクスに応じて、ソリューションは非常に単純になる場合があります。

ツリーのルートがTreeViewプレーン以外の場合、たとえばプレーンの場合、ItemsControlツリー内のすべての TreeViewItems は独立して選択可能になるため、基本的に無料でマルチセレクトを取得できます。したがって、ツリーのルートにItemsControlは a の代わりにan を使用してください。TreeView

このソリューションには、実装が非常に簡単であるという利点があります。次の点で、mattdlong のソリューションとは異なります。

  • 彼のソリューションでは、アイテムがクリックされると他のすべてのアイテムの選択が解除されるため、複数選択するにはアイテムを Ctrl キーを押しながらクリックする必要があります。
  • このソリューションでは、シングル クリックでクリックしたアイテムを選択/選択解除できますが、アイテムをすばやく選択して同時に他のすべての選択を解除する方法はありません。

もう 1 つの違いは、彼のソリューションではキーボード ナビゲーション (矢印キー) がすべての項目の選択を解除するのに対し、このソリューションではキーボード ナビゲーションは項目の選択を解除しないことです。

好みのセマンティクスに基づいて、これらのソリューションから選択する必要があります (シングル クリックで項目を追加するか、Ctrl キーを押しながらクリックして項目を追加するかなど)。Shift-クリックなど、より高度なセマンティクスが必要な場合は、相対的に追加します。

ToggleButtonまたはを含むCheckBox内の任意の場所を使用しItemContainerTemplateて、TreeViewItem のスタイルをカスタマイズすることもできますChecked={Binding IsSelected}。これにより、ユーザーはToggleButtonまたはをクリックして項目を選択できますCheckBox

于 2010-01-19T05:19:00.817 に答える