mirror of
https://github.com/AtomUI/AtomUI.git
synced 2026-10-24 02:09:37 +08:00
Add TagClose support for Select
This commit is contained in:
-2
@@ -706,8 +706,6 @@ namespace AtomUI.Controls.DesignTokens
|
||||
public static readonly TokenResourceKey MultiModePaddingLG = new TokenResourceKey("Select.MultiModePaddingLG");
|
||||
public static readonly TokenResourceKey MultiModePaddingSM = new TokenResourceKey("Select.MultiModePaddingSM");
|
||||
public static readonly TokenResourceKey MultipleItemBg = new TokenResourceKey("Select.MultipleItemBg");
|
||||
public static readonly TokenResourceKey MultipleItemBorderColor = new TokenResourceKey("Select.MultipleItemBorderColor");
|
||||
public static readonly TokenResourceKey MultipleItemBorderColorDisabled = new TokenResourceKey("Select.MultipleItemBorderColorDisabled");
|
||||
public static readonly TokenResourceKey MultipleItemColorDisabled = new TokenResourceKey("Select.MultipleItemColorDisabled");
|
||||
public static readonly TokenResourceKey MultipleItemHeight = new TokenResourceKey("Select.MultipleItemHeight");
|
||||
public static readonly TokenResourceKey MultipleItemHeightLG = new TokenResourceKey("Select.MultipleItemHeightLG");
|
||||
|
||||
@@ -4,6 +4,7 @@ using AtomUI.Theme.Utils;
|
||||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Controls.Primitives;
|
||||
using Avalonia.Input;
|
||||
using Avalonia.Media;
|
||||
|
||||
namespace AtomUI.Controls;
|
||||
@@ -143,5 +144,4 @@ public class TextBox : AvaloniaTextBox,
|
||||
{
|
||||
Clear();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -94,6 +94,7 @@
|
||||
</Setter>
|
||||
|
||||
<Style Selector="^:is(atom|TextBox)">
|
||||
<Setter Property="Background" Value="Transparent" />
|
||||
<Setter Property="SelectionBrush" Value="{DynamicResource {x:Static atom:SharedTokenKey.SelectionBackground}}" />
|
||||
<Setter Property="CaretBrush" Value="{DynamicResource {x:Static atom:SharedTokenKey.ColorText}}" />
|
||||
<Setter Property="SelectionForegroundBrush"
|
||||
|
||||
@@ -253,5 +253,4 @@ internal class ListDefaultView : SelectingItemsControl
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -36,6 +36,7 @@ internal class AddOnDecoratedBox : ContentControl,
|
||||
IMotionAwareControl
|
||||
{
|
||||
public const string AddOnDecoratedBoxPart = "PART_AddOnDecoratedBox";
|
||||
|
||||
#region 公共属性定义
|
||||
|
||||
public static readonly StyledProperty<object?> LeftAddOnProperty =
|
||||
@@ -180,6 +181,11 @@ internal class AddOnDecoratedBox : ContentControl,
|
||||
AvaloniaProperty.RegisterDirect<AddOnDecoratedBox, bool>(nameof(IsInnerBoxHover),
|
||||
o => o.IsInnerBoxHover,
|
||||
(o, v) => o.IsInnerBoxHover = v);
|
||||
|
||||
internal static readonly DirectProperty<AddOnDecoratedBox, bool> IsInnerBoxPressedProperty =
|
||||
AvaloniaProperty.RegisterDirect<AddOnDecoratedBox, bool>(nameof(IsInnerBoxPressed),
|
||||
o => o.IsInnerBoxPressed,
|
||||
(o, v) => o.IsInnerBoxPressed = v);
|
||||
|
||||
private CornerRadius _innerBoxCornerRadius;
|
||||
|
||||
@@ -228,6 +234,14 @@ internal class AddOnDecoratedBox : ContentControl,
|
||||
get => _isInnerBoxHover;
|
||||
set => SetAndRaise(IsInnerBoxHoverProperty, ref _isInnerBoxHover, value);
|
||||
}
|
||||
|
||||
private bool _isInnerBoxPressed;
|
||||
|
||||
internal bool IsInnerBoxPressed
|
||||
{
|
||||
get => _isInnerBoxPressed;
|
||||
set => SetAndRaise(IsInnerBoxPressedProperty, ref _isInnerBoxPressed, value);
|
||||
}
|
||||
|
||||
Control IControlSharedTokenResourcesHost.HostControl => this;
|
||||
string IControlSharedTokenResourcesHost.TokenId => AddOnDecoratedBoxToken.ID;
|
||||
@@ -376,6 +390,14 @@ internal class AddOnDecoratedBox : ContentControl,
|
||||
{
|
||||
IsInnerBoxHover = false;
|
||||
};
|
||||
ContentFrame.PointerPressed += (sender, args) =>
|
||||
{
|
||||
IsInnerBoxPressed = true;
|
||||
};
|
||||
ContentFrame.PointerReleased += (sender, args) =>
|
||||
{
|
||||
IsInnerBoxPressed = false;
|
||||
};
|
||||
}
|
||||
|
||||
ConfigureInnerBoxCornerRadius();
|
||||
|
||||
+1
-1
@@ -287,7 +287,7 @@
|
||||
|
||||
<Style Selector="^:pressed">
|
||||
<Setter Property="BorderBrush"
|
||||
Value="{DynamicResource {x:Static atom:SharedTokenKey.ColorError}}" />
|
||||
Value="{DynamicResource {x:Static atom:SharedTokenKey.ColorWarning}}" />
|
||||
</Style>
|
||||
</Style>
|
||||
</Style>
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
using System.Collections;
|
||||
using System.Diagnostics;
|
||||
using System.Reactive.Disposables;
|
||||
using AtomUI.Controls.Data;
|
||||
@@ -12,6 +11,7 @@ using Avalonia.Controls;
|
||||
using Avalonia.Controls.Primitives;
|
||||
using Avalonia.Controls.Templates;
|
||||
using Avalonia.Input;
|
||||
using Avalonia.Interactivity;
|
||||
using Avalonia.Media;
|
||||
using Avalonia.Metadata;
|
||||
using Avalonia.VisualTree;
|
||||
@@ -474,7 +474,8 @@ public class Select : TemplatedControl,
|
||||
private SelectSearchTextBox? _singleSearchInput;
|
||||
private readonly CompositeDisposable _subscriptionsOnOpen = new ();
|
||||
private ListFilterDescription? _filterDescription;
|
||||
|
||||
private string? _filterValue;
|
||||
|
||||
static Select()
|
||||
{
|
||||
FocusableProperty.OverrideDefaultValue<Select>(true);
|
||||
@@ -483,6 +484,8 @@ public class Select : TemplatedControl,
|
||||
target.HandleClearRequest();
|
||||
});
|
||||
OptionsSourceProperty.Changed.AddClassHandler<Select>((x, e) => x.HandleOptionsSourcePropertyChanged(e));
|
||||
SelectSearchTextBox.TextChangedEvent.AddClassHandler<Select>((x, e) => x.HandleSearchInputTextChanged(e));
|
||||
SelectTag.ClosedEvent.AddClassHandler<Select>((x, e) => x.HandleTagCloseRequest(e));
|
||||
}
|
||||
|
||||
public Select()
|
||||
@@ -639,6 +642,7 @@ public class Select : TemplatedControl,
|
||||
{
|
||||
_optionsBox.SelectionChanged += HandleOptionsBoxSelectionChanged;
|
||||
}
|
||||
|
||||
_popup = e.NameScope.Get<Popup>(SelectThemeConstants.PopupPart);
|
||||
_popup.Opened += PopupOpened;
|
||||
_popup.Closed += PopupClosed;
|
||||
@@ -669,21 +673,18 @@ public class Select : TemplatedControl,
|
||||
}
|
||||
else
|
||||
{
|
||||
var selectedOptions = new List<SelectOption>();
|
||||
var selectedOptions = new HashSet<SelectOption>();
|
||||
if (SelectedOptions != null)
|
||||
{
|
||||
foreach (var option in SelectedOptions)
|
||||
{
|
||||
if (!selectedOptions.Contains(option))
|
||||
{
|
||||
selectedOptions.Add(option);
|
||||
}
|
||||
selectedOptions.Add(option);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var item in e.RemovedItems)
|
||||
{
|
||||
if (item is SelectOption selectOption)
|
||||
if (item is SelectOption selectOption && !selectOption.IsSelected)
|
||||
{
|
||||
selectedOptions.Remove(selectOption);
|
||||
}
|
||||
@@ -691,17 +692,22 @@ public class Select : TemplatedControl,
|
||||
|
||||
foreach (var item in e.AddedItems)
|
||||
{
|
||||
if (item is SelectOption selectOption && !selectedOptions.Contains(selectOption))
|
||||
if (item is SelectOption selectOption && !selectedOptions.Contains(selectOption) && selectOption.IsSelected)
|
||||
{
|
||||
selectedOptions.Add(selectOption);
|
||||
}
|
||||
}
|
||||
SetCurrentValue(SelectedOptionsProperty, selectedOptions);
|
||||
var oldSelectedOptions = SelectedOptions?.ToHashSet() ?? new HashSet<SelectOption>();
|
||||
if (!oldSelectedOptions.SetEquals(selectedOptions))
|
||||
{
|
||||
SetCurrentValue(SelectedOptionsProperty, selectedOptions.ToList());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change)
|
||||
{
|
||||
base.OnPropertyChanged(change);
|
||||
if (change.Property == SelectedOptionsProperty)
|
||||
{
|
||||
ConfigurePlaceholderVisible();
|
||||
@@ -735,7 +741,6 @@ public class Select : TemplatedControl,
|
||||
{
|
||||
HandleOptionFilterPropChanged();
|
||||
}
|
||||
base.OnPropertyChanged(change);
|
||||
}
|
||||
|
||||
private void PopupClosed(object? sender, EventArgs e)
|
||||
@@ -750,6 +755,8 @@ public class Select : TemplatedControl,
|
||||
_singleSearchInput.Width = double.NaN;
|
||||
}
|
||||
}
|
||||
|
||||
_filterValue = null;
|
||||
}
|
||||
|
||||
private void PopupOpened(object? sender, EventArgs e)
|
||||
@@ -761,11 +768,6 @@ public class Select : TemplatedControl,
|
||||
parent.GetObservable(IsVisibleProperty).Subscribe(IsVisibleChanged).DisposeWith(_subscriptionsOnOpen);
|
||||
}
|
||||
|
||||
if (_optionsBox != null)
|
||||
{
|
||||
_optionsBox.SelectedItem = SelectedOption;
|
||||
_optionsBox.SelectedItems = (IList?)SelectedOptions;
|
||||
}
|
||||
DropDownOpened?.Invoke(this, EventArgs.Empty);
|
||||
if (Mode == SelectMode.Single)
|
||||
{
|
||||
@@ -786,8 +788,25 @@ public class Select : TemplatedControl,
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
if (SelectedOptions != null)
|
||||
{
|
||||
foreach (var option in SelectedOptions)
|
||||
{
|
||||
option.IsSelected = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (SelectedOption != null)
|
||||
{
|
||||
SelectedOption.IsSelected = false;
|
||||
}
|
||||
SelectedOptions = null;
|
||||
SelectedOption = null;
|
||||
if (_optionsBox != null)
|
||||
{
|
||||
_optionsBox.SelectedItems = null;
|
||||
_optionsBox.SelectedItem = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void ConfigureMaxDropdownHeight()
|
||||
@@ -825,7 +844,7 @@ public class Select : TemplatedControl,
|
||||
private void ConfigurePlaceholderVisible()
|
||||
{
|
||||
SetCurrentValue(IsPlaceholderTextVisibleProperty, (Mode == SelectMode.Single && SelectedOption == null) ||
|
||||
(Mode != SelectMode.Single && SelectedOptions == null || SelectedOptions?.Count == 0));
|
||||
(Mode != SelectMode.Single && (SelectedOptions == null || SelectedOptions?.Count == 0) && string.IsNullOrEmpty(_filterValue)));
|
||||
}
|
||||
|
||||
private void ConfigureSelectionIsEmpty()
|
||||
@@ -841,16 +860,20 @@ public class Select : TemplatedControl,
|
||||
{
|
||||
_singleSearchInput.Width = _singleSearchInput.Bounds.Width;
|
||||
}
|
||||
_singleSearchInput.TextChanged += HandleSearchInputTextChanged;
|
||||
}
|
||||
}
|
||||
|
||||
private void HandleSearchInputTextChanged(object? sender, TextChangedEventArgs e)
|
||||
private void HandleSearchInputTextChanged(TextChangedEventArgs e)
|
||||
{
|
||||
if (_optionsBox != null && _optionsBox.FilterDescriptions != null)
|
||||
{
|
||||
var filterValue = _singleSearchInput?.Text;
|
||||
if (string.IsNullOrEmpty(filterValue))
|
||||
if (e.Source is TextBox textBox)
|
||||
{
|
||||
_filterValue = textBox.Text;
|
||||
}
|
||||
|
||||
ConfigurePlaceholderVisible();
|
||||
if (string.IsNullOrEmpty(_filterValue))
|
||||
{
|
||||
_optionsBox.FilterDescriptions.Clear();
|
||||
}
|
||||
@@ -861,13 +884,13 @@ public class Select : TemplatedControl,
|
||||
var oldFilter = _filterDescription;
|
||||
Debug.Assert(oldFilter.FilterConditions.Count == 1);
|
||||
var oldFilterValue = oldFilter.FilterConditions.First().ToString();
|
||||
if (oldFilterValue != filterValue)
|
||||
if (oldFilterValue != _filterValue)
|
||||
{
|
||||
_filterDescription = new ListFilterDescription()
|
||||
{
|
||||
PropertyPath = _filterDescription.PropertyPath,
|
||||
Filter = _filterDescription.Filter,
|
||||
FilterConditions = [filterValue]
|
||||
FilterConditions = [_filterValue]
|
||||
};
|
||||
_optionsBox.FilterDescriptions.Remove(oldFilter);
|
||||
_optionsBox.FilterDescriptions.Add(_filterDescription);
|
||||
@@ -879,12 +902,22 @@ public class Select : TemplatedControl,
|
||||
{
|
||||
PropertyPath = OptionFilterProp,
|
||||
Filter = FilterFn,
|
||||
FilterConditions = [filterValue],
|
||||
FilterConditions = [_filterValue],
|
||||
};
|
||||
_optionsBox.FilterDescriptions.Add(_filterDescription);
|
||||
}
|
||||
}
|
||||
}
|
||||
e.Handled = true;
|
||||
}
|
||||
|
||||
private void HandleTagCloseRequest(RoutedEventArgs e)
|
||||
{
|
||||
if (e.Source is SelectTag tag && tag.Option != null)
|
||||
{
|
||||
_optionsBox?.DeSelect(tag.Option);
|
||||
}
|
||||
e.Handled = true;
|
||||
}
|
||||
|
||||
private void HandleOptionFilterPropChanged()
|
||||
|
||||
@@ -13,6 +13,9 @@ internal class SelectAddOnDecoratedBox : AddOnDecoratedBox
|
||||
o => o.IsSelectionEmpty,
|
||||
(o, v) => o.IsSelectionEmpty = v);
|
||||
|
||||
public static readonly StyledProperty<bool> IsDropDownOpenProperty =
|
||||
AvaloniaProperty.Register<SelectAddOnDecoratedBox, bool>(nameof(IsDropDownOpen));
|
||||
|
||||
public SelectMode Mode
|
||||
{
|
||||
get => GetValue(ModeProperty);
|
||||
@@ -26,4 +29,10 @@ internal class SelectAddOnDecoratedBox : AddOnDecoratedBox
|
||||
get => _isSelectionEmpty;
|
||||
set => SetAndRaise(IsSelectionEmptyProperty, ref _isSelectionEmpty, value);
|
||||
}
|
||||
|
||||
public bool IsDropDownOpen
|
||||
{
|
||||
get => GetValue(IsDropDownOpenProperty);
|
||||
set => SetValue(IsDropDownOpenProperty, value);
|
||||
}
|
||||
}
|
||||
@@ -11,6 +11,9 @@ internal class SelectHandle : TemplatedControl
|
||||
public static readonly StyledProperty<bool> IsInputHoverProperty =
|
||||
AvaloniaProperty.Register<SelectHandle, bool>(nameof(IsInputHover));
|
||||
|
||||
public static readonly StyledProperty<bool> IsInputPressedProperty =
|
||||
AvaloniaProperty.Register<SelectHandle, bool>(nameof(IsInputPressed));
|
||||
|
||||
public static readonly StyledProperty<bool> IsSearchEnabledProperty =
|
||||
AvaloniaProperty.Register<SelectHandle, bool>(nameof(IsSearchEnabled));
|
||||
|
||||
@@ -35,6 +38,12 @@ internal class SelectHandle : TemplatedControl
|
||||
set => SetValue(IsInputHoverProperty, value);
|
||||
}
|
||||
|
||||
public bool IsInputPressed
|
||||
{
|
||||
get => GetValue(IsInputPressedProperty);
|
||||
set => SetValue(IsInputPressedProperty, value);
|
||||
}
|
||||
|
||||
public bool IsSearchEnabled
|
||||
{
|
||||
get => GetValue(IsSearchEnabledProperty);
|
||||
|
||||
@@ -10,4 +10,6 @@ public record SelectOption : ISelectOption
|
||||
public string Header { get; set; } = string.Empty;
|
||||
public bool IsEnabled { get; set; } = true;
|
||||
public object? Value { get; set; }
|
||||
|
||||
internal bool IsSelected { get; set; } = false;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
using System.Reactive.Disposables;
|
||||
using AtomUI.Data;
|
||||
using AtomUI.Utils;
|
||||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Input;
|
||||
@@ -18,7 +17,7 @@ internal class SelectOptions : List
|
||||
return new SelectOptionItem();
|
||||
}
|
||||
|
||||
private void DoSelectOption(Control container)
|
||||
private void LogicalSelectOption(Control container)
|
||||
{
|
||||
if (ListDefaultView != null)
|
||||
{
|
||||
@@ -29,22 +28,69 @@ internal class SelectOptions : List
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var mode = SelectionMode;
|
||||
var item = ListDefaultView.ItemFromContainer(container);
|
||||
var mode = SelectionMode;
|
||||
if (mode == SelectionMode.Single)
|
||||
{
|
||||
ListDefaultView.Selection.Select(index);
|
||||
}
|
||||
else if (mode == SelectionMode.Multiple)
|
||||
{
|
||||
if (ListDefaultView.Selection.IsSelected(index))
|
||||
if (item is SelectOption option)
|
||||
{
|
||||
ListDefaultView.Selection.Deselect(index);
|
||||
if (ListDefaultView.Selection.IsSelected(index))
|
||||
{
|
||||
option.IsSelected = false;
|
||||
ListDefaultView.Selection.Deselect(index);
|
||||
}
|
||||
else
|
||||
{
|
||||
option.IsSelected = true;
|
||||
ListDefaultView.Selection.Select(index);
|
||||
}
|
||||
}
|
||||
else
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Select(SelectOption option)
|
||||
{
|
||||
if (ListDefaultView != null)
|
||||
{
|
||||
var container = ListDefaultView.ContainerFromItem(option);
|
||||
if (container != null)
|
||||
{
|
||||
var index = ListDefaultView.IndexFromContainer(container);
|
||||
if (index != -1)
|
||||
{
|
||||
if (index < 0 || index >= ItemCount)
|
||||
{
|
||||
ListDefaultView.Selection.Select(index);
|
||||
return;
|
||||
}
|
||||
option.IsSelected = true;
|
||||
ListDefaultView.Selection.Select(index);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void DeSelect(SelectOption option)
|
||||
{
|
||||
if (ListDefaultView != null)
|
||||
{
|
||||
var container = ListDefaultView.ContainerFromItem(option);
|
||||
if (container != null)
|
||||
{
|
||||
var index = ListDefaultView.IndexFromContainer(container);
|
||||
if (index != -1)
|
||||
{
|
||||
if (index < 0 || index >= ItemCount)
|
||||
{
|
||||
return;
|
||||
}
|
||||
option.IsSelected = false;
|
||||
ListDefaultView.Selection.Deselect(index);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -55,7 +101,7 @@ internal class SelectOptions : List
|
||||
var container = GetContainerFromEventSource(source);
|
||||
if (container != null)
|
||||
{
|
||||
DoSelectOption(container);
|
||||
LogicalSelectOption(container);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -81,6 +127,11 @@ internal class SelectOptions : List
|
||||
{
|
||||
listItem.SetCurrentValue(IsEnabledProperty, data.IsEnabled);
|
||||
}
|
||||
if (!listItem.IsSet(SelectOptionItem.IsSelectedProperty))
|
||||
{
|
||||
listItem.SetCurrentValue(SelectOptionItem.IsSelectedProperty, data.IsSelected);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Controls.Primitives;
|
||||
using Avalonia.Input;
|
||||
using Avalonia.Layout;
|
||||
|
||||
namespace AtomUI.Controls;
|
||||
|
||||
@@ -20,6 +21,9 @@ internal class SelectResultOptionsBox : TemplatedControl
|
||||
public static readonly StyledProperty<bool> IsSearchEnabledProperty =
|
||||
Select.IsSearchEnabledProperty.AddOwner<SelectResultOptionsBox>();
|
||||
|
||||
public static readonly StyledProperty<bool> IsDropDownOpenProperty =
|
||||
AvaloniaProperty.Register<SelectResultOptionsBox, bool>(nameof(IsDropDownOpen));
|
||||
|
||||
private IList<SelectOption>? _selectedOptions;
|
||||
|
||||
public IList<SelectOption>? SelectedOptions
|
||||
@@ -39,8 +43,15 @@ internal class SelectResultOptionsBox : TemplatedControl
|
||||
get => GetValue(IsSearchEnabledProperty);
|
||||
set => SetValue(IsSearchEnabledProperty, value);
|
||||
}
|
||||
|
||||
public bool IsDropDownOpen
|
||||
{
|
||||
get => GetValue(IsDropDownOpenProperty);
|
||||
set => SetValue(IsDropDownOpenProperty, value);
|
||||
}
|
||||
|
||||
private WrapPanel? _defaultPanel;
|
||||
private SelectSearchTextBox? _searchTextBox;
|
||||
|
||||
protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change)
|
||||
{
|
||||
@@ -49,6 +60,15 @@ internal class SelectResultOptionsBox : TemplatedControl
|
||||
{
|
||||
HandleSelectedOptionsChanged();
|
||||
}
|
||||
else if (change.Property == IsSearchEnabledProperty ||
|
||||
change.Property == ModeProperty)
|
||||
{
|
||||
ConfigureSearchTextControl();
|
||||
}
|
||||
else if (change.Property == IsDropDownOpenProperty)
|
||||
{
|
||||
ConfigureSearchTextReadOnly();
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnPointerPressed(PointerPressedEventArgs e)
|
||||
@@ -66,25 +86,80 @@ internal class SelectResultOptionsBox : TemplatedControl
|
||||
protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
|
||||
{
|
||||
base.OnApplyTemplate(e);
|
||||
_defaultPanel = e.NameScope.Find<WrapPanel>(SelectResultOptionsBoxThemeConstants.DefaultPanelPart);
|
||||
_defaultPanel = e.NameScope.Find<WrapPanel>(SelectResultOptionsBoxThemeConstants.DefaultPanelPart);
|
||||
_searchTextBox = new SelectSearchTextBox()
|
||||
{
|
||||
HorizontalAlignment = HorizontalAlignment.Stretch
|
||||
};
|
||||
if (IsSearchEnabled)
|
||||
{
|
||||
if (Mode == SelectMode.Multiple)
|
||||
{
|
||||
_defaultPanel?.Children.Add(_searchTextBox);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void HandleSelectedOptionsChanged()
|
||||
{
|
||||
if (_defaultPanel != null)
|
||||
{
|
||||
_searchTextBox?.Clear();
|
||||
_defaultPanel.Children.Clear();
|
||||
if (_selectedOptions != null)
|
||||
{
|
||||
foreach (var option in _selectedOptions)
|
||||
{
|
||||
_defaultPanel.Children.Add(new Tag()
|
||||
_defaultPanel.Children.Add(new SelectTag()
|
||||
{
|
||||
TagText = option.Header,
|
||||
Bordered = false
|
||||
Option = option
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (_searchTextBox != null)
|
||||
{
|
||||
_defaultPanel.Children.Add(_searchTextBox);
|
||||
_searchTextBox.Focus();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void ConfigureSearchTextControl()
|
||||
{
|
||||
if (_searchTextBox != null)
|
||||
{
|
||||
if (Mode == SelectMode.Multiple)
|
||||
{
|
||||
if (_defaultPanel != null)
|
||||
{
|
||||
if (IsSearchEnabled)
|
||||
{
|
||||
_defaultPanel.Children.Add(_searchTextBox);
|
||||
}
|
||||
else
|
||||
{
|
||||
_defaultPanel.Children.Remove(_searchTextBox);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void ConfigureSearchTextReadOnly()
|
||||
{
|
||||
if (_searchTextBox != null)
|
||||
{
|
||||
if (IsDropDownOpen)
|
||||
{
|
||||
_searchTextBox.IsReadOnly = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
_searchTextBox.Clear();
|
||||
_searchTextBox.IsReadOnly = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
namespace AtomUI.Controls;
|
||||
|
||||
internal class SelectTag : Tag
|
||||
{
|
||||
public SelectOption? Option { get; set; }
|
||||
}
|
||||
@@ -15,12 +15,6 @@ internal class SelectToken : AbstractControlDesignToken
|
||||
/// </summary>
|
||||
public Color MultipleItemBg { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 多选标签边框色
|
||||
/// Border color of multiple tag
|
||||
/// </summary>
|
||||
public Color MultipleItemBorderColor { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 多选标签高度
|
||||
/// Height of multiple tag
|
||||
@@ -51,12 +45,6 @@ internal class SelectToken : AbstractControlDesignToken
|
||||
/// </summary>
|
||||
public Color MultipleItemColorDisabled { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 多选标签禁用边框色
|
||||
/// Border color of multiple tag when disabled
|
||||
/// </summary>
|
||||
public Color MultipleItemBorderColorDisabled { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 选项选中时文本颜色
|
||||
/// Text color when option is selected
|
||||
@@ -165,13 +153,11 @@ internal class SelectToken : AbstractControlDesignToken
|
||||
OptionFontSize = SharedToken.FontSize;
|
||||
OptionHeight = SharedToken.ControlHeight;
|
||||
MultipleItemBg = SharedToken.ColorFillSecondary;
|
||||
MultipleItemBorderColor = Colors.Transparent;
|
||||
MultipleItemHeight = multipleItemHeight;
|
||||
MultipleItemHeightSM = multipleItemHeightSM;
|
||||
MultipleItemHeightLG = multipleItemHeightLG;
|
||||
MultipleSelectorBgDisabled = SharedToken.ColorBgContainerDisabled;
|
||||
MultipleItemColorDisabled = SharedToken.ColorTextDisabled;
|
||||
MultipleItemBorderColorDisabled = Colors.Transparent;
|
||||
SelectAffixPadding = SharedToken.PaddingXXS;
|
||||
|
||||
PopupBorderRadius = SharedToken.BorderRadiusLG;
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
using System.Collections.Specialized;
|
||||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
|
||||
namespace AtomUI.Controls;
|
||||
|
||||
internal class SelectWrapPanel : WrapPanel
|
||||
{
|
||||
private SelectSearchTextBox? _searchTextBox;
|
||||
|
||||
protected override Size ArrangeOverride(Size finalSize)
|
||||
{
|
||||
var size = base.ArrangeOverride(finalSize);
|
||||
if (_searchTextBox != null)
|
||||
{
|
||||
if (Children.Count == 1)
|
||||
{
|
||||
_searchTextBox.Arrange(new Rect(0, 0, finalSize.Width, finalSize.Height));
|
||||
}
|
||||
else
|
||||
{
|
||||
// 找最后一个
|
||||
var indexOf = Children.IndexOf(_searchTextBox);
|
||||
var lastIndex = indexOf - 1;
|
||||
var lastTag = Children[lastIndex];
|
||||
var lastBounds = lastTag.Bounds;
|
||||
var offestX = lastBounds.Right + ItemSpacing;
|
||||
var offsetY = lastBounds.Top;
|
||||
var width = finalSize.Width - offestX;
|
||||
|
||||
if ((offestX + _searchTextBox.DesiredSize.Width) > finalSize.Width)
|
||||
{
|
||||
offestX = 0;
|
||||
offsetY += lastBounds.Height + LineSpacing;
|
||||
width = finalSize.Width;
|
||||
}
|
||||
var targetSearchBoxBounds = new Rect(offestX, offsetY, width, _searchTextBox.DesiredSize.Height);
|
||||
_searchTextBox.Arrange(targetSearchBoxBounds);
|
||||
}
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
protected override void ChildrenChanged(object? sender, NotifyCollectionChangedEventArgs e)
|
||||
{
|
||||
base.ChildrenChanged(sender, e);
|
||||
if (e.OldItems != null)
|
||||
{
|
||||
foreach (var oldItem in e.OldItems)
|
||||
{
|
||||
if (oldItem is SelectSearchTextBox)
|
||||
{
|
||||
_searchTextBox = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (e.NewItems != null)
|
||||
{
|
||||
foreach (var newItem in e.NewItems)
|
||||
{
|
||||
if (newItem is SelectSearchTextBox searchTextBox)
|
||||
{
|
||||
_searchTextBox = searchTextBox;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -10,24 +10,183 @@
|
||||
</ControlTheme.BasedOn>
|
||||
|
||||
<Style Selector="^:is(atom|SelectAddOnDecoratedBox)">
|
||||
<Style Selector="^:not(^[Mode=Single])^[IsSelectionEmpty=False]">
|
||||
<Style Selector="^[SizeType=Large]">
|
||||
<Style Selector="^ /template/ Border#PART_ContentFrame">
|
||||
<Setter Property="Padding"
|
||||
Value="{DynamicResource {x:Static atom:SelectTokenKey.MultiModePaddingLG}}" />
|
||||
<Style Selector="^:not(^[Mode=Single])">
|
||||
<Style Selector="^[IsSelectionEmpty=False]">
|
||||
<Style Selector="^[SizeType=Large]">
|
||||
<Style Selector="^ /template/ Border#PART_ContentFrame">
|
||||
<Setter Property="Padding"
|
||||
Value="{DynamicResource {x:Static atom:SelectTokenKey.MultiModePaddingLG}}" />
|
||||
</Style>
|
||||
</Style>
|
||||
<Style Selector="^[SizeType=Middle]">
|
||||
<Style Selector="^ /template/ Border#PART_ContentFrame">
|
||||
<Setter Property="Padding"
|
||||
Value="{DynamicResource {x:Static atom:SelectTokenKey.MultiModePadding}}" />
|
||||
</Style>
|
||||
|
||||
</Style>
|
||||
<Style Selector="^[SizeType=Small]">
|
||||
<Style Selector="^ /template/ Border#PART_ContentFrame">
|
||||
<Setter Property="Padding"
|
||||
Value="{DynamicResource {x:Static atom:SelectTokenKey.MultiModePaddingSM}}" />
|
||||
</Style>
|
||||
</Style>
|
||||
</Style>
|
||||
<Style Selector="^[SizeType=Middle]">
|
||||
<Style Selector="^ /template/ Border#PART_ContentFrame">
|
||||
<Setter Property="Padding"
|
||||
Value="{DynamicResource {x:Static atom:SelectTokenKey.MultiModePadding}}" />
|
||||
</Style>
|
||||
|
||||
<Style Selector="^[StyleVariant=Outline]">
|
||||
<Setter Property="BorderBrush" Value="{DynamicResource {x:Static atom:SharedTokenKey.ColorBorder}}" />
|
||||
|
||||
<Style Selector="^[IsInnerBoxHover=True]">
|
||||
<Setter Property="BorderBrush"
|
||||
Value="{DynamicResource {x:Static atom:AddOnDecoratedBoxTokenKey.HoverBorderColor}}" />
|
||||
</Style>
|
||||
|
||||
<Style Selector="^:focus-within">
|
||||
<Setter Property="BorderBrush"
|
||||
Value="{DynamicResource {x:Static atom:AddOnDecoratedBoxTokenKey.ActiveBorderColor}}" />
|
||||
</Style>
|
||||
|
||||
<Style Selector="^:pressed">
|
||||
<Setter Property="BorderBrush"
|
||||
Value="{DynamicResource {x:Static atom:AddOnDecoratedBoxTokenKey.ActiveBorderColor}}" />
|
||||
</Style>
|
||||
|
||||
<Style Selector="^[IsDropDownOpen=True]">
|
||||
<Setter Property="BorderBrush"
|
||||
Value="{DynamicResource {x:Static atom:AddOnDecoratedBoxTokenKey.ActiveBorderColor}}" />
|
||||
</Style>
|
||||
|
||||
<Style Selector="^[Status=Error]">
|
||||
<Setter Property="BorderBrush"
|
||||
Value="{DynamicResource {x:Static atom:SharedTokenKey.ColorError}}" />
|
||||
|
||||
<Style Selector="^[IsInnerBoxHover=True]">
|
||||
<Setter Property="BorderBrush"
|
||||
Value="{DynamicResource {x:Static atom:SharedTokenKey.ColorErrorBorderHover}}" />
|
||||
</Style>
|
||||
|
||||
<Style Selector="^:focus-within">
|
||||
<Setter Property="BorderBrush"
|
||||
Value="{DynamicResource {x:Static atom:SharedTokenKey.ColorError}}" />
|
||||
</Style>
|
||||
|
||||
<Style Selector="^:pressed">
|
||||
<Setter Property="BorderBrush"
|
||||
Value="{DynamicResource {x:Static atom:SharedTokenKey.ColorError}}" />
|
||||
</Style>
|
||||
|
||||
<Style Selector="^[IsDropDownOpen=True]">
|
||||
<Setter Property="BorderBrush"
|
||||
Value="{DynamicResource {x:Static atom:SharedTokenKey.ColorError}}" />
|
||||
</Style>
|
||||
</Style>
|
||||
<Style Selector="^[SizeType=Small]">
|
||||
<Style Selector="^ /template/ Border#PART_ContentFrame">
|
||||
<Setter Property="Padding"
|
||||
Value="{DynamicResource {x:Static atom:SelectTokenKey.MultiModePaddingSM}}" />
|
||||
|
||||
<Style Selector="^[Status=Warning]">
|
||||
<Setter Property="BorderBrush"
|
||||
Value="{DynamicResource {x:Static atom:SharedTokenKey.ColorWarning}}" />
|
||||
|
||||
<Style Selector="^[IsInnerBoxHover=True]">
|
||||
<Setter Property="BorderBrush"
|
||||
Value="{DynamicResource {x:Static atom:SharedTokenKey.ColorWarningBorderHover}}" />
|
||||
</Style>
|
||||
|
||||
<Style Selector="^:focus-within">
|
||||
<Setter Property="BorderBrush"
|
||||
Value="{DynamicResource {x:Static atom:SharedTokenKey.ColorWarning}}" />
|
||||
</Style>
|
||||
|
||||
<Style Selector="^:pressed">
|
||||
<Setter Property="BorderBrush"
|
||||
Value="{DynamicResource {x:Static atom:SharedTokenKey.ColorWarning}}" />
|
||||
</Style>
|
||||
<Style Selector="^[IsDropDownOpen=True]">
|
||||
<Setter Property="BorderBrush"
|
||||
Value="{DynamicResource {x:Static atom:SharedTokenKey.ColorWarning}}" />
|
||||
</Style>
|
||||
</Style>
|
||||
</Style>
|
||||
|
||||
<Style Selector="^[StyleVariant=Filled]">
|
||||
<Setter Property="BorderBrush" Value="Transparent" />
|
||||
<Setter Property="Background"
|
||||
Value="{DynamicResource {x:Static atom:SharedTokenKey.ColorFillTertiary}}" />
|
||||
|
||||
<Style Selector="^[IsInnerBoxHover=True]">
|
||||
<Setter Property="Background"
|
||||
Value="{DynamicResource {x:Static atom:SharedTokenKey.ColorFillSecondary}}" />
|
||||
</Style>
|
||||
|
||||
<Style Selector="^:focus-within">
|
||||
<Setter Property="BorderBrush"
|
||||
Value="{DynamicResource {x:Static atom:AddOnDecoratedBoxTokenKey.ActiveBorderColor}}" />
|
||||
<Setter Property="Background" Value="Transparent" />
|
||||
</Style>
|
||||
|
||||
<Style Selector="^:pressed">
|
||||
<Setter Property="BorderBrush"
|
||||
Value="{DynamicResource {x:Static atom:AddOnDecoratedBoxTokenKey.ActiveBorderColor}}" />
|
||||
</Style>
|
||||
|
||||
<Style Selector="^[IsDropDownOpen=True]">
|
||||
<Setter Property="BorderBrush"
|
||||
Value="{DynamicResource {x:Static atom:AddOnDecoratedBoxTokenKey.ActiveBorderColor}}" />
|
||||
</Style>
|
||||
|
||||
<Style Selector="^[Status=Error]">
|
||||
<Setter Property="BorderBrush"
|
||||
Value="Transparent" />
|
||||
<Setter Property="Background"
|
||||
Value="{DynamicResource {x:Static atom:SharedTokenKey.ColorErrorBg}}" />
|
||||
|
||||
<Style Selector="^[IsInnerBoxHover=True]">
|
||||
<Setter Property="Background"
|
||||
Value="{DynamicResource {x:Static atom:SharedTokenKey.ColorErrorBgHover}}" />
|
||||
</Style>
|
||||
|
||||
<Style Selector="^:focus-within">
|
||||
<Setter Property="BorderBrush"
|
||||
Value="{DynamicResource {x:Static atom:SharedTokenKey.ColorError}}" />
|
||||
<Setter Property="Background"
|
||||
Value="{DynamicResource {x:Static atom:AddOnDecoratedBoxTokenKey.ActiveBg}}" />
|
||||
</Style>
|
||||
|
||||
<Style Selector="^:pressed">
|
||||
<Setter Property="BorderBrush"
|
||||
Value="{DynamicResource {x:Static atom:SharedTokenKey.ColorError}}" />
|
||||
</Style>
|
||||
|
||||
<Style Selector="^[IsDropDownOpen=True]">
|
||||
<Setter Property="BorderBrush"
|
||||
Value="{DynamicResource {x:Static atom:SharedTokenKey.ColorError}}" />
|
||||
</Style>
|
||||
</Style>
|
||||
|
||||
<Style Selector="^[Status=Warning]">
|
||||
<Setter Property="BorderBrush" Value="Transparent" />
|
||||
<Setter Property="Background"
|
||||
Value="{DynamicResource {x:Static atom:SharedTokenKey.ColorWarningBg}}" />
|
||||
|
||||
<Style Selector="^[IsInnerBoxHover=True]">
|
||||
<Setter Property="Background"
|
||||
Value="{DynamicResource {x:Static atom:SharedTokenKey.ColorWarningBgHover}}" />
|
||||
</Style>
|
||||
|
||||
<Style Selector="^:focus-within">
|
||||
<Setter Property="BorderBrush"
|
||||
Value="{DynamicResource {x:Static atom:SharedTokenKey.ColorWarning}}" />
|
||||
<Setter Property="Background"
|
||||
Value="{DynamicResource {x:Static atom:AddOnDecoratedBoxTokenKey.ActiveBg}}" />
|
||||
</Style>
|
||||
|
||||
<Style Selector="^:pressed">
|
||||
<Setter Property="BorderBrush"
|
||||
Value="{DynamicResource {x:Static atom:SharedTokenKey.ColorWarning}}" />
|
||||
</Style>
|
||||
|
||||
<Style Selector="^[IsDropDownOpen=True]">
|
||||
<Setter Property="BorderBrush"
|
||||
Value="{DynamicResource {x:Static atom:SharedTokenKey.ColorWarning}}" />
|
||||
</Style>
|
||||
</Style>
|
||||
</Style>
|
||||
|
||||
@@ -66,14 +66,20 @@
|
||||
</Style>
|
||||
|
||||
<Style Selector="^[IsClearable=True]">
|
||||
<Style Selector="^[IsInputHover=True][IsSelectionEmpty=False]">
|
||||
<Style Selector="^ /template/ atom|Icon#OpenIndicator">
|
||||
<Setter Property="IsVisible" Value="False" />
|
||||
</Style>
|
||||
<Style Selector="^ /template/ atom|IconButton#PART_ClearButton">
|
||||
<Setter Property="IsVisible" Value="True" />
|
||||
<Style Selector="^[IsSelectionEmpty=False]">
|
||||
<Style Selector="^[IsInputHover=True]">
|
||||
<Style Selector="^ /template/ atom|Icon#OpenIndicator">
|
||||
<Setter Property="IsVisible" Value="False" />
|
||||
</Style>
|
||||
<Style Selector="^ /template/ atom|Icon#SearchIndicator">
|
||||
<Setter Property="IsVisible" Value="False" />
|
||||
</Style>
|
||||
<Style Selector="^ /template/ atom|IconButton#PART_ClearButton">
|
||||
<Setter Property="IsVisible" Value="True" />
|
||||
</Style>
|
||||
</Style>
|
||||
</Style>
|
||||
|
||||
</Style>
|
||||
|
||||
</ControlTheme>
|
||||
|
||||
@@ -7,12 +7,12 @@
|
||||
<Setter Property="Template">
|
||||
<ControlTemplate>
|
||||
<Panel Name="RootLayout">
|
||||
<WrapPanel Name="{x:Static atom:SelectResultOptionsBoxThemeConstants.DefaultPanelPart}"/>
|
||||
<atom:SelectWrapPanel Name="{x:Static atom:SelectResultOptionsBoxThemeConstants.DefaultPanelPart}"/>
|
||||
</Panel>
|
||||
</ControlTemplate>
|
||||
</Setter>
|
||||
|
||||
<Style Selector="^ /template/ WrapPanel#PART_DefaultPanel">
|
||||
<Style Selector="^ /template/ atom|SelectWrapPanel#PART_DefaultPanel">
|
||||
<Setter Property="ItemSpacing" Value="{DynamicResource {x:Static atom:SharedTokenKey.SpacingXXS}}"/>
|
||||
<Setter Property="LineSpacing" Value="{DynamicResource {x:Static atom:SharedTokenKey.SpacingXXS}}"/>
|
||||
</Style>
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
<ResourceDictionary
|
||||
xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:atom="https://atomui.net"
|
||||
xmlns:themes="using:AtomUI.Controls.Themes"
|
||||
x:ClassModifier="internal">
|
||||
<ControlTheme x:Key="{x:Type atom:SelectTag}" TargetType="atom:SelectTag">
|
||||
<ControlTheme.BasedOn>
|
||||
<themes:TagTheme TargetType="atom:SelectTag" />
|
||||
</ControlTheme.BasedOn>
|
||||
|
||||
<Style Selector="^:is(atom|SelectTag)">
|
||||
<Setter Property="Bordered" Value="False"/>
|
||||
<Setter Property="Background" Value="{DynamicResource {x:Static atom:SelectTokenKey.MultipleItemBg}}" />
|
||||
<Setter Property="IsClosable" Value="True" />
|
||||
<Setter Property="FontSize" Value="{DynamicResource {x:Static atom:SelectTokenKey.OptionFontSize}}" />
|
||||
</Style>
|
||||
|
||||
</ControlTheme>
|
||||
</ResourceDictionary>
|
||||
@@ -23,7 +23,8 @@
|
||||
ContentLeftAddOn="{TemplateBinding ContentLeftAddOn}"
|
||||
ContentLeftAddOnTemplate="{TemplateBinding ContentLeftAddOnTemplate}"
|
||||
Mode="{TemplateBinding Mode}"
|
||||
IsSelectionEmpty="{TemplateBinding IsSelectionEmpty}">
|
||||
IsSelectionEmpty="{TemplateBinding IsSelectionEmpty}"
|
||||
IsDropDownOpen="{TemplateBinding IsDropDownOpen}">
|
||||
<atom:AddOnDecoratedBox.ContentRightAddOn>
|
||||
<StackPanel Orientation="Horizontal"
|
||||
Spacing="{DynamicResource {x:Static atom:SharedTokenKey.SpacingXS}}">
|
||||
@@ -39,7 +40,8 @@
|
||||
IsClearable="{Binding IsAllowClear, RelativeSource={RelativeSource AncestorType=atom:Select}}"
|
||||
IsSelectionEmpty="{Binding IsSelectionEmpty, RelativeSource={RelativeSource AncestorType=atom:Select}}"
|
||||
IsDropDownOpen="{Binding IsDropDownOpen, RelativeSource={RelativeSource AncestorType=atom:Select}}"
|
||||
IsInputHover="{Binding IsInnerBoxHover, RelativeSource={RelativeSource AncestorType=atom:AddOnDecoratedBox}}"/>
|
||||
IsInputHover="{Binding IsInnerBoxHover, RelativeSource={RelativeSource AncestorType=atom:AddOnDecoratedBox}}"
|
||||
IsInputPressed="{Binding IsInnerBoxPressed, RelativeSource={RelativeSource AncestorType=atom:AddOnDecoratedBox}}"/>
|
||||
</StackPanel>
|
||||
</atom:AddOnDecoratedBox.ContentRightAddOn>
|
||||
<Panel>
|
||||
@@ -66,11 +68,14 @@
|
||||
Watermark="{TemplateBinding SelectedOption, Converter={StaticResource OptionHeaderConverter}}"/>
|
||||
<atom:SelectResultOptionsBox
|
||||
Name="SelectedOptionsBox"
|
||||
HorizontalAlignment="Left"
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Center"
|
||||
Mode="{TemplateBinding Mode}"
|
||||
SelectedOptions="{TemplateBinding SelectedOptions}"
|
||||
IsSearchEnabled="{TemplateBinding IsSearchEnabled}"
|
||||
IsVisible="False"/>
|
||||
IsDropDownOpen="{TemplateBinding IsDropDownOpen}"
|
||||
IsVisible="False"
|
||||
Focusable="True"/>
|
||||
</Panel>
|
||||
</atom:SelectAddOnDecoratedBox>
|
||||
<atom:Popup Name="{x:Static atom:SelectThemeConstants.PopupPart}"
|
||||
@@ -157,7 +162,9 @@
|
||||
<Style Selector="^ /template/ atom|SelectResultOptionsBox#SelectedOptionsBox">
|
||||
<Setter Property="IsVisible" Value="True" />
|
||||
</Style>
|
||||
|
||||
<Style Selector="^[IsSearchEnabled=False]">
|
||||
<Setter Property="Cursor" Value="Hand"/>
|
||||
</Style>
|
||||
<Style Selector="^ /template/ atom|SelectOptions#PART_OptionsBox">
|
||||
<Setter Property="IsShowSelectedIndicator" Value="True" />
|
||||
<Setter Property="SelectionMode" Value="Multiple" />
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
<ResourceInclude Source="SelectResultOptionsBoxTheme.axaml"/>
|
||||
<ResourceInclude Source="SelectSearchTextBoxTheme.axaml"/>
|
||||
<ResourceInclude Source="SelectTheme.axaml"/>
|
||||
<ResourceInclude Source="SelectTagTheme.axaml"/>
|
||||
<ResourceInclude Source="SelectOptionsTheme.axaml"/>
|
||||
<ResourceInclude Source="SelectOptionItemTheme.axaml"/>
|
||||
<ResourceInclude Source="SelectAddOnDecoratedBoxTheme.axaml"/>
|
||||
|
||||
Reference in New Issue
Block a user