123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205 |
- using Avalonia;
- using Avalonia.Controls;
- using Avalonia.Controls.Metadata;
- using Avalonia.Controls.Primitives;
- using Avalonia.LogicalTree;
- using Avalonia.Media;
- using Avalonia.Metadata;
- using Avalonia.Threading;
- using CommunityToolkit.Mvvm.Input;
- using System;
- using System.Collections;
- using System.Collections.Generic;
- using System.Collections.ObjectModel;
- using System.Collections.Specialized;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- using System.Windows.Input;
- namespace InABox.Avalonia.Components;
- public partial class ButtonStrip : TemplatedControl
- {
- public static StyledProperty<IBrush?> SelectedBackgroundProperty = AvaloniaProperty.Register<ButtonStripItem, IBrush?>(
- nameof(SelectedBackground));
- public static StyledProperty<IBrush?> SelectedForegroundProperty = AvaloniaProperty.Register<ButtonStripItem, IBrush?>(
- nameof(SelectedForeground));
- public static StyledProperty<double> ItemSpacingProperty = AvaloniaProperty.Register<ButtonStripItem, double>(
- nameof(ItemSpacing));
- public static StyledProperty<ObservableCollection<ButtonStripItem>> ItemsProperty =
- AvaloniaProperty.Register<ButtonStripItem, ObservableCollection<ButtonStripItem>>(nameof(Items));
- public IBrush? SelectedBackground
- {
- get => GetValue(SelectedBackgroundProperty);
- set => SetValue(SelectedBackgroundProperty, value);
- }
- public IBrush? SelectedForeground
- {
- get => GetValue(SelectedForegroundProperty);
- set => SetValue(SelectedForegroundProperty, value);
- }
- public double ItemSpacing
- {
- get => GetValue(ItemSpacingProperty);
- set => SetValue(ItemSpacingProperty, value);
- }
- [Content]
- public ObservableCollection<ButtonStripItem> Items
- {
- get => GetValue(ItemsProperty);
- set => SetValue(ItemsProperty, value);
- }
- public ButtonStripItem? SelectedItem
- {
- get => Items.FirstOrDefault(x => x.Selected);
- set
- {
- foreach(var item in Items)
- {
- item.Selected = item == value;
- }
- }
- }
- public event EventHandler? SelectionChanged;
- static ButtonStrip()
- {
- ItemsProperty.Changed.AddClassHandler<ButtonStrip>(Items_Changed);
- }
- private static void Items_Changed(ButtonStrip strip, AvaloniaPropertyChangedEventArgs args)
- {
- strip.LogicalChildren.Clear();
- if (strip.Items is not null)
- {
- strip.SelectedItem = strip.Items.FirstOrDefault();
- strip.LogicalChildren.AddRange(strip.Items);
- foreach(var item in strip.Items)
- {
- item.Command = strip.ItemSelectedCommand;
- }
- }
- }
- public ButtonStrip()
- {
- Items = new();
- Items.CollectionChanged += Items_CollectionChanged;
- }
- private void Items_CollectionChanged(object? sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
- {
- SelectedItem ??= Items.FirstOrDefault();
- switch (e.Action)
- {
- case NotifyCollectionChangedAction.Add:
- AddControlItemsToLogicalChildren(e.NewItems);
- break;
- case NotifyCollectionChangedAction.Remove:
- RemoveControlItemsFromLogicalChildren(e.OldItems);
- break;
- }
- foreach(var item in Items)
- {
- item.Command = ItemSelectedCommand;
- }
- }
- private void AddControlItemsToLogicalChildren(IEnumerable? items)
- {
- if (items is null) return;
- List<ILogical>? toAdd = null;
- foreach(var i in items)
- {
- if(i is Control control && !LogicalChildren.Contains(control))
- {
- toAdd ??= new();
- toAdd.Add(control);
- }
- }
- if(toAdd is not null)
- {
- LogicalChildren.AddRange(toAdd);
- }
- }
- private void RemoveControlItemsFromLogicalChildren(IEnumerable? items)
- {
- if (items is null) return;
- List<ILogical>? toRemove = null;
- foreach(var i in items)
- {
- if(i is Control control)
- {
- toRemove ??= new();
- toRemove.Add(control);
- }
- }
- if(toRemove is not null)
- {
- LogicalChildren.RemoveAll(toRemove);
- }
- }
- [RelayCommand]
- private void ItemSelected(ButtonStripItem item)
- {
- var children = this.GetLogicalChildren().ToArray();
- SelectedItem = item;
- }
- public void AddRange(IEnumerable<string> items)
- {
- foreach(var item in items)
- {
- Items.Add(new() { Text = item });
- }
- }
- }
- [PseudoClasses(":selected")]
- public class ButtonStripItem : TemplatedControl
- {
- public static StyledProperty<string> TextProperty = AvaloniaProperty.Register<ButtonStripItem, string>(nameof(Text));
- public static StyledProperty<bool> SelectedProperty = AvaloniaProperty.Register<ButtonStripItem, bool>(nameof(Selected));
- public static StyledProperty<int> IndexProperty = AvaloniaProperty.Register<ButtonStripItem, int>(nameof(Index));
- public static StyledProperty<ICommand> CommandProperty = AvaloniaProperty.Register<ButtonStripItem, ICommand>(nameof(Command));
- public string Text
- {
- get => GetValue(TextProperty);
- set => SetValue(TextProperty, value);
- }
- public bool Selected
- {
- get => GetValue(SelectedProperty);
- set => SetValue(SelectedProperty, value);
- }
- public int Index
- {
- get => GetValue(IndexProperty);
- set => SetValue(IndexProperty, value);
- }
- public ICommand Command
- {
- get => GetValue(CommandProperty);
- set => SetValue(CommandProperty, value);
- }
- static ButtonStripItem()
- {
- SelectedProperty.Changed.AddClassHandler<ButtonStripItem>(Selected_Changed);
- }
- private static void Selected_Changed(ButtonStripItem item, AvaloniaPropertyChangedEventArgs args)
- {
- item.PseudoClasses.Set(":selected", item.Selected);
- }
- }
|