VisualHelper.cs 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. using System;
  2. using System.Linq;
  3. using System.Windows;
  4. using System.Windows.Interop;
  5. using System.Windows.Media;
  6. using HandyControl.Tools.Interop;
  7. namespace HandyControl.Tools;
  8. public static class VisualHelper
  9. {
  10. internal static VisualStateGroup TryGetVisualStateGroup(DependencyObject d, string groupName)
  11. {
  12. var root = GetImplementationRoot(d);
  13. if (root == null) return null;
  14. return VisualStateManager
  15. .GetVisualStateGroups(root)?
  16. .OfType<VisualStateGroup>()
  17. .FirstOrDefault(group => string.CompareOrdinal(groupName, group.Name) == 0);
  18. }
  19. internal static FrameworkElement GetImplementationRoot(DependencyObject d) =>
  20. 1 == VisualTreeHelper.GetChildrenCount(d)
  21. ? VisualTreeHelper.GetChild(d, 0) as FrameworkElement
  22. : null;
  23. public static T GetChild<T>(DependencyObject d) where T : DependencyObject
  24. {
  25. if (d == null) return default;
  26. if (d is T t) return t;
  27. for (var i = 0; i < VisualTreeHelper.GetChildrenCount(d); i++)
  28. {
  29. var child = VisualTreeHelper.GetChild(d, i);
  30. var result = GetChild<T>(child);
  31. if (result != null) return result;
  32. }
  33. return default;
  34. }
  35. public static T GetParent<T>(DependencyObject d) where T : DependencyObject =>
  36. d switch
  37. {
  38. null => default,
  39. T t => t,
  40. Window _ => null,
  41. _ => GetParent<T>(VisualTreeHelper.GetParent(d))
  42. };
  43. public static IntPtr GetHandle(this Visual visual) => (PresentationSource.FromVisual(visual) as HwndSource)?.Handle ?? IntPtr.Zero;
  44. internal static void HitTestVisibleElements(Visual visual, HitTestResultCallback resultCallback, HitTestParameters parameters) =>
  45. VisualTreeHelper.HitTest(visual, ExcludeNonVisualElements, resultCallback, parameters);
  46. private static HitTestFilterBehavior ExcludeNonVisualElements(DependencyObject potentialHitTestTarget)
  47. {
  48. if (!(potentialHitTestTarget is Visual)) return HitTestFilterBehavior.ContinueSkipSelfAndChildren;
  49. if (!(potentialHitTestTarget is UIElement uIElement) || uIElement.IsVisible && uIElement.IsEnabled)
  50. return HitTestFilterBehavior.Continue;
  51. return HitTestFilterBehavior.ContinueSkipSelfAndChildren;
  52. }
  53. internal static bool ModifyStyle(IntPtr hWnd, int styleToRemove, int styleToAdd)
  54. {
  55. var windowLong = InteropMethods.GetWindowLong(hWnd, InteropValues.GWL.STYLE);
  56. var num = (windowLong & ~styleToRemove) | styleToAdd;
  57. if (num == windowLong) return false;
  58. InteropMethods.SetWindowLong(hWnd, InteropValues.GWL.STYLE, num);
  59. return true;
  60. }
  61. }