/
anna_grinchenko
/
ReactiveUISample
Обзор
Документация
Войти
/
anna_grinchenko
/
ReactiveUISample
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
Controls/EditableTextBlock.cs
136 строк
5 KB
GrinchenkoAnna
Первый символ группы в заголовке меняет цвет в зависимости от принадлежности к:
13 июл 2026, 15:34
13 июл 2026, 15:34
1ddea67
Код
Авторство
О чём код?
using Avalonia; using Avalonia.Controls; using Avalonia.Controls.Primitives; using Avalonia.Input; using Avalonia.Interactivity; using Avalonia.Media; using ReactiveUI.SourceGenerators; using System; using System.Windows.Input; namespace ReactiveUISample.Controls { public class EditableTextBlock : TemplatedControl { private TextBlock? _displayedTextBlock; private TextBox? _editTextBox; private bool _isEditing; public string Text { get => GetValue(TextProperty); set => SetValue(TextProperty, value); } public static readonly StyledProperty<string> TextProperty = AvaloniaProperty.Register<EditableTextBlock, string>(nameof(Text), defaultValue: string.Empty); public event EventHandler<RoutedEventArgs> TextChanged; public static readonly RoutedEvent<RoutedEventArgs> TextChangedEvent = RoutedEvent.Register<EditableTextBlock, RoutedEventArgs>(nameof(TextChanged), routingStrategy: RoutingStrategies.Bubble); private IBrush? _headerForeground; public IBrush? HeaderForeground { get => _headerForeground; set => SetAndRaise(HeaderForegroundProperty, ref _headerForeground, value); } public static readonly DirectProperty<EditableTextBlock, IBrush?> HeaderForegroundProperty = AvaloniaProperty.RegisterDirect<EditableTextBlock, IBrush?>(nameof(HeaderForeground), o => o.HeaderForeground, (o, v) => o.HeaderForeground = v); public EditableTextBlock() { if (Application.Current is not null) Application.Current.ActualThemeVariantChanged += (_,_) => UpdateHeaderForeground(); TextProperty.Changed.AddClassHandler<EditableTextBlock>((_,_) => UpdateHeaderForeground()); } protected override void OnApplyTemplate(TemplateAppliedEventArgs e) { base.OnApplyTemplate(e); _displayedTextBlock = e.NameScope.Find<TextBlock>("PART_DisplayTextBlock"); _editTextBox = e.NameScope.Find<TextBox>("PART_EditTextBox"); if (_displayedTextBlock is not null) _displayedTextBlock.DoubleTapped += OnDoubleTapped; if (_editTextBox is not null) { _editTextBox.LostFocus += OnLostFocus; _editTextBox.KeyDown += OnKeyDown; } UpdateHeaderForeground(); } private void OnDoubleTapped(object? sender, RoutedEventArgs e) { if (_displayedTextBlock is null || _editTextBox is null) return; _isEditing = true; _displayedTextBlock.IsVisible = false; _editTextBox.IsVisible = true; _editTextBox.Focus(); _editTextBox.SelectAll(); _editTextBox.Text = Text; } private void ExitEditing(bool commit) { if (_displayedTextBlock is null || _editTextBox is null) return; if (!_isEditing) return; _isEditing = false; if (commit && _editTextBox.Text != Text) { Text = _editTextBox.Text; RaiseEvent(new RoutedEventArgs(TextChangedEvent)); } _editTextBox.IsVisible = false; _displayedTextBlock.IsVisible = true; } private void OnLostFocus(object? sender, RoutedEventArgs e) { ExitEditing(commit: true); } private void OnKeyDown(object? sender, KeyEventArgs e) { if (e.Key == Key.Enter) { ExitEditing(commit: true); e.Handled = true; } else if (e.Key == Key.Escape) { ExitEditing(commit: false); e.Handled = true; } } private void UpdateHeaderForeground() { var key = Text; var app = Application.Current; if (app is null || string.IsNullOrEmpty(key)) { HeaderForeground = Brushes.Gray; return; } char firstChar = key[0]; string resourceKey = firstChar switch { >= 'A' and <= 'Z' => "GroupHeaderLatinBrush", >= 'А' and <= 'Я' or 'Ё' => "GroupHeaderCyrillicBrush", >= '0' and <= '9' => "GroupHeaderDigitBrush", _ => "GroupHeaderDefaultBrush" }; if (app.Resources.TryGetResource(resourceKey, app.ActualThemeVariant, out var brush)) HeaderForeground = brush as IBrush; else HeaderForeground = Brushes.Gray; } } }