TreeView用于展示表格
# 展示表格的窗口
class TableViewWindow : EditorWindow { [MenuItem("TreeView Examples/Table View Window")] static void ShowWindow() { var window = GetWindow<TableViewWindow>(); window.titleContent = new GUIContent("My Window"); window.Show(); } TableView _tableView; TreeViewState _treeViewState; MultiColumnHeaderState _multiColHeaderState; private void OnEnable() { if (null == _treeViewState) _treeViewState = new TreeViewState(); //单独用一个类, 以便于序列化状态 _multiColHeaderState = CreateStateWith3Cols(); var multiColHeader = new MultiColumnHeader(_multiColHeaderState); multiColHeader.ResizeToFit(); _tableView = new TableView(_treeViewState, multiColHeader); } private void OnGUI() { var xMargin = 10; var yMargin = 10; var rect = new Rect(xMargin, yMargin, position.width - xMargin * 2, position.height - yMargin * 2); _tableView.OnGUI(rect); } static MultiColumnHeaderState CreateStateWith3Cols() { var columns = new[] { new MultiColumnHeaderState.Column { headerContent = new GUIContent(EditorGUIUtility.FindTexture("FilterByType"), "这里是tooltips"), contextMenuText = "Type", width = 60, minWidth = 50, maxWidth = 100, headerTextAlignment = TextAlignment.Center, autoResize = false, allowToggleVisibility = true, }, new MultiColumnHeaderState.Column { headerContent = new GUIContent("Key"), width = 100, minWidth = 30, headerTextAlignment = TextAlignment.Left, canSort = true, autoResize = false, }, new MultiColumnHeaderState.Column { headerContent = new GUIContent("Value"), width = 200, minWidth = 50, headerTextAlignment = TextAlignment.Right, canSort = true, autoResize = false, }, }; var state = new MultiColumnHeaderState(columns); return state; } }
# 数据类
class RowData { public int id; public string name; public string value; public RowData(int id, string name, string value) { this.id = id; this.name = name; this.value = value; } }
# TreeView用于展示表格,重写BuildRoot和RowGUI。
class TableView : TreeView { Dictionary<int, RowData> _testDatas; public TableView(TreeViewState state, MultiColumnHeader multiColumnHeader) : base(state, multiColumnHeader) { CreateTestData(); rowHeight = 35; showAlternatingRowBackgrounds = true; //隔行显示颜色 showBorder = true; //表格边框 Reload(); } void CreateTestData() { Debug.Log($"CreateTestData"); _testDatas = new Dictionary<int, RowData>(); _testDatas.Add(0, new RowData(0, "n0", "zero")); _testDatas.Add(1, new RowData(1, "n1", "one")); _testDatas.Add(2, new RowData(2, "n2", "two")); _testDatas.Add(3, new RowData(3, "n3", "three")); _testDatas.Add(4, new RowData(4, "n4", "four")); _testDatas.Add(5, new RowData(5, "n5", "five")); _testDatas.Add(6, new RowData(6, "n6", "six")); } protected override TreeViewItem BuildRoot() { var rootTreeViewItem = new TreeViewItem(-1, -1); //root的depth必须为-1 for (var id = 0; id < _testDatas.Count; ++id) { var rowData = _testDatas[id]; var childTreeViewItem = new TreeViewItem(rowData.id, 0, $"dummy_{id}"); rootTreeViewItem.AddChild(childTreeViewItem); } return rootTreeViewItem; } protected override void RowGUI(RowGUIArgs args) { for (var i = 0; i < args.GetNumVisibleColumns(); ++i) { CellGUI(args.GetCellRect(i), args.item, args.GetColumn(i), ref args); } } private void CellGUI(Rect cellRect, TreeViewItem item, int col, ref RowGUIArgs args) { //var kv = _testDatas[item.id]; if (!_testDatas.TryGetValue(item.id, out var cellRowData)) return; CenterRectUsingSingleLineHeight(ref cellRect); //控件的区域居中 switch (col) { case 0: GUI.Label(cellRect, $"{args.row}_id:{item.id}"); break; case 1: GUI.Label(cellRect, $"{cellRowData.name}"); break; case 2: GUI.TextField(cellRect, $"{cellRowData.value}"); break; } } }
# 效果图
【一些tips】
# 如果要用TreeView展示多列,肯定需要重写RowGUI,自己绘制每一列。
# CenterRectUsingSingleLineHeight这个函数的作用是将控件居中,不然会被拉伸。下面就是不调用的效果
# 关于为啥会有TreeViewState和MultiColumnHeaderState这种单独的State类,主要是可以用于序列化界面关闭时的状态,下次再打开时
可以恢复到上次的状态。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性