none
WPF 模拟地图缩放 图钉 RRS feed

  • 问题

  • WPF 地图缩放时的图钉控件没,此控件需要可响应事件,随地图的缩放 相对位置不变,大小不变,地图为自己的矢量图片
    2014年7月16日 9:05

答案

  • 你好,

    >>能发个Demo吗

    你可以从我的OneDrive下载:http://1drv.ms/1kBymSb

    >>能不能让矢量图缩放,不要窗体缩放

    如果在上个帖子中的回复,对于Canvas,可以指定LayoutTransform为ScaleTransform,像这样:

    <Canvas Name="canvas" Height="200" Width="200" MouseLeftButtonDown="canvas_MouseLeftButtonDown">
        <Canvas.LayoutTransform>
            <ScaleTransform ScaleX="2" ScaleY="2" CenterX=".5" CenterY=".5" />
        </Canvas.LayoutTransform>
    </Canvas>

    上面是在XAML中,代码后台里也是同样可以使用的


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    • 已标记为答案 weiss_2009 2014年7月18日 8:13
    2014年7月18日 6:15
    版主
  • 嗯!已经下载了,我想问问如何让这个矢量图进行缩放呢?

    你好,

    我在上面的回复中已经提到了,在后台使用各种变换,譬如ScaleTransform,可以调整大小比例, 如果需要更进一步的帮助,建议您对此问题开新帖,否则楼层太多,不利于讨论 :)


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    2014年7月18日 8:08
    版主
  • 你好!我的意思是地图为自己的矢量图片,而且不需要联网的 Bing 不合适吧!

    你好,

    如果只是想在矢量图上绘制,我们可以使用Canvas,把你的矢量地图放在里面,然后处理Canvas MouseLeftButtonDown 事件,在后台添加自定义Shape去模拟图钉,同样可以对Shape添加事件处理。

    在以下的Sample中,我是使用Polygon去绘制一个倒三角,然后对其鼠标点击事件添加事件处理函数:

    private void canvas_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
                Polygon myPolygon = new Polygon();
                myPolygon.Stroke = System.Windows.Media.Brushes.Black;
                myPolygon.Fill = System.Windows.Media.Brushes.Red;
                myPolygon.StrokeThickness = 1;
                System.Windows.Point Point1 = new System.Windows.Point(0, 0);
                System.Windows.Point Point2 = new System.Windows.Point(10, 0);
                System.Windows.Point Point3 = new System.Windows.Point(5, 20);
                PointCollection myPointCollection = new PointCollection();
                myPointCollection.Add(Point1);
                myPointCollection.Add(Point2);
                myPointCollection.Add(Point3);
                myPolygon.Points = myPointCollection;
                myPolygon.MouseDown += myPolygon_MouseDown;//Add event handler
    
                canvas.Children.Add(myPolygon);
                Canvas.SetLeft(myPolygon, e.GetPosition(canvas).X-5);
                Canvas.SetTop(myPolygon, e.GetPosition(canvas).Y-20);
    }
    
    void myPolygon_MouseDown(object sender, MouseButtonEventArgs e)
    {
                MessageBox.Show("Clicked");
    }

    XAML:

    <Viewbox Stretch="Uniform">
                <Canvas Name="canvas" Height="200" Width="200" MouseLeftButtonDown="canvas_MouseLeftButtonDown">
                    <!--放置矢量图资源-->
                    <ContentControl Template="{StaticResource Credit-Card}"  />
                </Canvas>
            </Viewbox>

    截图:


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    2014年7月18日 3:28
    版主

全部回复

  • 你好,

    你可以使用WPF Bing 地图控件去实现你的效果:

    #Bing Maps WPF Control
    http://msdn.microsoft.com/en-us/library/hh750210.aspx

    我在这个帖子中提供了一个详细的Sample: http://social.microsoft.com/Forums/zh-CN/c5ee4c60-9438-4803-9d42-ed1ddc6e5c4d/wpf-bing-map-wpf-bing?forum=wpfzhchs

    你只需要使用Pushpin Class去显示图钉,效果如下动图:

    <m:Map Name="myMap" 
                   Center="-1.968404, 30.036240" 
                   ZoomLevel="10"
                   CredentialsProvider="balabala"
                   Mode="AerialWithLabels" >
                <m:Pushpin Location="40.782001,-73.831703"/>
            </m:Map>


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    2014年7月17日 10:09
    版主
  • 你好!我的意思是地图为自己的矢量图片,而且不需要联网的 Bing 不合适吧!
    2014年7月18日 1:31
  • 你好!我的意思是地图为自己的矢量图片,而且不需要联网的 Bing 不合适吧!

    你好,

    如果只是想在矢量图上绘制,我们可以使用Canvas,把你的矢量地图放在里面,然后处理Canvas MouseLeftButtonDown 事件,在后台添加自定义Shape去模拟图钉,同样可以对Shape添加事件处理。

    在以下的Sample中,我是使用Polygon去绘制一个倒三角,然后对其鼠标点击事件添加事件处理函数:

    private void canvas_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
                Polygon myPolygon = new Polygon();
                myPolygon.Stroke = System.Windows.Media.Brushes.Black;
                myPolygon.Fill = System.Windows.Media.Brushes.Red;
                myPolygon.StrokeThickness = 1;
                System.Windows.Point Point1 = new System.Windows.Point(0, 0);
                System.Windows.Point Point2 = new System.Windows.Point(10, 0);
                System.Windows.Point Point3 = new System.Windows.Point(5, 20);
                PointCollection myPointCollection = new PointCollection();
                myPointCollection.Add(Point1);
                myPointCollection.Add(Point2);
                myPointCollection.Add(Point3);
                myPolygon.Points = myPointCollection;
                myPolygon.MouseDown += myPolygon_MouseDown;//Add event handler
    
                canvas.Children.Add(myPolygon);
                Canvas.SetLeft(myPolygon, e.GetPosition(canvas).X-5);
                Canvas.SetTop(myPolygon, e.GetPosition(canvas).Y-20);
    }
    
    void myPolygon_MouseDown(object sender, MouseButtonEventArgs e)
    {
                MessageBox.Show("Clicked");
    }

    XAML:

    <Viewbox Stretch="Uniform">
                <Canvas Name="canvas" Height="200" Width="200" MouseLeftButtonDown="canvas_MouseLeftButtonDown">
                    <!--放置矢量图资源-->
                    <ContentControl Template="{StaticResource Credit-Card}"  />
                </Canvas>
            </Viewbox>

    截图:


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    2014年7月18日 3:28
    版主
  • 能不能让矢量图缩放,不要窗体缩放?
    2014年7月18日 3:48
  • 你好,

    >>能发个Demo吗

    你可以从我的OneDrive下载:http://1drv.ms/1kBymSb

    >>能不能让矢量图缩放,不要窗体缩放

    如果在上个帖子中的回复,对于Canvas,可以指定LayoutTransform为ScaleTransform,像这样:

    <Canvas Name="canvas" Height="200" Width="200" MouseLeftButtonDown="canvas_MouseLeftButtonDown">
        <Canvas.LayoutTransform>
            <ScaleTransform ScaleX="2" ScaleY="2" CenterX=".5" CenterY=".5" />
        </Canvas.LayoutTransform>
    </Canvas>

    上面是在XAML中,代码后台里也是同样可以使用的


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    • 已标记为答案 weiss_2009 2014年7月18日 8:13
    2014年7月18日 6:15
    版主
  • 你好!这个链接不能访问https://onedrive.live.com/
    2014年7月18日 7:03
  • 你好!这个链接不能访问https://onedrive.live.com/

    你好,

    我把这个项目上传到示例代码库了,你可以下载参考:http://code.msdn.microsoft.com/Wpf-Vector-Based-Image-0ed1a3da


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.


    2014年7月18日 7:37
    版主
  • 嗯!已经下载了,我想问问如何让这个矢量图进行缩放呢?
    2014年7月18日 8:05
  • 嗯!已经下载了,我想问问如何让这个矢量图进行缩放呢?

    你好,

    我在上面的回复中已经提到了,在后台使用各种变换,譬如ScaleTransform,可以调整大小比例, 如果需要更进一步的帮助,建议您对此问题开新帖,否则楼层太多,不利于讨论 :)


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    2014年7月18日 8:08
    版主
  • 嗯! 主要刚刚接触WPF 多多指点  
    新帖:    http://social.msdn.microsoft.com/Forums/lync/zh-CN/5e914186-2f8f-44f4-b263-6aa7e8ae04a9/wpf-?forum=wpfzhchs
    2014年7月18日 8:14
  • 这是我为我们公司一个图片热点功能写的一个算法

    并没有模块化,所以不能提供系统的代码.

    思路很简单,就是根据底图所在控件的位置来改变地标控件的位置,需要注意也就是麻烦的地方就是在缩放的时候,还让地标控件同步移动而已

    下面是一个Behavior,就是这个效果的.可能还有其他部分代码没有贴上来,几年前写的了,我已经忘记了,不好意思

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Windows;
    using System.Windows.Interactivity;
    using System.Windows.Media;
    using System.Windows.Input;
    using System.Windows.Controls;
    using System.Windows.Media.Animation;
    
    namespace Shinning.Core.UtilityFunctions.Hero.Behaviors
    {
        /// <summary>
        /// 只针对Image控件使用
        /// </summary>
        public class MapModeDragMoveScaleBehavior : Behavior<FrameworkElement>
        {
            #region Dependency Properties
    
            //用于恢复初始缩放率
            public double Scale_Reset
            {
                get { return (double)GetValue(Scale_ResetProperty); }
                set { SetValue(Scale_ResetProperty, value); }
            }
    
            // Using a DependencyProperty as the backing store for Scale_Reset.  This enables animation, styling, binding, etc...
            public static readonly DependencyProperty Scale_ResetProperty =
                DependencyProperty.Register("Scale_Reset", typeof(double), typeof(MapModeDragMoveScaleBehavior), new UIPropertyMetadata(0.0, (s, e) =>
                {
                    (Instance.m_Element.RenderTransform as MatrixTransform).Matrix = new Matrix(
                  (double)e.NewValue,
                  0, 0,
                  (double)e.NewValue,
                 (Instance.m_Element.RenderTransform as MatrixTransform).Matrix.OffsetX,
                 (Instance.m_Element.RenderTransform as MatrixTransform).Matrix.OffsetY
                 );
    
                    Instance.IsOutScaleRange();
                    Instance.CheckOutBounds();
    
                    if (Instance.MatrixChanged != null)
                        Instance.MatrixChanged((Instance.m_Element.RenderTransform as MatrixTransform).Matrix);
                }));
    
            #endregion
    
            #region Members
    
            public static MapModeDragMoveScaleBehavior Instance;
    
            private FrameworkElement m_Element;//当前对象
    
            private Vector m_ManipulateTranslationDValue;//触摸移动时的差值量,递减移动
            private Point m_ManipulateStartTranslation;//触摸起始点
            private double m_ManipulateScaleDValue;//触摸缩放时的差值量,递减移动
            private Vector m_ManipulateOldScaleDValue;//上次的缩放率
            private Vector m_MouseTranslationDValue;//鼠标移动时的差值量,递减移动
            private CustomTouchDevice m_ManipulateDevice1;//缩放点1
            private CustomTouchDevice m_ManipulateDevice2;//缩放点2
            private Point m_MouseStartPoint;//鼠标按下时的点
            private Point m_ScaleCenterPoint;//以此点位中心开始缩放
            private double m_MoveSpeedRate = .9;//默认移动速率
            private double m_ScaleRate = .85;//默认缩放速率
            private Mode m_OperateMode = Mode.None;//操作方式
            private bool m_CanTranslate = true;//允许偏移
            private bool m_IsScaleByFingerCenter = false;//按手指中心位置缩放
            private double m_OriginalScale = 1;//首次加载完成后的缩放值
            private double m_ErrorLimit = 2;
            private double m_MaxScale = 50;
            #endregion
    
            #region Delegate
    
            /// <summary>
            /// 矩阵发生改变
            /// </summary>
            public event Action<Matrix> MatrixChanged;
    
            /// <summary>
            /// 重置结束
            /// </summary>
            public event Action ResetComplated;
    
            #endregion
    
            #region Properties
    
            /// <summary>
            /// 是否以两指中间为中心缩放
            /// </summary>
            public bool IsScaleByFingerCenter
            {
                get { return m_IsScaleByFingerCenter; }
                set { m_IsScaleByFingerCenter = value; }
            }
    
            /// <summary>
            /// 最大缩放率
            /// </summary>
            public double MaxScale
            {
                get { return m_MaxScale; }
                set { m_MaxScale = value; }
            }
    
            /// <summary>
            /// 移动速率
            /// </summary>
            public double SpeedRate
            {
                get { return m_MoveSpeedRate; }
                set { m_MoveSpeedRate = value; }
            }
    
            /// <summary>
            /// 缩放速率
            /// </summary>
            public double ScaleRate
            {
                get { return m_ScaleRate; }
                set { m_ScaleRate = value; }
            }
    
            #endregion
    
            #region Attach Detach
    
            protected override void OnAttached()
            {
                Instance = this;
                m_Element = this.AssociatedObject as FrameworkElement;
                m_Element.Loaded += (s, e) =>
                {
                    if (m_Element is Image)
                    {
                        //(m_Element as Image).Source.IsFrozen = false;
                        InitialScale();
                        (m_Element as Image).SizeChanged += delegate
                        {
                            InitialScale();
                        };
                    }
                    //StartScale(1);
    
                };
                m_Element.RenderTransformOrigin = new Point(.5, .5);
                m_Element.RenderTransform = new MatrixTransform() { Matrix = new Matrix(1, 0, 0, 1, 0, 0) };
                RegistEvents();
                base.OnAttached();
            }
    
            protected override void OnDetaching()
            {
                UnRegistEvents();
                base.OnDetaching();
            }
    
            #endregion
    
            #region  Events
    
            //渲染
            void CompositionTarget_Rendering(object sender, EventArgs e)
            {
                switch (m_OperateMode)
                {
                    case Mode.TouchMoveAndScale:
    
                        m_ManipulateTranslationDValue = new Vector(m_ManipulateTranslationDValue.X * SpeedRate, m_ManipulateTranslationDValue.Y * SpeedRate);
                        if (Math.Abs(m_ManipulateTranslationDValue.X) > .1 || Math.Abs(m_ManipulateTranslationDValue.Y) > .1)
                            StartMove(m_ManipulateTranslationDValue);
    
    
                        m_ManipulateScaleDValue *= ScaleRate;
                        if (Math.Abs(m_ManipulateScaleDValue) > .001)
                            StartScale(m_ManipulateScaleDValue);
    
                        if (MatrixChanged != null)
                            MatrixChanged((m_Element.RenderTransform as MatrixTransform).Matrix);
                        //值过小退出滑动
                        if (Math.Abs(m_ManipulateScaleDValue) < .1 && Math.Abs(m_ManipulateTranslationDValue.X) < .1 || Math.Abs(m_ManipulateTranslationDValue.Y) < .1)
                            m_OperateMode = Mode.None;
                        break;
                    case Mode.MouseMove:
    
                        StartMove(m_MouseTranslationDValue);
    
                        m_MouseTranslationDValue = new Vector(m_MouseTranslationDValue.X * SpeedRate, m_MouseTranslationDValue.Y * SpeedRate);
    
                        if (MatrixChanged != null)
                            MatrixChanged((m_Element.RenderTransform as MatrixTransform).Matrix);
    
    
                        //值过小退出滑动
                        if (Math.Abs(m_MouseTranslationDValue.X) < .1 && Math.Abs(m_MouseTranslationDValue.Y) < .1)
                            m_OperateMode = Mode.None;
    
                        break;
                }
            }
    
            #region Manipulate Events
    
            void m_Element_ManipulationCompleted(object sender, System.Windows.Input.ManipulationCompletedEventArgs e)
            {
                m_CanTranslate = true;
                m_ManipulateDevice1.Id = 0;
                m_ManipulateDevice2.Id = 0;
                m_ScaleCenterPoint = new Point(0, 0);
                // m_TouchTranslationDValue = new Vector(0, 0);
            }
    
            void m_Element_ManipulationDelta(object sender, System.Windows.Input.ManipulationDeltaEventArgs e)
            {
                object o = e.CumulativeManipulation.Expansion;
                m_OperateMode = Mode.TouchMoveAndScale;
    
                if (e.Manipulators.Count() == 1 && e.CumulativeManipulation.Scale.X == 1 && e.CumulativeManipulation.Scale.Y == 1)
                {
                    if (m_CanTranslate == true)
                    {
                        m_ManipulateScaleDValue = 0;
                        Vector dTranslation = Point.Subtract(e.ManipulationOrigin, m_ManipulateStartTranslation);
    
                        //值过小退出滑动
                        if (Math.Abs(dTranslation.X) < .1 && Math.Abs(dTranslation.Y) < .1)
                            return;
    
                        m_ManipulateTranslationDValue = new Vector((m_ManipulateTranslationDValue.X * 2 + dTranslation.X * (m_Element.RenderTransform as MatrixTransform).Matrix.M11) / 2, (m_ManipulateTranslationDValue.Y * 2 + dTranslation.Y * (m_Element.RenderTransform as MatrixTransform).Matrix.M11) / 2);
    
                        m_ManipulateStartTranslation = e.ManipulationOrigin;
                    }
                }
                else
                {
                    if (e.Manipulators.Count() < 2)
                        return;
    
                    m_CanTranslate = false;
                    if (m_ManipulateOldScaleDValue == e.CumulativeManipulation.Scale)
                        return;
                    else
                        m_ManipulateOldScaleDValue = e.CumulativeManipulation.Scale;
    
                    double scaleDValue = e.CumulativeManipulation.Scale.X > e.CumulativeManipulation.Scale.Y ? e.CumulativeManipulation.Scale.X - 1 : e.CumulativeManipulation.Scale.Y - 1;
    
                    //判断轻微移动有缺陷,待优化,暂不适用
                    if (!CheckLightMove(e.Manipulators.ToList()))
                    {
                        m_ManipulateScaleDValue = scaleDValue / 2;
                        return;
                    }
    
                    if (m_ManipulateScaleDValue == (m_ManipulateScaleDValue == 0 ? scaleDValue : (m_ManipulateScaleDValue + scaleDValue) / 2))
                        m_ManipulateScaleDValue *= SpeedRate;
                    else
                    {
                        if (Math.Abs(m_ManipulateScaleDValue - (m_ManipulateScaleDValue + scaleDValue) / 2) > 5)
                        {
                            m_ManipulateScaleDValue = (m_ManipulateScaleDValue + scaleDValue) / 4;
                        }
                        else
                            m_ManipulateScaleDValue = m_ManipulateScaleDValue == 0 ? scaleDValue : (m_ManipulateScaleDValue + scaleDValue) / 2;
                    }
                }
            }
    
            void m_Element_ManipulationStarted(object sender, ManipulationStartedEventArgs e)
            {
                m_CanTranslate = true;
                m_ManipulateStartTranslation = e.ManipulationOrigin;
                m_ManipulateTranslationDValue = new Vector(0, 0);
                m_ManipulateScaleDValue = 0;
            }
    
            #endregion
    
            #region Mouse Evnets
    
            void m_Element_MouseUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
            {
                m_OperateMode = Mode.MouseMove;
                m_MouseStartPoint = new Point(0, 0);
            }
    
            void m_Element_MouseMove(object sender, System.Windows.Input.MouseEventArgs e)
            {
                if (e.LeftButton == MouseButtonState.Pressed)
                {
                    if (m_MouseStartPoint == new Point(0, 0))
                        m_MouseStartPoint = e.GetPosition(m_Element);
    
                    Vector dv = Point.Subtract(e.GetPosition(m_Element), m_MouseStartPoint);
    
                    if (m_MouseTranslationDValue == new Vector(0, 0))
                        m_MouseTranslationDValue = dv;
                    else
                        m_MouseTranslationDValue = new Vector(((m_MouseTranslationDValue.X + dv.X * (m_Element.RenderTransform as MatrixTransform).Matrix.M11) / 2), ((m_MouseTranslationDValue.Y + dv.Y * (m_Element.RenderTransform as MatrixTransform).Matrix.M11) / 2));
    
                    StartMove(m_MouseTranslationDValue);
    
                    if (MatrixChanged != null)
                        MatrixChanged((m_Element.RenderTransform as MatrixTransform).Matrix);
    
                    m_MouseStartPoint = e.GetPosition(m_Element);
                }
            }
    
            void m_Element_MouseDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
            {
                m_MouseStartPoint = e.GetPosition(m_Element);
                m_MouseTranslationDValue = new Vector(0, 0);
            }
    
            #endregion
    
            #region Touch Events
    
            void m_Element_TouchUp(object sender, TouchEventArgs e)
            {
            }
    
            void m_Element_TouchDown(object sender, TouchEventArgs e)
            {
                //m_TouchStartPoint = e.GetTouchPoint(m_Element).Position;
                //m_ManipulateTranslationDValue = new Vector(0, 0);
                //m_OperateMode = Mode.TouchMove;
            }
    
            void m_Element_TouchMove(object sender, TouchEventArgs e)
            {
                //Vector dTranslation = Point.Subtract(e.GetTouchPoint(m_Element).Position, m_TouchStartPoint);
                ////值过小退出滑动
                //if (Math.Abs(dTranslation.X) < .1 && Math.Abs(dTranslation.Y) < .1)
                //    return;
    
                //m_ManipulateTranslationDValue = new Vector((m_ManipulateTranslationDValue.X * 2 + dTranslation.X*(m_Element.RenderTransform as MatrixTransform).Matrix.M11) / 2, (m_ManipulateTranslationDValue.Y * 2 + dTranslation.Y*(m_Element.RenderTransform as MatrixTransform).Matrix.M11) / 2);
    
                //m_TouchStartPoint = e.GetTouchPoint(m_Element).Position;
    
            }
    
            #endregion
    
            #endregion
    
            #region Functions
    
            /// <summary>
            /// 检查轻微移动
            /// </summary>
            /// <param name="devices">触点集合</param>
            bool CheckLightMove(List<IManipulator> devices)
            {
                if (m_ManipulateDevice1.Id == 0 && m_ManipulateDevice2.Id == 0)
                {
                    m_ManipulateDevice1 = new CustomTouchDevice() { Id = devices[0].Id, Position = devices[0].GetPosition(m_Element) };
                    m_ManipulateDevice2 = new CustomTouchDevice() { Id = devices[1].Id, Position = devices[1].GetPosition(m_Element) };
                    return true;
                }
                else if (devices.Find(l => l.Id == m_ManipulateDevice1.Id) != null && devices.Find(l => l.Id == m_ManipulateDevice2.Id) != null)
                {
                    IManipulator tempDevice1 = (IManipulator)devices.Where(l => l.Id == m_ManipulateDevice1.Id).SingleOrDefault();
                    IManipulator tempDevice2 = (IManipulator)devices.Where(l => l.Id == m_ManipulateDevice2.Id).SingleOrDefault();
    
                    bool isLight = IsScaling(IsLightMove(m_ManipulateDevice1.Position, tempDevice1.GetPosition(m_Element)), IsLightMove(m_ManipulateDevice2.Position, tempDevice2.GetPosition(m_Element)));
                    if (isLight)
                    {
                        m_ManipulateDevice1.Position = tempDevice1.GetPosition(m_Element);
                        m_ManipulateDevice2.Position = tempDevice2.GetPosition(m_Element);
    
                        return true;
                    }
                    else
                    {
                        m_ManipulateDevice1.Position = tempDevice1.GetPosition(m_Element);
                        m_ManipulateDevice2.Position = tempDevice2.GetPosition(m_Element);
    
                        return false;
                    }
    
                }
                return false;
            }
    
            /// <summary>
            /// 根据两个点判断是否轻微移动
            /// </summary>
            bool IsLightMove(Point p1, Point p2)
            {
                double moveDistance = Point.Subtract(p1, p2).Length;
    
                if (IsScaleByFingerCenter)
                    SetScaleCenter(p1, p2);
    
                Console.WriteLine(moveDistance.ToString());
                if (moveDistance > 5)
                    return true;
                else
                    return false;
            }
    
            /// <summary>
            /// 两个值必须都是true才判定为轻微移动
            /// </summary>
            bool IsScaling(bool b1, bool b2)
            {
                if (b1 && b2)
                    return true;
                else
                    return false;
            }
    
            /// <summary>
            /// 根据传入值,进行移动
            /// </summary>
            /// <param name="dv">偏移量</param>
            void StartMove(Vector dv)
            {
                (m_Element.RenderTransform as MatrixTransform).Matrix = new Matrix(
                    (m_Element.RenderTransform as MatrixTransform).Matrix.M11,
                    0, 0,
                    (m_Element.RenderTransform as MatrixTransform).Matrix.M22,
                    (m_Element.RenderTransform as MatrixTransform).Matrix.OffsetX + dv.X,
                    (m_Element.RenderTransform as MatrixTransform).Matrix.OffsetY + dv.Y
                    );
    
                CheckOutBounds();
                if (MatrixChanged != null)
                    MatrixChanged((m_Element.RenderTransform as MatrixTransform).Matrix);
            }
    
            /// <summary>
            /// 根据传入值,进行缩放
            /// </summary>
            /// <param name="dv">缩放量</param>
            void StartScale(double dv)
            {
                (m_Element.RenderTransform as MatrixTransform).Matrix = new Matrix(
                    (m_Element.RenderTransform as MatrixTransform).Matrix.M11 + dv,
                    0, 0,
                    (m_Element.RenderTransform as MatrixTransform).Matrix.M22 + dv,
                   (m_Element.RenderTransform as MatrixTransform).Matrix.OffsetX,
                   (m_Element.RenderTransform as MatrixTransform).Matrix.OffsetY
                   );
    
                if (MatrixChanged != null)
                    MatrixChanged((m_Element.RenderTransform as MatrixTransform).Matrix);
    
                IsOutScaleRange();
                CheckOutBounds();
    
                if (MatrixChanged != null)
                    MatrixChanged((m_Element.RenderTransform as MatrixTransform).Matrix);
            }
    
            /// <summary>
            /// 限制是否已到边界
            /// </summary>
            public void CheckOutBounds()
            {
                double offsetX = 0;
                double offsetY = 0;
                double currentWidth = m_Element.ActualWidth * (m_Element.RenderTransform as MatrixTransform).Matrix.M11 - SystemParameters.PrimaryScreenWidth;
                double currentHeight = m_Element.ActualHeight * (m_Element.RenderTransform as MatrixTransform).Matrix.M11 - SystemParameters.PrimaryScreenHeight;
    
                if ((m_Element.RenderTransform as MatrixTransform).Matrix.OffsetX > 0)
                {
                    if ((m_Element.RenderTransform as MatrixTransform).Matrix.OffsetX > currentWidth / 2)
                        offsetX = currentWidth / 2;
                    else
                        offsetX = (m_Element.RenderTransform as MatrixTransform).Matrix.OffsetX;
                }
                else if ((m_Element.RenderTransform as MatrixTransform).Matrix.OffsetX < 0)
                {
                    if ((m_Element.RenderTransform as MatrixTransform).Matrix.OffsetX < -currentWidth / 2)
                        offsetX = -currentWidth / 2;
                    else
                        offsetX = (m_Element.RenderTransform as MatrixTransform).Matrix.OffsetX;
                }
    
                if ((m_Element.RenderTransform as MatrixTransform).Matrix.OffsetY > 0)
                {
                    if ((m_Element.RenderTransform as MatrixTransform).Matrix.OffsetY > currentHeight / 2)
                        offsetY = currentHeight / 2;
                    else
                        offsetY = (m_Element.RenderTransform as MatrixTransform).Matrix.OffsetY;
                }
                else if ((m_Element.RenderTransform as MatrixTransform).Matrix.OffsetY < 0)
                {
                    if ((m_Element.RenderTransform as MatrixTransform).Matrix.OffsetY < -currentHeight / 2)
                        offsetY = -currentHeight / 2;
                    else
                        offsetY = (m_Element.RenderTransform as MatrixTransform).Matrix.OffsetY;
                }
    
                (m_Element.RenderTransform as MatrixTransform).Matrix = new Matrix(
                    (m_Element.RenderTransform as MatrixTransform).Matrix.M11,
                    0, 0,
                    (m_Element.RenderTransform as MatrixTransform).Matrix.M22,
                   offsetX,
                   offsetY
                   );
                if (MatrixChanged != null)
                    MatrixChanged((m_Element.RenderTransform as MatrixTransform).Matrix);
            }
    
            /// <summary>
            /// 已到缩放大小临界点
            /// </summary>
            public bool IsOutScaleRange()
            {
                double scale = 0;
                if ((m_Element.RenderTransform as MatrixTransform).Matrix.M11 > m_OriginalScale + MaxScale)
                    scale = m_OriginalScale + MaxScale;
                else if ((m_Element.RenderTransform as MatrixTransform).Matrix.M11 < m_OriginalScale)
                    scale = m_OriginalScale;
                else
                    return false;
    
                (m_Element.RenderTransform as MatrixTransform).Matrix = new Matrix(
                 scale,
                  0, 0,
                  scale,
                 (m_Element.RenderTransform as MatrixTransform).Matrix.OffsetX,
                 (m_Element.RenderTransform as MatrixTransform).Matrix.OffsetY
                 );
                if (MatrixChanged != null)
                    MatrixChanged((m_Element.RenderTransform as MatrixTransform).Matrix);
                return false;
            }
    
            /// <summary>
            /// 缩放初始化,用于使图片完全充满屏幕
            /// </summary>
            void InitialScale()
            {
                double augmenter = 0;
    
                Size sizeImage = new Size((m_Element as Image).ActualWidth, (m_Element as Image).ActualHeight);
                Size sizeImageSource = new Size((m_Element as Image).Source.Width, (m_Element as Image).Source.Height);
    
                if ((sizeImageSource.Width / sizeImageSource.Height) == (SystemParameters.PrimaryScreenWidth / SystemParameters.PrimaryScreenHeight))
                    return;
    
                if (SystemParameters.PrimaryScreenWidth - sizeImageSource.Width > SystemParameters.PrimaryScreenHeight - sizeImageSource.Height)
                {
                    if (sizeImage.Width + m_ErrorLimit >= SystemParameters.PrimaryScreenWidth && sizeImage.Height + m_ErrorLimit < SystemParameters.PrimaryScreenHeight)
                        augmenter = SystemParameters.PrimaryScreenHeight / sizeImage.Height - 1;
                    else
                        augmenter = SystemParameters.PrimaryScreenWidth / sizeImage.Width - 1;
                }
                else
                {
                    if (sizeImage.Width + m_ErrorLimit < SystemParameters.PrimaryScreenWidth && sizeImage.Height + m_ErrorLimit >= SystemParameters.PrimaryScreenHeight)
                        augmenter = SystemParameters.PrimaryScreenWidth / sizeImage.Width - 1;
                    else
                        augmenter = SystemParameters.PrimaryScreenHeight / sizeImage.Height - 1;
                }
    
                (m_Element.RenderTransform as MatrixTransform).Matrix = new Matrix(
                 1 + augmenter,
                 0, 0,
                 1 + augmenter,
                 (m_Element.RenderTransform as MatrixTransform).Matrix.OffsetX,
                 (m_Element.RenderTransform as MatrixTransform).Matrix.OffsetY
                    );
    
    
                ////this.BeginAnimation(MapModeDragMoveScaleBehavior.Scale_ResetProperty, new DoubleAnimation((m_Element.RenderTransform as MatrixTransform).Matrix.M11, TimeSpan.FromMilliseconds(300)));
    
                m_OriginalScale = (m_Element.RenderTransform as MatrixTransform).Matrix.M11;
    
    
                if (Instance.MatrixChanged != null)
                    Instance.MatrixChanged((Instance.m_Element.RenderTransform as MatrixTransform).Matrix);
    
                CheckOutBounds();
    
    
            }
    
            /// <summary>
            /// 根据两点设置缩放中心点
            /// </summary>
            void SetScaleCenter(Point p1, Point p2)
            {
                if (m_ScaleCenterPoint != new Point(0, 0))
                    return;
    
                Point tempPoint = new Point((p1.X + p2.X) / 2, (p1.Y + p2.Y) / 2);
                double x = (((m_Element.ActualWidth * (m_Element.RenderTransform as MatrixTransform).Matrix.M11)) / 2 - (m_Element.RenderTransform as MatrixTransform).Matrix.OffsetX) - (m_Element.RenderTransform as MatrixTransform).Matrix.OffsetX / 2;
                double y = (((m_Element.ActualHeight * (m_Element.RenderTransform as MatrixTransform).Matrix.M11)) / 2 - (m_Element.RenderTransform as MatrixTransform).Matrix.OffsetY) - (m_Element.RenderTransform as MatrixTransform).Matrix.OffsetY / 2;
                m_ScaleCenterPoint = new Point(x, y);
                //(m_Element.RenderTransform as MatrixTransform).Matrix
                //m_Element.RenderTransformOrigin = new Point(a, b);
            }
    
            /// <summary>
            /// 注册事件
            /// </summary>
            void RegistEvents()
            {
                m_Element.IsManipulationEnabled = true;
                CompositionTarget.Rendering += CompositionTarget_Rendering;
                m_Element.AddHandler(FrameworkElement.ManipulationStartedEvent, (EventHandler<ManipulationStartedEventArgs>)(m_Element_ManipulationStarted), false);
                m_Element.AddHandler(FrameworkElement.ManipulationDeltaEvent, (EventHandler<ManipulationDeltaEventArgs>)(m_Element_ManipulationDelta), false);
                m_Element.AddHandler(FrameworkElement.ManipulationCompletedEvent, (EventHandler<ManipulationCompletedEventArgs>)(m_Element_ManipulationCompleted), false);
                m_Element.AddHandler(FrameworkElement.MouseDownEvent, (MouseButtonEventHandler)m_Element_MouseDown, false);
                m_Element.AddHandler(FrameworkElement.MouseMoveEvent, (MouseEventHandler)m_Element_MouseMove, false);
                m_Element.AddHandler(FrameworkElement.MouseUpEvent, (MouseButtonEventHandler)m_Element_MouseUp, false);
                m_Element.AddHandler(FrameworkElement.TouchDownEvent, (EventHandler<TouchEventArgs>)(m_Element_TouchDown), false);
                m_Element.AddHandler(FrameworkElement.TouchMoveEvent, (EventHandler<TouchEventArgs>)(m_Element_TouchMove), false);
                m_Element.AddHandler(FrameworkElement.TouchUpEvent, (EventHandler<TouchEventArgs>)(m_Element_TouchUp), false);
            }
    
            /// <summary>
            /// 注销事件
            /// </summary>
            void UnRegistEvents()
            {
                m_Element.IsManipulationEnabled = false;
                CompositionTarget.Rendering += CompositionTarget_Rendering;
                m_Element.AddHandler(FrameworkElement.ManipulationStartedEvent, (EventHandler<ManipulationStartedEventArgs>)(m_Element_ManipulationStarted));
                m_Element.RemoveHandler(FrameworkElement.ManipulationDeltaEvent, (EventHandler<ManipulationDeltaEventArgs>)(m_Element_ManipulationDelta));
                m_Element.RemoveHandler(FrameworkElement.ManipulationCompletedEvent, (EventHandler<ManipulationCompletedEventArgs>)(m_Element_ManipulationCompleted));
                m_Element.RemoveHandler(FrameworkElement.MouseDownEvent, (MouseButtonEventHandler)m_Element_MouseDown);
                m_Element.RemoveHandler(FrameworkElement.MouseMoveEvent, (MouseEventHandler)m_Element_MouseMove);
                m_Element.RemoveHandler(FrameworkElement.MouseUpEvent, (MouseButtonEventHandler)m_Element_MouseUp);
                m_Element.RemoveHandler(FrameworkElement.TouchDownEvent, (EventHandler<TouchEventArgs>)(m_Element_TouchDown));
                m_Element.RemoveHandler(FrameworkElement.TouchMoveEvent, (EventHandler<TouchEventArgs>)(m_Element_TouchMove));
                m_Element.RemoveHandler(FrameworkElement.TouchUpEvent, (EventHandler<TouchEventArgs>)(m_Element_TouchUp));
            }
    
            /// <summary>
            /// 重置
            /// </summary>
            public void ReSet()
            {
                DoubleAnimation da = new DoubleAnimation((m_Element.RenderTransform as MatrixTransform).Matrix.M11, m_OriginalScale, TimeSpan.FromMilliseconds(500));
                da.Completed += delegate
                {
                    if (ResetComplated != null)
                        ResetComplated();
                };
                this.BeginAnimation(MapModeDragMoveScaleBehavior.Scale_ResetProperty, da);
    
    
            }
    
            #endregion
    
        }
    
        /// <summary>
        /// Operation Mode
        /// </summary>
        public enum Mode
        {
            TouchMoveAndScale,
            MouseMove,
            None
        }
    
        /// <summary>
        /// 用于判断轻微操作的触摸内容
        /// </summary>
        public struct CustomTouchDevice
        {
            public Point Position { get; set; }
            public int Id { get; set; }
        }
    }
    



    与我交流:点击这里给我发消息

    2014年7月22日 8:11
  •     /// <summary>
            /// 计算当前热点根据Matrix转换
            /// </summary>
            /// <param name="element"></param>
            /// <param name="mainMatrix"></param>
            public static void CalculatePosition(this FrameworkElement element, Matrix mainMatrix)
            {
                HotSpotItem item = element.DataContext as HotSpotItem;
                ContentPresenter cp = VisualTreeHelper.GetParent(element) as ContentPresenter;
    
                Point mapCenterPoint = new Point(SystemParameters.PrimaryScreenWidth / 2 + item.CurrentMatrix.OffsetX, SystemParameters.PrimaryScreenHeight / 2 + item.CurrentMatrix.OffsetY);
    
                //偏移时,同步移动热点
                double left = item.Location.X + (mainMatrix.OffsetX - item.CurrentMatrix.OffsetX);
                double top = item.Location.Y + (mainMatrix.OffsetY - item.CurrentMatrix.OffsetY);
    
                //缩放时,同步移动热点
                left += ((item.Location.X - mapCenterPoint.X + element.ActualWidth / 2) * (mainMatrix.M11 - item.CurrentMatrix.M11)) / item.CurrentMatrix.M11;
                top += ((item.Location.Y - mapCenterPoint.Y + element.ActualHeight) * (mainMatrix.M11 - item.CurrentMatrix.M11)) / item.CurrentMatrix.M11;
    
                cp.SetValue(Canvas.LeftProperty, left);
                cp.SetValue(Canvas.TopProperty, top);
    
                item.Location = new Point(
                    left,
                    top
                    );
    
                item.CurrentMatrix = mainMatrix;
            }
    
            /// <summary>
            ///第一次加载 计算当前热点根据Matrix转换
            /// </summary>
            /// <param name="element"></param>
            /// <param name="mainMatrix"></param>
            public static void CalculatePosition(this FrameworkElement element, double width, double height)
            {
                Matrix mainMatrix = (InstanceClass.ImageStyleControlInstance.Map.RenderTransform as MatrixTransform).Matrix;
                HotSpotItem item = element.DataContext as HotSpotItem;
                ContentPresenter cp = VisualTreeHelper.GetParent(element) as ContentPresenter;
    
                if (!IsAdding)
                {
                    width = 0; height = 0;
                }
    
                cp.SetValue(Canvas.LeftProperty, item.Location.X + (mainMatrix.OffsetX - item.CurrentMatrix.OffsetX) - width);
                cp.SetValue(Canvas.TopProperty, item.Location.Y + (mainMatrix.OffsetY - item.CurrentMatrix.OffsetY) - height);
    
                IsAdding = false;
    
                item.Location = new Point(
                    (double)cp.GetValue(Canvas.LeftProperty),
                    (double)cp.GetValue(Canvas.TopProperty)
                    );
    
                item.CurrentMatrix = mainMatrix;
            }

    这是两个关键的方法


    与我交流:点击这里给我发消息

    2014年7月22日 8:12
  • HeroHua0509:

         你好,你提供的图片热点功能,我没有看懂,xmal中是如何设计的,不知道大神最近还在嘛

    2020年12月21日 6:40