using System; using System.Collections.Generic; using Microsoft.AspNetCore.Components; using System.Linq; using System.Collections; using System.Threading.Tasks; 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; } [Parameter] public bool ChangeOnSelect { get; set; } [Parameter] public string DefaultValue { get; set; } [Parameter] public string ExpandTrigger { get; set; } [Parameter] public string NotFoundContent { get; set; } = "Not Found"; [Parameter] public string PlaceHolder { get; set; } = LocaleProvider.CurrentLocale.Global.Placeholder; [Parameter] public string PopupContainerSelector { get; set; } = "body"; [Parameter] public bool ShowSearch { get; set; } /// /// Please use SelectedNodesChanged instead. /// [Obsolete("Instead use SelectedNodesChanged.")] [Parameter] public Action, string, string> OnChange { get; set; } [Parameter] public EventCallback SelectedNodesChanged { 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); ProcessParentAndDefault(); } } private List _nodelist; internal List _selectedNodes = new List(); internal List _hoverSelectedNodes = new List(); internal List _renderNodes = new List(); private ClassMapper _menuClassMapper = new ClassMapper(); private ClassMapper _inputClassMapper = new ClassMapper(); private bool ToggleState { get; set; } private bool IsOnCascader { get; set; } private SelectedTypeEnum SelectedType { get; set; } private string _displayText; private bool _initialized; private static Dictionary _sizeMap = new Dictionary() { ["large"] = "lg", ["small"] = "sm" }; protected override void OnInitialized() { base.OnInitialized(); ClassMapper .Add("ant-cascader-picker") .GetIf(() => $"ant-cascader-picker-{Size}", () => _sizeMap.ContainsKey(Size)) .If("ant-cascader-picker-rtl", () => RTL); _inputClassMapper .Add("ant-input") .Add("ant-cascader-input") .GetIf(() => $"ant-input-{_sizeMap[Size]}", () => _sizeMap.ContainsKey(Size)) .If("ant-cascader-input-rtl", () => RTL); _menuClassMapper .Add("ant-cascader-menu") .If($"ant-cascader-menu-rtl", () => RTL); SetDefaultValue(Value ?? DefaultValue); } 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; SetValue(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() { 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)) { _selectedNodes.Clear(); var node = GetNodeByValue(_nodelist, defaultValue); SetSelectedNodeWithParent(node, ref _selectedNodes); _renderNodes = _selectedNodes; SetValue(node?.Value); } _initialized = true; } /// /// 设置输入框选中值 /// /// private void SetValue(string value) { RefreshDisplayValue(); if (Value != value) { CurrentValueAsString = value; if (_initialized && SelectedNodesChanged.HasDelegate) { SelectedNodesChanged.InvokeAsync(_selectedNodes.ToArray()); } } } 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; } } }