using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows.Controls; using System.Windows.Media; using System.Windows.Input; using System.Windows; using MetroGauges.Controls.DrawTools; namespace MetroGauges.Controls { public class MapBase : UserControl { public DrawToolBase CrrentDrawTool { get; set; } protected ScaleTransform _MapRootScale; protected TranslateTransform _MapRootTranslate; protected event EventHandler BaseLoadedHander; protected Grid m_Root; protected Grid m_ChildContainer; //键盘事件使用 protected TextBox m_RootKeyHook; //右键菜单控件 protected System.Windows.Controls.ContextMenu m_ContextMenu; bool m_CancelMove = false; bool m_CanWheel = true; public bool DisabledMove { get; set; } public bool CancelMove { set { m_CancelMove = value; if (m_CancelMove) { m_Root.MouseLeftButtonDown -= this.m_Root_MouseLeftButtonDown; m_Root.MouseLeftButtonUp -= this.m_Root_MouseLeftButtonUp; m_Root.MouseRightButtonUp -= this.m_Root_MouseRightButtonUp; m_Root.MouseRightButtonDown -= this.m_Root_MouseRightButtonDown; m_Root.MouseMove -= this.m_Root_MouseMove; m_Root.MouseWheel -= this.m_Root_MouseWheel; } } get { return m_CancelMove; } } public bool CanWheel { set { m_CanWheel = value; } } public MapBase() { m_ContextMenu = new System.Windows.Controls.ContextMenu(); } public override void OnApplyTemplate() { base.OnApplyTemplate(); if (m_Root != null) { m_Root.Clip = null; m_Root.SizeChanged -= this.m_Root_SizeChanged; m_Root.MouseLeftButtonDown -= this.m_Root_MouseLeftButtonDown; m_Root.MouseLeftButtonUp -= this.m_Root_MouseLeftButtonUp; m_Root.MouseRightButtonUp -= this.m_Root_MouseRightButtonUp; m_Root.MouseRightButtonDown -= this.m_Root_MouseRightButtonDown; m_Root.MouseMove -= this.m_Root_MouseMove; m_Root.MouseWheel -= this.m_Root_MouseWheel; m_Root.KeyDown -= this.m_Root_KeyDown; m_Root.KeyUp -= this.m_Root_KeyUp; } _MapRootScale = null; _MapRootTranslate = null; if (m_Root != null) { m_Root.SizeChanged += this.m_Root_SizeChanged; m_Root.MouseLeftButtonDown += this.m_Root_MouseLeftButtonDown; m_Root.MouseLeftButtonUp += this.m_Root_MouseLeftButtonUp; m_Root.MouseRightButtonUp += this.m_Root_MouseRightButtonUp; m_Root.MouseRightButtonDown += this.m_Root_MouseRightButtonDown; m_Root.MouseDown += M_Root_MouseDown; m_Root.MouseUp += M_Root_MouseUp; m_Root.MouseMove += this.m_Root_MouseMove; m_Root.MouseWheel += this.m_Root_MouseWheel; m_Root.KeyDown += this.m_Root_KeyDown; m_Root.KeyUp += this.m_Root_KeyUp; TransformGroup tg = new TransformGroup(); _MapRootScale = new ScaleTransform() { ScaleX = 1, ScaleY = 1 }; _MapRootTranslate = new TranslateTransform() { X = 0, Y = 0 }; tg.Children.Add(_MapRootScale); tg.Children.Add(_MapRootTranslate); m_ChildContainer.RenderTransform = tg; } m_Root_SizeChanged(null, null); if (BaseLoadedHander != null) BaseLoadedHander(this, null); } #region FindGeometrys /// /// /// /// /// /// internal FrameworkElement FindGeometry(Type type, MouseButtonEventArgs e) { System.Windows.Point p = e.GetPosition(m_Root); HitTestResult hitResult = VisualTreeHelper.HitTest(m_Root, p); if (hitResult == null || hitResult.VisualHit == null) return null; if (hitResult.VisualHit is FrameworkElement) { FrameworkElement el = hitResult.VisualHit as FrameworkElement; while (el != null) { if (el.GetType().FullName == type.FullName) return el; else el = el.Parent as FrameworkElement; } } return null; } /// /// /// /// /// /// internal FrameworkElement FindGeometry(List types, MouseButtonEventArgs e) { System.Windows.Point p = e.GetPosition(m_Root); return FindGeometry(types, p); } /// /// /// /// /// /// internal FrameworkElement FindGeometry(List types, MouseEventArgs e) { System.Windows.Point p = e.GetPosition(m_Root); return FindGeometry(types, p); } /// /// /// /// /// /// internal FrameworkElement FindGeometry(List types, DragEventArgs e) { System.Windows.Point p = e.GetPosition(m_Root); return FindGeometry(types, p); } private FrameworkElement FindGeometry(List types, System.Windows.Point p) { List typenames = new List(); foreach (Type t in types) typenames.Add(t.FullName); HitTestResult hitResult = VisualTreeHelper.HitTest(m_Root, p); if (hitResult == null || hitResult.VisualHit == null) return null; if (hitResult.VisualHit is FrameworkElement) { FrameworkElement el = hitResult.VisualHit as FrameworkElement; while (el != null) { if (typenames.Contains(el.GetType().FullName)) return el; else el = el.Parent as FrameworkElement; } } return null; } #endregion #region Root event protected virtual void m_Root_MouseRightButtonDown(object sender, MouseButtonEventArgs e) { //e.Handled = true; } protected virtual void m_Root_MouseRightButtonUp(object sender, MouseButtonEventArgs e) { //e.Handled = true; if (CrrentDrawTool != null) { CrrentDrawTool.MouseRightButtonUp(sender, e); } } protected virtual void m_Root_SizeChanged(object sender, SizeChangedEventArgs e) { if (m_Root != null) { if (m_Root.Clip == null) m_Root.Clip = new RectangleGeometry(); (m_Root.Clip as RectangleGeometry).Rect = new Rect() { X = 0, Y = 0, Width = m_Root.ActualWidth, Height = m_Root.ActualHeight }; } } protected virtual void m_Root_KeyUp(object sender, System.Windows.Input.KeyEventArgs e) { } protected virtual void m_Root_KeyDown(object sender, System.Windows.Input.KeyEventArgs e) { } private System.Windows.Point? _PanRefPoint = null; private double _DefaultOffsetScale = 0.1; protected bool IsCanMove = true; private bool isMoved = false; protected virtual void m_Root_MouseWheel(object sender, System.Windows.Input.MouseWheelEventArgs e) { if (!m_CanWheel) return; if (!e.Handled) { if (e.Delta > 0) { ZoomInMap(); this.PanMap(-100, -100); } else { ZoomOutMap(); this.PanMap(100, 100); } e.Handled = true; } } /// /// 空白区域单击 /// protected virtual void EmptyCliecked() { } protected virtual void m_Root_MouseLeftButtonUp(object sender, System.Windows.Input.MouseButtonEventArgs e) { if (CrrentDrawTool != null) { CrrentDrawTool.MouseLeftButtonUp(sender, e); } } private void M_Root_MouseUp(object sender, MouseButtonEventArgs e) { if (!isMoved) { m_RootKeyHook.Focus(); EmptyCliecked(); } if (_PanRefPoint != null) { m_Root.Cursor = null; _PanRefPoint = null; m_Root.ReleaseMouseCapture(); e.Handled = true; } IsCanMove = true; isMoved = false; } private void M_Root_MouseDown(object sender, MouseButtonEventArgs e) { if (e.ChangedButton == MouseButton.Middle && e.ButtonState == MouseButtonState.Pressed) { if (IsCanMove) { m_Root.Cursor = Cursors.Hand; m_Root.CaptureMouse(); } _PanRefPoint = e.GetPosition(m_Root); } } protected virtual void m_Root_MouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e) { if (CrrentDrawTool != null) { CrrentDrawTool.MouseLeftButtonDown(sender, e); } e.Handled = true; } protected virtual void m_Root_MouseMove(object sender, System.Windows.Input.MouseEventArgs e) { if (!e.Handled || _PanRefPoint != null) { if (_PanRefPoint != null && IsCanMove && !DisabledMove) { m_Root.Cursor = Cursors.Hand; System.Windows.Point newPoint = e.GetPosition(m_Root); if (_PanRefPoint.HasValue) { double offsetX = newPoint.X - _PanRefPoint.Value.X; double offsetY = newPoint.Y - _PanRefPoint.Value.Y; this.PanMap(offsetX, offsetY); isMoved = true; } _PanRefPoint = newPoint; e.Handled = true; } } if (CrrentDrawTool != null) { CrrentDrawTool.MouseMove(sender, e); } } #endregion #region PanMap,ZoomInMap,ZoomOutMap,Fit /// /// /// /// /// public virtual void PanMap(double OffsetX, double OffsetY) { if (_MapRootTranslate != null) { _MapRootTranslate.X += OffsetX; _MapRootTranslate.Y += OffsetY; } } /// /// /// public virtual void ZoomInMap() { ZoomInMap(_DefaultOffsetScale); } /// /// /// /// public virtual void ZoomInMap(double offsetScale) { if (_MapRootScale != null) { _MapRootScale.ScaleX += offsetScale; _MapRootScale.ScaleY += offsetScale; } } /// /// /// public virtual void ZoomOutMap() { ZoomOutMap(_DefaultOffsetScale); } /// /// /// /// public virtual void ZoomOutMap(double offsetScale) { if (_MapRootScale != null) { if ((_MapRootScale.ScaleX - offsetScale) > 0) { _MapRootScale.ScaleX -= offsetScale; _MapRootScale.ScaleY -= offsetScale; } } } /// /// /// public virtual void Fit() { if (_MapRootScale != null && _MapRootTranslate != null) { _MapRootScale.ScaleX = 1; _MapRootScale.ScaleY = 1; _MapRootTranslate.X = 0; _MapRootTranslate.Y = 0; } } #endregion } }