update table view
新增单元格视图类
This commit is contained in:
@@ -0,0 +1,245 @@
|
||||
#if UNITY_2019_4_OR_NEWER
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using UnityEditor.UIElements;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace YooAsset.Editor
|
||||
{
|
||||
/// <summary>
|
||||
/// Unity2022版本以上推荐官方类:MultiColumnListView组件
|
||||
/// </summary>
|
||||
public class TableView : VisualElement
|
||||
{
|
||||
private readonly Toolbar _toolbar;
|
||||
private readonly ListView _listView;
|
||||
|
||||
private readonly List<TableColumn> _columns = new List<TableColumn>(10);
|
||||
private List<ITableData> _itemsSource;
|
||||
private List<ITableData> _sortingDatas;
|
||||
|
||||
// 排序相关
|
||||
private string _sortingHeaderElement = string.Empty;
|
||||
private bool _descendingSort = true;
|
||||
|
||||
/// <summary>
|
||||
/// 数据源
|
||||
/// </summary>
|
||||
public List<ITableData> itemsSource
|
||||
{
|
||||
get
|
||||
{
|
||||
return _itemsSource;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (CheckItemsSource(value))
|
||||
{
|
||||
_itemsSource = value;
|
||||
_sortingDatas = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 单元视图交互事件
|
||||
/// </summary>
|
||||
public Action<PointerDownEvent, ITableData> ClickTableDataEvent;
|
||||
|
||||
/// <summary>
|
||||
/// 单元视图交互事件
|
||||
/// </summary>
|
||||
public Action<TableColumn> ClickTableHeadEvent;
|
||||
|
||||
|
||||
public TableView()
|
||||
{
|
||||
_toolbar = new Toolbar();
|
||||
this.Add(_toolbar);
|
||||
|
||||
_listView = new ListView();
|
||||
_listView.makeItem = MakeListViewElement;
|
||||
_listView.bindItem = BindListViewElement;
|
||||
_listView.RegisterCallback<PointerDownEvent>(OnClickListItem);
|
||||
this.Add(_listView);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 添加单元列
|
||||
/// </summary>
|
||||
public void AddColumn(TableColumn column)
|
||||
{
|
||||
var toolbarBtn = new ToolbarButton();
|
||||
toolbarBtn.userData = column;
|
||||
toolbarBtn.name = column.ElementName;
|
||||
toolbarBtn.text = column.HeaderTitle;
|
||||
toolbarBtn.style.unityTextAlign = TextAnchor.MiddleLeft;
|
||||
toolbarBtn.style.flexGrow = column.ColumnStyle.Stretchable ? 1f : 0f;
|
||||
toolbarBtn.style.width = column.ColumnStyle.Width;
|
||||
toolbarBtn.style.minWidth = column.ColumnStyle.MinWidth;
|
||||
toolbarBtn.style.maxWidth = column.ColumnStyle.MaxWidth;
|
||||
toolbarBtn.clickable.clickedWithEventInfo += OnClickTableHead;
|
||||
SetCellElementStyle(toolbarBtn);
|
||||
_toolbar.Add(toolbarBtn);
|
||||
_columns.Add(column);
|
||||
|
||||
// 计算索引值
|
||||
column.ColumnIndex = _columns.Count - 1;
|
||||
|
||||
if (column.ColumnStyle.Sortable == false)
|
||||
toolbarBtn.SetEnabled(false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 添加单元列集合
|
||||
/// </summary>
|
||||
public void AddColumns(IList<TableColumn> columns)
|
||||
{
|
||||
foreach (var column in columns)
|
||||
{
|
||||
AddColumn(column);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 重建表格视图
|
||||
/// </summary>
|
||||
public void RebuildView()
|
||||
{
|
||||
if (_itemsSource == null)
|
||||
return;
|
||||
|
||||
var itemsSource = _sortingDatas.Where(row => row.Visible);
|
||||
|
||||
_listView.Clear();
|
||||
_listView.ClearSelection();
|
||||
_listView.itemsSource = itemsSource.ToList();
|
||||
_listView.Rebuild();
|
||||
}
|
||||
|
||||
private bool CheckItemsSource(List<ITableData> itemsSource)
|
||||
{
|
||||
if (itemsSource == null || itemsSource.Count == 0)
|
||||
{
|
||||
Debug.LogWarning("Items source is null or empty !");
|
||||
return false;
|
||||
}
|
||||
|
||||
int cellCount = itemsSource[0].Cells.Count;
|
||||
for (int i = 0; i < itemsSource.Count; i++)
|
||||
{
|
||||
var tableData = itemsSource[i];
|
||||
if (tableData == null)
|
||||
{
|
||||
Debug.LogWarning($"Items source has null instance !");
|
||||
return false;
|
||||
}
|
||||
if (tableData.Cells == null || tableData.Cells.Count == 0)
|
||||
{
|
||||
Debug.LogWarning($"Items source data has empty cells !");
|
||||
return false;
|
||||
}
|
||||
if (tableData.Cells.Count != cellCount)
|
||||
{
|
||||
Debug.LogWarning($"Items source data has inconsisten cells count ! Item index {i}");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
private void OnClickListItem(PointerDownEvent evt)
|
||||
{
|
||||
var selectData = _listView.selectedItem as ITableData;
|
||||
if (selectData == null)
|
||||
return;
|
||||
|
||||
ClickTableDataEvent?.Invoke(evt, selectData);
|
||||
}
|
||||
private void OnClickTableHead(EventBase eventBase)
|
||||
{
|
||||
if (_itemsSource == null)
|
||||
return;
|
||||
|
||||
ToolbarButton toolbarBtn = eventBase.target as ToolbarButton;
|
||||
var clickedColumn = toolbarBtn.userData as TableColumn;
|
||||
if (clickedColumn == null)
|
||||
return;
|
||||
|
||||
ClickTableHeadEvent?.Invoke(clickedColumn);
|
||||
if (clickedColumn.ColumnStyle.Sortable == false)
|
||||
return;
|
||||
|
||||
if (_sortingHeaderElement != clickedColumn.ElementName)
|
||||
{
|
||||
_sortingHeaderElement = clickedColumn.ElementName;
|
||||
_descendingSort = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
_descendingSort = !_descendingSort;
|
||||
}
|
||||
|
||||
// 升降符号
|
||||
foreach (var column in _columns)
|
||||
{
|
||||
var button = _toolbar.Q<ToolbarButton>(column.ElementName);
|
||||
button.text = column.HeaderTitle;
|
||||
}
|
||||
if (_descendingSort)
|
||||
toolbarBtn.text = $"{clickedColumn.HeaderTitle} ↓";
|
||||
else
|
||||
toolbarBtn.text = $"{clickedColumn.HeaderTitle} ↑";
|
||||
|
||||
// 升降排序
|
||||
if (_descendingSort)
|
||||
_sortingDatas = _itemsSource.OrderByDescending(tableData => tableData.Cells[clickedColumn.ColumnIndex]).ToList();
|
||||
else
|
||||
_sortingDatas = _itemsSource.OrderBy(tableData => tableData.Cells[clickedColumn.ColumnIndex]).ToList();
|
||||
|
||||
// 刷新数据表
|
||||
RebuildView();
|
||||
}
|
||||
private VisualElement MakeListViewElement()
|
||||
{
|
||||
VisualElement listViewElement = new VisualElement();
|
||||
listViewElement.style.flexDirection = FlexDirection.Row;
|
||||
foreach (var colum in _columns)
|
||||
{
|
||||
var cellElement = colum.MakeCell.Invoke();
|
||||
cellElement.name = colum.ElementName;
|
||||
SetCellElementStyle(cellElement);
|
||||
listViewElement.Add(cellElement);
|
||||
}
|
||||
return listViewElement;
|
||||
}
|
||||
private void BindListViewElement(VisualElement listViewElement, int index)
|
||||
{
|
||||
var sourceDatas = _listView.itemsSource as List<ITableData>;
|
||||
var tableData = sourceDatas[index];
|
||||
foreach (var colum in _columns)
|
||||
{
|
||||
var cellElement = listViewElement.Q(colum.ElementName);
|
||||
var tableCell = tableData.Cells[colum.ColumnIndex];
|
||||
colum.BindCell.Invoke(cellElement, tableData, tableCell);
|
||||
}
|
||||
}
|
||||
private void SetCellElementStyle(VisualElement element)
|
||||
{
|
||||
StyleLength defaultStyle = new StyleLength(1f);
|
||||
element.style.paddingTop = defaultStyle;
|
||||
element.style.paddingBottom = defaultStyle;
|
||||
element.style.paddingLeft = defaultStyle;
|
||||
element.style.paddingRight = defaultStyle;
|
||||
element.style.marginTop = defaultStyle;
|
||||
element.style.marginBottom = defaultStyle;
|
||||
element.style.marginLeft = defaultStyle;
|
||||
element.style.marginRight = defaultStyle;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
Reference in New Issue
Block a user