TreeView+SearchField,以及双击,重命名,Delete键删除,搜索过滤的使用


 # 展示TreeView的窗口

class SimpleTreeView2Window : EditorWindow
{
    [MenuItem("TreeView Examples/Simple Tree View Window2")]
    static void ShowWindow()
    {
        var window = GetWindow();
        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();
        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显示。

# 搜索过滤效果

相关