Files
2026-02-23 17:02:55 +08:00

436 lines
13 KiB
C#

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
/// <summary>
///
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="point"></param>
/// <returns></returns>
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;
}
/// <summary>
///
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="point"></param>
/// <returns></returns>
internal FrameworkElement FindGeometry(List<Type> types, MouseButtonEventArgs e)
{
System.Windows.Point p = e.GetPosition(m_Root);
return FindGeometry(types, p);
}
/// <summary>
///
/// </summary>
/// <param name="types"></param>
/// <param name="e"></param>
/// <returns></returns>
internal FrameworkElement FindGeometry(List<Type> types, MouseEventArgs e)
{
System.Windows.Point p = e.GetPosition(m_Root);
return FindGeometry(types, p);
}
/// <summary>
///
/// </summary>
/// <param name="types"></param>
/// <param name="e"></param>
/// <returns></returns>
internal FrameworkElement FindGeometry(List<Type> types, DragEventArgs e)
{
System.Windows.Point p = e.GetPosition(m_Root);
return FindGeometry(types, p);
}
private FrameworkElement FindGeometry(List<Type> types, System.Windows.Point p)
{
List<string> typenames = new List<string>();
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;
}
}
/// <summary>
/// 空白区域单击
/// </summary>
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
/// <summary>
///
/// </summary>
/// <param name="OffsetX"></param>
/// <param name="OffsetY"></param>
public virtual void PanMap(double OffsetX, double OffsetY)
{
if (_MapRootTranslate != null)
{
_MapRootTranslate.X += OffsetX;
_MapRootTranslate.Y += OffsetY;
}
}
/// <summary>
///
/// </summary>
public virtual void ZoomInMap()
{
ZoomInMap(_DefaultOffsetScale);
}
/// <summary>
///
/// </summary>
/// <param name="offsetScale"></param>
public virtual void ZoomInMap(double offsetScale)
{
if (_MapRootScale != null)
{
_MapRootScale.ScaleX += offsetScale;
_MapRootScale.ScaleY += offsetScale;
}
}
/// <summary>
///
/// </summary>
public virtual void ZoomOutMap()
{
ZoomOutMap(_DefaultOffsetScale);
}
/// <summary>
///
/// </summary>
/// <param name="offsetScale"></param>
public virtual void ZoomOutMap(double offsetScale)
{
if (_MapRootScale != null)
{
if ((_MapRootScale.ScaleX - offsetScale) > 0)
{
_MapRootScale.ScaleX -= offsetScale;
_MapRootScale.ScaleY -= offsetScale;
}
}
}
/// <summary>
///
/// </summary>
public virtual void Fit()
{
if (_MapRootScale != null && _MapRootTranslate != null)
{
_MapRootScale.ScaleX = 1;
_MapRootScale.ScaleY = 1;
_MapRootTranslate.X = 0;
_MapRootTranslate.Y = 0;
}
}
#endregion
}
}