TreeView+SearchField,以及双击,重命名,Delete键删除,搜索过滤的使用
# 展示TreeView的窗口
class SimpleTreeView2Window : EditorWindow { [MenuItem("TreeView Examples/Simple Tree View Window2")] static void ShowWindow() { var window = GetWindow<SimpleTreeView2Window>(); window.titleContent = new GUIContent("My Window"); window.Show(); } SearchField _searchField; SimpleTreeView2 _tableView; TreeViewState _treeViewState; private void OnEnable() { if (null == _treeViewState) _treeViewState = new TreeViewState(); //单独用一个类, 以便于序列化状态 _tableView = new SimpleTreeView2(_treeViewState); _searchField = new SearchField(); _searchField.downOrUpArrowKeyPressed += _tableView.SetFocusAndEnsureSelectedItem; } private void OnGUI() { var xMargin = 10; var yMargin = 10; var searchBarHeight = 20; _tableView.searchString = _searchField.OnGUI(new Rect(xMargin, yMargin, position.width - xMargin * 2, searchBarHeight), _tableView.searchString); var rect = new Rect(xMargin, yMargin + searchBarHeight, position.width - xMargin * 2, position.height - searchBarHeight - yMargin * 2); _tableView.OnGUI(rect); } }
#TreeView
(#) DoubleClickedItem处理双击
(#) KeyEvent处理Delete键
(#) DoesItemMatchSearch处理搜索过滤
(#) CanRename和RenameEnded处理重命名
class SimpleTreeView2 : TreeView { private Dictionary<int, string> _testDatas; public SimpleTreeView2(TreeViewState state) : base(state) { CreateTestData(); //customFoldoutYOffset = 15; showAlternatingRowBackgrounds = true; //隔行显示颜色 showBorder = true; //表格边框 Reload(); } void CreateTestData() { _testDatas = new Dictionary<int, string>(); for (var id = 0; id < 10; ++id) { _testDatas.Add(id, $"id_{id}"); } } protected override TreeViewItem BuildRoot() { var rootTreeViewItem = new TreeViewItem(-1, -1); //root的depth必须为-1 var rows = new List<TreeViewItem>(); foreach (var entry in _testDatas) { var id = entry.Key; var displayName = entry.Value; var depth = id % 3; rows.Add(new TreeViewItem(id, depth, displayName)); } SetupParentsAndChildrenFromDepths(rootTreeViewItem, rows); //根据depth自动调整TreeViewItem间的父子关系 return rootTreeViewItem; } protected override void DoubleClickedItem(int id) { var treeViewItem = FindItem(id, rootItem); if (null != treeViewItem) { Debug.Log($"双击了: {treeViewItem.displayName}"); } } protected override void KeyEvent() { if (Event.current.type == EventType.KeyUp && Event.current.keyCode == KeyCode.Delete) { var needReload = false; var selectionIds = GetSelection(); foreach (var id in selectionIds) { Debug.Log($"key delete: {id}"); needReload |= _testDatas.Remove(id); } if (needReload) Reload(); } } protected override bool DoesItemMatchSearch(TreeViewItem item, string search) { return item.displayName.IndexOf(search, StringComparison.OrdinalIgnoreCase) >= 0; } protected override bool CanRename(TreeViewItem item) { Rect renameRect = GetRenameRect(treeViewRect, 0, item); return renameRect.width > 150; } protected override void RenameEnded(RenameEndedArgs args) { if (args.acceptedRename) { Debug.Log($"RenameEnded: itemID:{args.itemID}, {args.originalName} => {args.newName}"); if (_testDatas.ContainsKey(args.itemID)) { _testDatas[args.itemID] = args.newName; Reload(); } } } }
# 重命名效果,注意:这边设置了行宽度大于150时才能重命名,所以窗口宽度拉的太小的时候就不让重命名。
还有就是重命名只支持行,如果每行有多个列,无法在行1列1,行1列2分别显示重命名框,要么只能在行1列1显示,要么只能在行1列2显示,要么只能整个行1显示。
# 搜索过滤效果
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!