You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
155 lines
3.7 KiB
155 lines
3.7 KiB
using Connected.Annotations;
|
|
using Connected.Utilities;
|
|
using Microsoft.AspNetCore.Components;
|
|
|
|
namespace Connected.Components;
|
|
|
|
/// <summary>
|
|
/// Represents an option of a select or multi-select. To be used inside MudSelect.
|
|
/// </summary>
|
|
public partial class SelectItem<T> : SelectItemBase, IDisposable
|
|
{
|
|
private String GetCssClasses() => new CssBuilder()
|
|
.AddClass(Class)
|
|
.Build();
|
|
|
|
private ISelect _parent;
|
|
internal string ItemId { get; } = "_" + Guid.NewGuid().ToString().Substring(0, 8);
|
|
|
|
/// <summary>
|
|
/// The parent select component
|
|
/// </summary>
|
|
[CascadingParameter]
|
|
internal ISelect IMudSelect
|
|
{
|
|
get => _parent;
|
|
set
|
|
{
|
|
_parent = value;
|
|
if (_parent == null)
|
|
return;
|
|
_parent.CheckGenericTypeMatch(this);
|
|
if (Select == null)
|
|
return;
|
|
bool isSelected = Select.Add(this);
|
|
if (_parent.MultiSelection)
|
|
{
|
|
Select.SelectionChangedFromOutside += OnUpdateSelectionStateFromOutside;
|
|
InvokeAsync(() => OnUpdateSelectionStateFromOutside(Select.SelectedValues));
|
|
}
|
|
else
|
|
{
|
|
IsSelected = isSelected;
|
|
}
|
|
}
|
|
}
|
|
|
|
private IShadowSelect _shadowParent;
|
|
private bool _isSelected;
|
|
|
|
[CascadingParameter]
|
|
internal IShadowSelect ParentShadow
|
|
{
|
|
get => _shadowParent;
|
|
set
|
|
{
|
|
_shadowParent = value;
|
|
((Select<T>)_shadowParent)?.RegisterShadowItem(this);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Select items with HideContent==true are only there to register their RenderFragment with the select but
|
|
/// wont render and have no other purpose!
|
|
/// </summary>
|
|
[CascadingParameter(Name = "HideContent")]
|
|
internal bool HideContent { get; set; }
|
|
|
|
internal Select<T> Select => (Select<T>)IMudSelect;
|
|
|
|
private void OnUpdateSelectionStateFromOutside(IEnumerable<T> selection)
|
|
{
|
|
if (selection == null)
|
|
return;
|
|
var old_is_selected = IsSelected;
|
|
IsSelected = selection.Contains(Value);
|
|
if (old_is_selected != IsSelected)
|
|
InvokeAsync(StateHasChanged);
|
|
}
|
|
|
|
/// <summary>
|
|
/// A user-defined option that can be selected
|
|
/// </summary>
|
|
[Parameter]
|
|
[Category(CategoryTypes.FormComponent.Behavior)]
|
|
public T Value { get; set; }
|
|
|
|
/// <summary>
|
|
/// Mirrors the MultiSelection status of the parent select
|
|
/// </summary>
|
|
protected bool MultiSelection
|
|
{
|
|
get
|
|
{
|
|
if (Select == null)
|
|
return false;
|
|
return Select.MultiSelection;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Selected state of the option. Only works if the parent is a mulit-select
|
|
/// </summary>
|
|
internal bool IsSelected
|
|
{
|
|
get => _isSelected;
|
|
set
|
|
{
|
|
_isSelected = value;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// The checkbox icon reflects the multi-select option's state
|
|
/// </summary>
|
|
protected string CheckBoxIcon
|
|
{
|
|
get
|
|
{
|
|
if (!MultiSelection)
|
|
return null;
|
|
return IsSelected ? Icons.Material.Filled.CheckBox : Icons.Material.Filled.CheckBoxOutlineBlank;
|
|
}
|
|
}
|
|
|
|
protected string DisplayString
|
|
{
|
|
get
|
|
{
|
|
var converter = Select?.Converter;
|
|
if (converter == null)
|
|
return $"{Value}";
|
|
return converter.Convert(Value);
|
|
}
|
|
}
|
|
|
|
private void OnClicked()
|
|
{
|
|
if (MultiSelection)
|
|
IsSelected = !IsSelected;
|
|
|
|
Select?.SelectOption(Value);
|
|
InvokeAsync(StateHasChanged);
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
try
|
|
{
|
|
Select?.Remove(this);
|
|
((Select<T>)_shadowParent)?.UnregisterShadowItem(this);
|
|
}
|
|
catch (Exception) { }
|
|
}
|
|
}
|