using System; using System.Windows; using System.Windows.Controls; namespace CustomUI { public class ZToolTip : ToolTip { #region Private属性 private EnumPlacement mPlacement; #endregion #region 依赖属性定义 public static readonly DependencyProperty PlacementExProperty = DependencyProperty.Register("PlacementEx" , typeof(EnumPlacement), typeof(ZToolTip), new PropertyMetadata(EnumPlacement.TopLeft)); public static readonly DependencyProperty IsShowShadowProperty = DependencyProperty.Register("IsShowShadow" , typeof(bool), typeof(ZToolTip), new PropertyMetadata(true)); #endregion #region 依赖属性set get /// /// 鼠标按下时按钮的背景色 /// public EnumPlacement PlacementEx { get { return (EnumPlacement)GetValue(PlacementExProperty); } set { SetValue(PlacementExProperty, value); } } /// /// 是否显示阴影 /// public bool IsShowShadow { get { return (bool)GetValue(IsShowShadowProperty); } set { SetValue(IsShowShadowProperty, value); } } #endregion #region Constructors static ZToolTip() { DefaultStyleKeyProperty.OverrideMetadata(typeof(ZToolTip), new FrameworkPropertyMetadata(typeof(ZToolTip))); } #endregion #region Override方法 public ZToolTip() { this.Initialized += (o, e) => { this.mPlacement = this.PlacementEx; }; } protected override void OnOpened(RoutedEventArgs e) { //当在原本设置的位置显示Tooptip时,发现位置不够,重新设置ToopTip的Placement if(this.PlacementTarget != null) { double workAreaX = SystemParameters.WorkArea.Width;//得到屏幕工作区域宽度 double workAreaY = SystemParameters.WorkArea.Height;//得到屏幕工作区域高度 FrameworkElement control = this.PlacementTarget as FrameworkElement; double controlWidth = control.ActualWidth; double controlHeight = control.ActualHeight; Point p = this.PlacementTarget.PointFromScreen(new Point(0, 0)); if(p != null) { double pointX = Math.Abs(p.X); //得到控件在屏幕中的X坐标 double pointY = Math.Abs(p.Y); switch (this.mPlacement) { case EnumPlacement.LeftTop: this.SetLeftPosition(pointX, EnumPlacement.RightTop); break; case EnumPlacement.LeftBottom: this.SetLeftPosition(pointX, EnumPlacement.RightBottom); break; case EnumPlacement.LeftCenter: this.SetLeftPosition(pointX, EnumPlacement.RightCenter); break; case EnumPlacement.RightTop: SetRightPosition(workAreaX, controlWidth, pointX, EnumPlacement.LeftTop); break; case EnumPlacement.RightBottom: SetRightPosition(workAreaX, controlWidth, pointX, EnumPlacement.LeftBottom); break; case EnumPlacement.RightCenter: SetRightPosition(workAreaX, controlWidth, pointX, EnumPlacement.LeftCenter); break; case EnumPlacement.TopLeft: this.SetTopPosition(pointY, EnumPlacement.BottomLeft); break; case EnumPlacement.TopCenter: this.SetTopPosition(pointY, EnumPlacement.BottomCenter); break; case EnumPlacement.TopRight: this.SetTopPosition(pointY, EnumPlacement.BottomRight); break; case EnumPlacement.BottomLeft: SetBottomPosition(workAreaY, controlHeight, pointY, EnumPlacement.TopLeft); break; case EnumPlacement.BottomCenter: SetBottomPosition(workAreaY, controlHeight, pointY, EnumPlacement.TopCenter); break; case EnumPlacement.BottomRight: SetBottomPosition(workAreaY, controlHeight, pointY, EnumPlacement.TopRight); break; default: break; } } } base.OnOpened(e); } #endregion; #region Private方法 private void SetBottomPosition(double workAreaY, double controlHeight, double pointY, EnumPlacement placement) { if (workAreaY - (pointY + controlHeight) < this.ActualHeight) { this.PlacementEx = placement; } else { this.PlacementEx = this.mPlacement; } } private void SetTopPosition(double pointY, EnumPlacement placement) { if (pointY < this.ActualHeight) { this.PlacementEx = placement; } else { this.PlacementEx = this.mPlacement; } } private void SetRightPosition(double workAreaX, double controlWidth, double pointX, EnumPlacement placement) { if (workAreaX - (pointX + controlWidth) < this.ActualWidth) { this.PlacementEx = placement; } else { this.PlacementEx = this.mPlacement; } } private void SetLeftPosition(double pointX, EnumPlacement placement) { if (pointX < this.ActualWidth) { this.PlacementEx = placement; } else { this.PlacementEx = this.mPlacement; } } #endregion } }