FocusBehavior.cs 1.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. using System.Reactive;
  2. using System.Reactive.Disposables;
  3. using Avalonia.Controls;
  4. using Avalonia.Data;
  5. using Avalonia.Threading;
  6. namespace Avalonia.Xaml.Interactions.Custom;
  7. /// <summary>
  8. ///
  9. /// </summary>
  10. public class FocusBehavior : DisposingBehavior<Control>
  11. {
  12. /// <summary>
  13. ///
  14. /// </summary>
  15. public static readonly StyledProperty<bool> IsFocusedProperty =
  16. AvaloniaProperty.Register<FocusBehavior, bool>(nameof(IsFocused), defaultBindingMode: BindingMode.TwoWay);
  17. /// <summary>
  18. ///
  19. /// </summary>
  20. public bool IsFocused
  21. {
  22. get => GetValue(IsFocusedProperty);
  23. set => SetValue(IsFocusedProperty, value);
  24. }
  25. /// <summary>
  26. ///
  27. /// </summary>
  28. /// <param name="disposables"></param>
  29. protected override void OnAttached(CompositeDisposable disposables)
  30. {
  31. if (AssociatedObject is not null)
  32. {
  33. disposables.Add(AssociatedObject.GetObservable(Avalonia.Input.InputElement.IsFocusedProperty)
  34. .Subscribe(new AnonymousObserver<bool>(
  35. focused =>
  36. {
  37. if (!focused)
  38. {
  39. SetCurrentValue(IsFocusedProperty, false);
  40. }
  41. })));
  42. disposables.Add(this.GetObservable(IsFocusedProperty)
  43. .Subscribe(new AnonymousObserver<bool>(
  44. focused =>
  45. {
  46. if (focused)
  47. {
  48. Dispatcher.UIThread.Post(() => AssociatedObject?.Focus());
  49. }
  50. })));
  51. }
  52. }
  53. }