ToolStripDropDown.PopupWrapper.cs 3.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. using System.Windows.Controls.Primitives;
  2. using System.Windows.Media.Effects;
  3. namespace System.Windows.Forms
  4. {
  5. public partial class ToolStripDropDown
  6. {
  7. private class PopupWrapper : IPopupWrapper
  8. {
  9. private System.Windows.Controls.StackPanel panel;
  10. private System.Windows.Controls.Primitives.Popup popup;
  11. private System.Windows.Controls.Border border;
  12. public bool IsOpen
  13. {
  14. get => popup.IsOpen;
  15. set => popup.IsOpen = value;
  16. }
  17. public PlacementMode Placement { get => popup.Placement; set => popup.Placement = value; }
  18. public UIElement PlacementTarget { get => popup.PlacementTarget; set => popup.PlacementTarget = value; }
  19. public double HorizontalOffset { get => popup.HorizontalOffset; set => popup.HorizontalOffset = value; }
  20. public double VerticalOffset { get => popup.VerticalOffset; set => popup.VerticalOffset = value; }
  21. public event EventHandler Opened;
  22. public event EventHandler Closed;
  23. public void AddChild(Control child) => panel.Children.Add(child.control);
  24. public void RemoveChild(Control child) => panel.Children.Remove(child.control);
  25. public void SetChildIndex(Control child, int index) => panel.Children.Insert(index, child.control);
  26. public void ApplyStyle(ToolStripProfessionalRenderer r) { }
  27. public void FixupDpi()
  28. {
  29. if (popup.PlacementTarget != null)
  30. {
  31. double sc1 = Helper.GetDpiScale(panel);
  32. double sc2 = Helper.GetDpiScale(popup.PlacementTarget);
  33. if (Math.Abs(sc1 - sc2) > 0.01)
  34. {
  35. // dpi is different, refresh the control
  36. popup.IsOpen = true;
  37. popup.IsOpen = false;
  38. }
  39. }
  40. }
  41. public PopupWrapper(Control owner)
  42. {
  43. // it will contain children
  44. panel = new();
  45. popup = new();
  46. popup.UseLayoutRounding = true;
  47. popup.StaysOpen = false;
  48. popup.AllowsTransparency = true;
  49. popup.PopupAnimation = PopupAnimation.Slide;
  50. popup.Tag = owner;
  51. border = new()
  52. {
  53. Margin = new Thickness(0, 0, 3, 3),
  54. BorderBrush = System.Windows.SystemColors.ActiveBorderBrush,
  55. BorderThickness = new Thickness(1),
  56. Background = System.Windows.SystemColors.WindowBrush
  57. };
  58. border.Effect = new DropShadowEffect()
  59. {
  60. Color = System.Windows.Media.Colors.Gray,
  61. Opacity = 0.5,
  62. ShadowDepth = 3,
  63. Direction = 315
  64. };
  65. popup.Child = border;
  66. border.Child = panel;
  67. popup.Opened += (s, e) => Opened?.Invoke(this, e);
  68. popup.Closed += (s, e) => Closed?.Invoke(this, e);
  69. }
  70. }
  71. }
  72. }