Tôi có một lớp con của System.Windows.Forms.TreeView
được gắn "thủ công" theo cách thủ công vào một tập hợp dữ liệu phân cấp. Tôi muốn người dùng có thể chỉnh sửa nhãn của cây và thay đổi được phản ánh lại dữ liệu. Vì vậy, tôi đặt LabelEdit
true và overrode OnAfterLabelEdit
theo giai điệu của:Tôi có thể chèn các nút vào một TreeView trong AfterLabelEdit mà không cần chỉnh sửa chúng không?
protected override void OnAfterLabelEdit(NodeLabelEditEventArgs e)
{
base.OnAfterLabelEdit(e);
TreeNode node = e.Node;
if (PassesSomeValidation(e.Label))
{
MyDataNode dataNode = node.Tag as MyDataNode;
dataNode.SomeBoundValue = e.Label;
int oldIndex = node.Index;
int newIndex = RepositionChangedDataNode(dataNode);
TreeNode parent = node.Parent;
parent.Nodes.RemoveAt(oldIndex);
parent.Nodes.Insert(newIndex, node);
}
else
{
e.CancelEdit = true;
}
}
RepositionChangedDataNode()
tái sắp xếp các dữ liệu và trả về chỉ số vào mà nút thay đổi di chuyển sau khi phân loại. Tôi đã hy vọng tôi chỉ có thể di chuyển nút đã chỉnh sửa để phản ánh động thái này.
Vấn đề là điều này làm cho nút thành ở chế độ chỉnh sửa! Tôi đã thử gọi số EndEdit()
, nhân bản nút trước khi chèn, thiết lập LabelEdit
thành sai và trả về true, gói thay đổi trong BeginUpdate()
/EndUpdate()
và các kết hợp khác nhau của những ý tưởng này, nhưng không có ý tưởng nào có hiệu lực.
Thủ phạm có vẻ là sự chèn. Ngay cả khi tôi cố gắng chèn một nút hoàn toàn mới mới, nút này sẽ chuyển sang chế độ chỉnh sửa ngay lập tức.
Vì vậy, có cách nào để làm cho TreeView
không hoạt động theo cách này không? Và nếu không, liệu có cách giải quyết tốt không?
Một số ý tưởng tôi đã xem xét:
- Đặt một TreeViewNodeSorter tùy chỉnh. Tuy nhiên, không muốn phải sắp xếp dữ liệu của tôi hai lần.
- Đặt cờ và trì hoãn bước xóa-chèn cho đến một số điểm sau AfterLabelEdit. Nó hoạt động để làm điều đó trong WndProc, nhưng điều này cảm thấy giống như một kludge lớn có khả năng thất bại bằng cách nào đó.
Sử dụng
BeginInvoke()
để đẩy bước remove-chèn lại vào hàng đợi thông báo như vậy:BeginInvoke(new MethodInvoker(delegate( { parent.Nodes.RemoveAt(oldIndex); parent.Nodes.Insert(newIndex, node); }));
này hoạt động và có vẻ sạch hơn với tôi hơn # 2, nhưng tôi biết điều này có lẽ không phải là cách
BeginInvoke()
được dự định được sử dụng, và nó có thể có hậu quả mà kiến thức rất hạn chế của tôi về máy bơm tin nhắn không thể dự đoán được.
Tôi gặp vấn đề tương tự - bạn đã làm gì? – Handleman
Đã quen với ý tưởng số 3 trong thời gian này. Dường như làm việc tốt cho đến nay. –
Tôi chỉ có một vấn đề tương tự khi cố gắng sắp xếp TreeView trong sự kiện AfterLabelEdit. Tôi đã sử dụng một giải pháp tương tự như của bạn, và nó hoạt động tốt. Đó có thể là một lỗi trong TreeView ... –