ControlExtensions.cs 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. // Copyright (c) The Avalonia Project. All rights reserved.
  2. // Licensed under the MIT license. See licence.md file in the project root for full license information.
  3. using System;
  4. using System.Linq;
  5. using Avalonia.Data;
  6. using Avalonia.LogicalTree;
  7. using Avalonia.Styling;
  8. namespace Avalonia.Controls
  9. {
  10. /// <summary>
  11. /// Adds common functionality to <see cref="IControl"/>.
  12. /// </summary>
  13. public static class ControlExtensions
  14. {
  15. /// <summary>
  16. /// Tries to bring the control into view.
  17. /// </summary>
  18. /// <param name="control">The control.</param>
  19. public static void BringIntoView(this IControl control)
  20. {
  21. Contract.Requires<ArgumentNullException>(control != null);
  22. control.BringIntoView(new Rect(control.Bounds.Size));
  23. }
  24. /// <summary>
  25. /// Tries to bring the control into view.
  26. /// </summary>
  27. /// <param name="control">The control.</param>
  28. /// <param name="rect">The area of the control to being into view.</param>
  29. public static void BringIntoView(this IControl control, Rect rect)
  30. {
  31. Contract.Requires<ArgumentNullException>(control != null);
  32. var ev = new RequestBringIntoViewEventArgs
  33. {
  34. RoutedEvent = Control.RequestBringIntoViewEvent,
  35. TargetObject = control,
  36. TargetRect = rect,
  37. };
  38. control.RaiseEvent(ev);
  39. }
  40. /// <summary>
  41. /// Finds the named control in the scope of the specified control.
  42. /// </summary>
  43. /// <typeparam name="T">The type of the control to find.</typeparam>
  44. /// <param name="control">The control to look in.</param>
  45. /// <param name="name">The name of the control to find.</param>
  46. /// <returns>The control or null if not found.</returns>
  47. public static T FindControl<T>(this IControl control, string name) where T : class, IControl
  48. {
  49. Contract.Requires<ArgumentNullException>(control != null);
  50. Contract.Requires<ArgumentNullException>(name != null);
  51. var nameScope = control.FindNameScope();
  52. if (nameScope == null)
  53. {
  54. throw new InvalidOperationException("Could not find parent name scope.");
  55. }
  56. return nameScope.Find<T>(name);
  57. }
  58. /// <summary>
  59. /// Adds or removes a pseudoclass depending on a boolean value.
  60. /// </summary>
  61. /// <param name="classes">The pseudoclasses collection.</param>
  62. /// <param name="name">The name of the pseudoclass to set.</param>
  63. /// <param name="value">True to add the pseudoclass or false to remove.</param>
  64. public static void Set(this IPseudoClasses classes, string name, bool value)
  65. {
  66. Contract.Requires<ArgumentNullException>(classes != null);
  67. if (value)
  68. {
  69. classes.Add(name);
  70. }
  71. else
  72. {
  73. classes.Remove(name);
  74. }
  75. }
  76. /// <summary>
  77. /// Sets a pseudoclass depending on an observable trigger.
  78. /// </summary>
  79. /// <param name="classes">The pseudoclasses collection.</param>
  80. /// <param name="name">The name of the pseudoclass to set.</param>
  81. /// <param name="trigger">The trigger: true adds the pseudoclass, false removes.</param>
  82. /// <returns>A disposable used to cancel the subscription.</returns>
  83. public static IDisposable Set(this IPseudoClasses classes, string name, IObservable<bool> trigger)
  84. {
  85. Contract.Requires<ArgumentNullException>(classes != null);
  86. return trigger.Subscribe(x => classes.Set(name, x));
  87. }
  88. }
  89. }