using System; using System.Collections.Generic; using Microsoft.AspNetCore.Components; using System.Linq; using System.Collections; namespace AntDesign { public partial class Cascader : AntInputComponentBase { [Parameter] public bool Readonly { get; set; } = true; /// /// 是否支持清除 /// [Parameter] public bool AllowClear { get; set; } = true; /// /// 是否显示关闭图标 /// private bool ShowClearIcon { get; set; } /// /// 当此项为 true 时,点选每级菜单选项值都会发生变化 /// [Parameter] public bool ChangeOnSelect { get; set; } /// /// 默认的选中项 /// [Parameter] public string DefaultValue { get; set; } /// /// 次级菜单的展开方式,可选 'click' 和 'hover' /// [Parameter] public string ExpandTrigger { get; set; } /// /// 当下拉列表为空时显示的内容 /// [Parameter] public string NotFoundContent { get; set; } = "Not Found"; /// /// 输入框占位文本 /// [Parameter] public string PlaceHolder { get; set; } = "请选择"; [Parameter] public string PopupContainerSelector { get; set; } = "body"; /// /// 在选择框中显示搜索框 /// [Parameter] public bool ShowSearch { get; set; } /// /// 选择完成后的回调(参数为选中的节点集合及选中值) /// [Parameter] public Action, string, string> OnChange { get; set; } [Parameter] public IReadOnlyCollection Options { get { if (_nodelist != null) return _nodelist; return Array.Empty(); } set { if (value == null || value.Count == 0) { _nodelist = null; return; } if (_nodelist == null) _nodelist = new List(); else if (_nodelist.Count != 0) _nodelist.Clear(); _nodelist.AddRange(value); _optionsNeedInitialize = true; } } private List _nodelist; /// /// 选中节点集合(click) /// internal List _selectedNodes = new List(); /// /// 选中节点集合(hover) /// internal List _hoverSelectedNodes = new List(); /// /// 用于渲染下拉节点集合(一级节点除外) /// internal List _renderNodes = new List(); private string _pickerSizeClass = string.Empty; private string _inputSizeClass = string.Empty; /// /// 浮层 展开/折叠状态 /// private bool ToggleState { get; set; } /// /// 鼠标是否处于 浮层 之上 /// private bool IsOnCascader { get; set; } /// /// 选择节点类型 /// Click: 点击选中节点, Hover: 鼠标移入选中节点 /// private SelectedTypeEnum SelectedType { get; set; } private string _displayText; private bool _optionsNeedInitialize; protected override void OnInitialized() { base.OnInitialized(); } protected override void OnParametersSet() { base.OnParametersSet(); Hashtable sizeMap = new Hashtable() { ["large"] = "lg", ["small"] = "sm" }; if (sizeMap.ContainsKey(Size)) { _pickerSizeClass = $"ant-cascader-picker-{Size}"; _inputSizeClass = $"ant-input-{sizeMap[Size]}"; } else { _pickerSizeClass = ""; _inputSizeClass = ""; } ProcessParentAndDefault(); } protected override void OnValueChange(string value) { base.OnValueChange(value); RefreshNodeValue(value); } #region event /// /// 输入框单击(显示/隐藏浮层) /// private void InputOnToggle() { SelectedType = SelectedTypeEnum.Click; _hoverSelectedNodes.Clear(); ToggleState = !ToggleState; } /// /// 输入框/浮层失去焦点(隐藏浮层) /// private void CascaderOnBlur() { if (!IsOnCascader) { ToggleState = false; _renderNodes = _selectedNodes; } } /// /// 输入框鼠标移入 /// private void InputOnMouseOver() { if (!AllowClear) return; ShowClearIcon = true; } /// /// 输入框鼠标移出 /// private void InputOnMouseOut() { if (!AllowClear) return; ShowClearIcon = false; } /// /// 清除已选择项 /// private void ClearSelected() { _selectedNodes.Clear(); _hoverSelectedNodes.Clear(); _displayText = string.Empty; CurrentValueAsString = string.Empty; } /// /// 浮层移入 /// private void NodesOnMouseOver() { if (!AllowClear) return; IsOnCascader = true; } /// /// 浮层移出 /// private void NodesOnMouseOut() { if (!AllowClear) return; IsOnCascader = false; } /// /// 下拉节点单击 /// /// private void NodeOnClick(CascaderNode node) { if (node.Disabled) return; SetSelectedNode(node, SelectedTypeEnum.Click); } /// /// 下拉节点移入 /// /// private void NodeOnMouseOver(CascaderNode node) { if (ExpandTrigger != "hover") return; if (node.Disabled) return; if (!node.HasChildren) return; SetSelectedNode(node, SelectedTypeEnum.Hover); } #endregion event /// /// 选中节点 /// /// /// internal void SetSelectedNode(CascaderNode cascaderNode, SelectedTypeEnum selectedType) { if (cascaderNode == null) return; SelectedType = selectedType; if (selectedType == SelectedTypeEnum.Click) { _selectedNodes.Clear(); SetSelectedNodeWithParent(cascaderNode, ref _selectedNodes); _renderNodes = _selectedNodes; if (ChangeOnSelect || !cascaderNode.HasChildren) SetValue(cascaderNode.Value); } else { _hoverSelectedNodes.Clear(); SetSelectedNodeWithParent(cascaderNode, ref _hoverSelectedNodes); _renderNodes = _hoverSelectedNodes; } _renderNodes.Sort((x, y) => x.Level.CompareTo(y.Level)); //Level 升序排序 if (!cascaderNode.HasChildren) { ToggleState = false; IsOnCascader = false; } } /// /// 设置选中所有父节点 /// /// /// private void SetSelectedNodeWithParent(CascaderNode node, ref List list) { if (node == null) return; list.Add(node); SetSelectedNodeWithParent(node.ParentNode, ref list); } /// /// Options 更新后处理父节点和默认值 /// private void ProcessParentAndDefault() { if (_optionsNeedInitialize) { _optionsNeedInitialize = false; InitCascaderNodeState(_nodelist, null, 0); SetDefaultValue(Value ?? DefaultValue); } } /// /// 初始化节点属性(Level, ParentNode) /// /// /// /// private void InitCascaderNodeState(List list, CascaderNode parentNode, int level) { if (list == null) return; foreach (var node in list) { node.Level = level; node.ParentNode = parentNode; if (node.HasChildren) InitCascaderNodeState(node.Children.ToList(), node, level + 1); } } /// /// 刷新选中的内容 /// /// private void RefreshNodeValue(string value) { _selectedNodes.Clear(); var node = GetNodeByValue(_nodelist, value); SetSelectedNodeWithParent(node, ref _selectedNodes); _renderNodes = _selectedNodes; RefreshDisplayValue(); OnChange?.Invoke(_selectedNodes, value, _displayText); } /// /// 设置默认选中 /// /// private void SetDefaultValue(string defaultValue) { if (string.IsNullOrWhiteSpace(defaultValue)) return; _selectedNodes.Clear(); var node = GetNodeByValue(_nodelist, defaultValue); SetSelectedNodeWithParent(node, ref _selectedNodes); _renderNodes = _selectedNodes; SetValue(node?.Value); } /// /// 设置输入框选中值 /// /// private void SetValue(string value) { RefreshDisplayValue(); if (Value != value) { CurrentValueAsString = value; } OnChange?.Invoke(_selectedNodes, value, _displayText); } private void RefreshDisplayValue() { _selectedNodes.Sort((x, y) => x.Level.CompareTo(y.Level)); //Level 升序排序 _displayText = string.Empty; int count = 0; foreach (var node in _selectedNodes) { if (node == null) continue; if (count < _selectedNodes.Count - 1) _displayText += node.Label + " / "; else _displayText += node.Label; count++; } } /// /// 根据指定值获取节点 /// /// /// /// private CascaderNode GetNodeByValue(List list, string value) { if (list == null) return null; CascaderNode result = null; foreach (var node in list) { if (node.Value == value) return node; if (node.HasChildren) { var nd = GetNodeByValue(node.Children.ToList(), value); if (nd != null) result = nd; } } return result; } } }