ユーザーが移動できるようにしようとしてTreeViewItems
いますTreeView
(具体的には、コントロールを押しながら矢印キーを押すことによって)。ノードを他のノードに移動したり、他のノードから移動したり、トップ レベルでノードを上下に移動したりできますが、サブノード内でノードを上に移動しようとしても何も起こりません。次の例外が発生します。
要素にはすでに論理的な親があります。新しい親にアタッチする前に、古い親からデタッチする必要があります。
これは、ノードを元のコレクションに追加しようとしたときに発生します (もちろん削除した後)。元の実装は次のとおりです。
private TreeViewItem getParent(TreeViewItem item)
{
for (int i=0; i<fragment_tree.Items.Count; ++i)
{
TreeViewItem r = getParent((TreeViewItem)(fragment_tree.Items[i]), item);
if (r != null)
{
return r;
}
}
return null;
}
private TreeViewItem getParent(TreeViewItem test, TreeViewItem item)
{
for (int i=0; i<test.Items.Count; ++i)
{
if (test.Items[i] == item)
{
return test;
}
}
for (int i=0; i<test.Items.Count; ++i)
{
TreeViewItem r = getParent((TreeViewItem)(test.Items[i]), item);
if (r != null)
{
return r;
}
}
return null;
}
private ItemCollection getContainingList(TreeViewItem item, out int id)
{
return getContainingList(fragment_tree.Items, item, out id);
}
private ItemCollection getContainingList(ItemCollection test, TreeViewItem item, out int id)
{
for (int i=0; i<test.Count; ++i)
{
if (test[i] == item)
{
id = i;
return test;
}
}
for (int i=0; i<test.Count; ++i)
{
ItemCollection r = getContainingList((TreeViewItem)(test[i]), out id);
if (r != null)
{
return r;
}
}
id = -1;
return null;
}
private void fragment_tree_PreviewKeyDown(object sender, KeyEventArgs e)
{
TreeViewItem selected_item = (TreeViewItem)(fragment_tree.SelectedItem);
if (selected_item.Header is String)
{
if (e.KeyboardDevice.IsKeyDown(Key.LeftCtrl) || e.KeyboardDevice.IsKeyDown(Key.RightCtrl))
{
if (e.Key == Key.Up)
{
int id;
ItemCollection collection = getContainingList(selected_item, out id);
if (collection != null) // it'll never be null, but w/e
{
if (id > 0)
{
collection.RemoveAt(id);
collection.Insert(id-1, selected_item);
selected_item.IsSelected = true;
}
}
e.Handled = true;
}
else if (e.Key == Key.Down)
{
int id;
ItemCollection collection = getContainingList(selected_item, out id);
if (collection != null) // it'll never be null, but w/e
{
if (id < collection.Count)
{
collection.RemoveAt(id);
collection.Insert(id+1, selected_item); // here is the exception
selected_item.IsSelected = true;
}
}
e.Handled = true;
}
else if (e.Key == Key.Left)
{
TreeViewItem parent = getParent(selected_item);
if (parent != null)
{
int id;
ItemCollection collection = getContainingList(parent, out id);
parent.Items.RemoveAt(id);
collection.Insert(id, selected_item);
selected_item.IsSelected = true;
}
e.Handled = true;
}
else if (e.Key == Key.Right)
{
int id;
ItemCollection collection = getContainingList(selected_item, out id);
if (id+1 < collection.Count)
{
TreeViewItem next_item = (TreeViewItem)(collection[id+1]);
collection.RemoveAt(id);
next_item.Items.Insert(0, selected_item);
next_item.IsExpanded = true;
selected_item.IsSelected = true;
}
e.Handled = true;
}
}
}
選択したものの深いクローンを作成しようとしましたがTreeViewItem
(オーバーヘッドが発生したくないのですが)、奇妙な動作が発生しました。サブツリー内で項目を上下に移動しようとすると、親に飛び出します。最上位のノードを上下に移動しようとすると、隣接するノードが削除されます。根本的な何かが欠けているように感じる
private TreeViewItem cloneTreeViewItem(TreeViewItem item)
{
TreeViewItem r = new TreeViewItem();
r.Header = item.Header;
r.Tag = item.Tag;
for (int i=0; i<item.Items.Count; ++i)
{
r.Items.Add(cloneTreeViewItem((TreeViewItem)(item.Items[i])));
}
return r;
}
....
if (e.Key == Key.Up)
{
int id;
ItemCollection collection = getContainingList(selected_item, out id);
if (collection != null) // it'll never be null, but w/e
{
if (id > 0)
{
collection.RemoveAt(id);
TreeViewItem clone = cloneTreeViewItem(selected_item);
collection.Insert(id-1, clone);
clone.IsSelected = true;
}
}
e.Handled = true;
}
else if (e.Key == Key.Down)
{
int id;
ItemCollection collection = getContainingList(selected_item, out id);
if (collection != null) // it'll never be null, but w/e
{
if (id < collection.Count)
{
collection.RemoveAt(id);
TreeViewItem clone = cloneTreeViewItem(selected_item);
collection.Insert(id+1, clone);
clone.IsSelected = true;
}
}
e.Handled = true;
}
.....
私はこのトピックを調査するのに少なくとも 1 時間費やしTreeViewItem
ましTreeViewItem
たTreeView
。あなたがこのサイトにくだらない質問をしないように努めていることは知っていますが、私の質問がそうでないことを願っています。任意の洞察をいただければ幸いです。