我試圖讓用戶圍繞TreeView
移動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;
}
.....
我確實花了至少一個小時研究這個話題,我明白TreeViewItem
必須從它的邏輯父被分離了,我從測試父知道根本TreeViewItem
總是一個TreeView
,我只是不知道如何分離它。我知道你會盡力讓這個網站擺脫無聊的問題,我希望我的網站不是一個。任何洞察力將不勝感激。
whoa whoa whoa ...不必要的,但意大利麪?我只是喜歡自己做事。你能否詳細說明「快速」答案?每個TreeViewItem的父項都是一個TreeView,但TreeView沒有任何子項字段。不過,我會考慮使用ObserableCollection,謝謝 – user1067042