ZToolTip.cs 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. using System;
  2. using System.Windows;
  3. using System.Windows.Controls;
  4. namespace CustomUI
  5. {
  6. public class ZToolTip : ToolTip
  7. {
  8. #region Private属性
  9. private EnumPlacement mPlacement;
  10. #endregion
  11. #region 依赖属性定义
  12. public static readonly DependencyProperty PlacementExProperty = DependencyProperty.Register("PlacementEx"
  13. , typeof(EnumPlacement), typeof(ZToolTip), new PropertyMetadata(EnumPlacement.TopLeft));
  14. public static readonly DependencyProperty IsShowShadowProperty = DependencyProperty.Register("IsShowShadow"
  15. , typeof(bool), typeof(ZToolTip), new PropertyMetadata(true));
  16. #endregion
  17. #region 依赖属性set get
  18. /// <summary>
  19. /// 鼠标按下时按钮的背景色
  20. /// </summary>
  21. public EnumPlacement PlacementEx
  22. {
  23. get { return (EnumPlacement)GetValue(PlacementExProperty); }
  24. set { SetValue(PlacementExProperty, value); }
  25. }
  26. /// <summary>
  27. /// 是否显示阴影
  28. /// </summary>
  29. public bool IsShowShadow
  30. {
  31. get { return (bool)GetValue(IsShowShadowProperty); }
  32. set { SetValue(IsShowShadowProperty, value); }
  33. }
  34. #endregion
  35. #region Constructors
  36. static ZToolTip()
  37. {
  38. DefaultStyleKeyProperty.OverrideMetadata(typeof(ZToolTip), new FrameworkPropertyMetadata(typeof(ZToolTip)));
  39. }
  40. #endregion
  41. #region Override方法
  42. public ZToolTip()
  43. {
  44. this.Initialized += (o, e) =>
  45. {
  46. this.mPlacement = this.PlacementEx;
  47. };
  48. }
  49. protected override void OnOpened(RoutedEventArgs e)
  50. {
  51. //当在原本设置的位置显示Tooptip时,发现位置不够,重新设置ToopTip的Placement
  52. if(this.PlacementTarget != null)
  53. {
  54. double workAreaX = SystemParameters.WorkArea.Width;//得到屏幕工作区域宽度
  55. double workAreaY = SystemParameters.WorkArea.Height;//得到屏幕工作区域高度
  56. FrameworkElement control = this.PlacementTarget as FrameworkElement;
  57. double controlWidth = control.ActualWidth;
  58. double controlHeight = control.ActualHeight;
  59. Point p = this.PlacementTarget.PointFromScreen(new Point(0, 0));
  60. if(p != null)
  61. {
  62. double pointX = Math.Abs(p.X); //得到控件在屏幕中的X坐标
  63. double pointY = Math.Abs(p.Y);
  64. switch (this.mPlacement)
  65. {
  66. case EnumPlacement.LeftTop:
  67. this.SetLeftPosition(pointX, EnumPlacement.RightTop);
  68. break;
  69. case EnumPlacement.LeftBottom:
  70. this.SetLeftPosition(pointX, EnumPlacement.RightBottom);
  71. break;
  72. case EnumPlacement.LeftCenter:
  73. this.SetLeftPosition(pointX, EnumPlacement.RightCenter);
  74. break;
  75. case EnumPlacement.RightTop:
  76. SetRightPosition(workAreaX, controlWidth, pointX, EnumPlacement.LeftTop);
  77. break;
  78. case EnumPlacement.RightBottom:
  79. SetRightPosition(workAreaX, controlWidth, pointX, EnumPlacement.LeftBottom);
  80. break;
  81. case EnumPlacement.RightCenter:
  82. SetRightPosition(workAreaX, controlWidth, pointX, EnumPlacement.LeftCenter);
  83. break;
  84. case EnumPlacement.TopLeft:
  85. this.SetTopPosition(pointY, EnumPlacement.BottomLeft);
  86. break;
  87. case EnumPlacement.TopCenter:
  88. this.SetTopPosition(pointY, EnumPlacement.BottomCenter);
  89. break;
  90. case EnumPlacement.TopRight:
  91. this.SetTopPosition(pointY, EnumPlacement.BottomRight);
  92. break;
  93. case EnumPlacement.BottomLeft:
  94. SetBottomPosition(workAreaY, controlHeight, pointY, EnumPlacement.TopLeft);
  95. break;
  96. case EnumPlacement.BottomCenter:
  97. SetBottomPosition(workAreaY, controlHeight, pointY, EnumPlacement.TopCenter);
  98. break;
  99. case EnumPlacement.BottomRight:
  100. SetBottomPosition(workAreaY, controlHeight, pointY, EnumPlacement.TopRight);
  101. break;
  102. default:
  103. break;
  104. }
  105. }
  106. }
  107. base.OnOpened(e);
  108. }
  109. #endregion;
  110. #region Private方法
  111. private void SetBottomPosition(double workAreaY, double controlHeight, double pointY, EnumPlacement placement)
  112. {
  113. if (workAreaY - (pointY + controlHeight) < this.ActualHeight)
  114. {
  115. this.PlacementEx = placement;
  116. }
  117. else
  118. {
  119. this.PlacementEx = this.mPlacement;
  120. }
  121. }
  122. private void SetTopPosition(double pointY, EnumPlacement placement)
  123. {
  124. if (pointY < this.ActualHeight)
  125. {
  126. this.PlacementEx = placement;
  127. }
  128. else
  129. {
  130. this.PlacementEx = this.mPlacement;
  131. }
  132. }
  133. private void SetRightPosition(double workAreaX, double controlWidth, double pointX, EnumPlacement placement)
  134. {
  135. if (workAreaX - (pointX + controlWidth) < this.ActualWidth)
  136. {
  137. this.PlacementEx = placement;
  138. }
  139. else
  140. {
  141. this.PlacementEx = this.mPlacement;
  142. }
  143. }
  144. private void SetLeftPosition(double pointX, EnumPlacement placement)
  145. {
  146. if (pointX < this.ActualWidth)
  147. {
  148. this.PlacementEx = placement;
  149. }
  150. else
  151. {
  152. this.PlacementEx = this.mPlacement;
  153. }
  154. }
  155. #endregion
  156. }
  157. }