找回密码
 立即注册

QQ登录

只需一步,快速开始

cf10082007

初级会员

22

主题

81

帖子

215

积分

初级会员

积分
215

活字格认证

cf10082007
初级会员   /  发表于:2014-8-22 09:09  /   查看:6473  /  回复:3
你好,我需要在chart控件上画两条竖直的线,并添加拖动事件,下面是我的代码。我的问题是怎么控制chartpanel的大小,bdr的width只能控制显示的大小,我发现chartpanel占满了整个chart。这样的画,我只能控制最新添加的线,老的被覆盖了。               
var obj = new ChartPanelObject()
                {
                    Action = ChartPanelAction.LeftMouseButtonDrag,
                    HorizontalAlignment = System.Windows.HorizontalAlignment.Center,
                    VerticalAlignment = VerticalAlignment.Stretch
                };

                var bdr = new Border()

                {
//                    Background = new SolidColorBrush(Colors.Red) { Opacity = 0.4 },
                    BorderBrush = new SolidColorBrush(Colors.Red),
                    Width = 40,
                    BorderThickness = new Thickness(1, 1, 1, 1),
                };

                obj.Content = bdr;
                obj.DataPoint = new System.Windows.Point(0.3, double.NaN);
                obj.Action = ChartPanelAction.LeftMouseButtonDrag;



                var obj1 = new ChartPanelObject()
                {
                    Action = ChartPanelAction.LeftMouseButtonDrag,
                    HorizontalAlignment = System.Windows.HorizontalAlignment.Center,
                    VerticalAlignment = VerticalAlignment.Stretch
                };

                var bdr1 = new Border()

                {
                    //                    Background = new SolidColorBrush(Colors.Red) { Opacity = 0.4 },
                    BorderBrush = new SolidColorBrush(Colors.Blue),
                    Width = 40,
                    BorderThickness = new Thickness(1, 1, 1, 1),
                };

                obj1.Content = bdr1;
                obj1.DataPoint = new System.Windows.Point(0.6, double.NaN);
                var pnl = new ChartPanel();
                var pnl1 = new ChartPanel();

                pnl.Children.Add(obj);
                pnl1.Children.Add(obj1);
                _chart.View.Layers.Add(pnl);
                _chart.View.Layers.Add(pnl1);

                pnl.AddHandler(System.Windows.Controls.Button.MouseLeftButtonDownEvent, new MouseButtonEventHandler(Element_MouseLeftButtonDown), true);
                pnl.AddHandler(System.Windows.Controls.Button.MouseMoveEvent, new System.Windows.Input.MouseEventHandler(Element_MouseMove), true);
                pnl.AddHandler(System.Windows.Controls.Button.MouseLeftButtonUpEvent, new MouseButtonEventHandler(Element_MouseLeftButtonUp), true);

                pnl.MouseMove += new System.Windows.Input.MouseEventHandler(Element_MouseMove);
                pnl.MouseLeftButtonDown += new MouseButtonEventHandler(Element_MouseLeftButtonDown);
                pnl.MouseLeftButtonUp += new MouseButtonEventHandler(Element_MouseLeftButtonUp);

                pnl1.AddHandler(System.Windows.Controls.Button.MouseLeftButtonDownEvent, new MouseButtonEventHandler(Element_MouseLeftButtonDown), true);
                pnl1.AddHandler(System.Windows.Controls.Button.MouseMoveEvent, new System.Windows.Input.MouseEventHandler(Element_MouseMove), true);
                pnl1.AddHandler(System.Windows.Controls.Button.MouseLeftButtonUpEvent, new MouseButtonEventHandler(Element_MouseLeftButtonUp), true);

                pnl1.MouseMove += new System.Windows.Input.MouseEventHandler(Element_MouseMove);
                pnl1.MouseLeftButtonDown += new MouseButtonEventHandler(Element_MouseLeftButtonDown);
                pnl1.MouseLeftButtonUp += new MouseButtonEventHandler(Element_MouseLeftButtonUp);

3 个回复

倒序浏览
Alice
社区贡献组   /  发表于:2014-8-22 10:28:00
沙发
回复 1楼cf10082007的帖子

根据之前提示的内容,按照这个思路,你只要对代码进行修改就能实现你的需求。

对于你新提出还是无法拖动事件里正确画线的问题,再次给提供思路如下:

通过ChartPanel的DataPoint使得线的位置改变。另外在每次移动位置的时候,需要先Clear所有的ChartPanel的children,然后再重新添加。
比如,鼠标在chart上滑过的时候,竖直的线随着鼠标位置改变。
1.CreateMarker方法,返回一个ChartPanelObject,可以添加到ChartPanel中。代码参考:
  1. ChartPanelObject CreateMarker(bool isHorizontal, Point pnt)
  2.         {
  3.             var obj = new ChartPanelObject();

  4.             var bdr = new Border()
  5.             {
  6.                 BorderBrush = Background = new SolidColorBrush(Colors.Red),
  7.                 Padding = new Thickness(2),
  8.             };

  9.             if (isHorizontal)
  10.             {
  11.                 bdr.BorderThickness = new Thickness(0, 2, 0, 0);
  12.                 bdr.Margin = new Thickness(0, -1, 0, 0);
  13.                 obj.HorizontalContentAlignment = HorizontalAlignment.Stretch;

  14.                 if (pnt.X == 0 && pnt.Y == 0)
  15.                     obj.DataPoint = new Point(double.NaN, 0.5);
  16.                 else
  17.                 {
  18.                     //Data Point where Mouse cursor is present
  19.                     Point dpt = chart.View.PointToData(pnt);

  20.                     double val;
  21.                     // Gets the index of the nearest data point
  22.                     int ptIndex = chart.View.DataIndexFromPoint(pnt, 0, MeasureOption.X, out val);

  23.                     // Use the above index to calculate the Coordinates of that nearest Data Point
  24.                     Point closeScreenPoint = chart.View.DataIndexToPoint(0, ptIndex);

  25.                     // Get the location of the next data point depending on whether mouse was
  26.                     // was moved towards left or right
  27.                     Point awayScreenPoint;
  28.                     if (pnt.X > closeScreenPoint.X)
  29.                         awayScreenPoint = chart.View.DataIndexToPoint(0, ptIndex + 1);
  30.                     else
  31.                         awayScreenPoint = chart.View.DataIndexToPoint(0, ptIndex - 1);

  32.                     //Get coordinates where Vertical marker will intersect the chart line
  33.                     double crossY = GetY(closeScreenPoint, awayScreenPoint, pnt);

  34.                     //Get DataPoint for the above intersecting coordinates
  35.                     Point closeDataPoint = chart.View.PointToData(new Point(pnt.X, crossY));

  36.                     // set the DataPoint as the Attached data source for the Horizontal marker
  37.                     obj.DataPoint = new Point(double.NaN, closeDataPoint.Y);

  38.                     ellipseDataPoint.Y = closeDataPoint.Y;
  39.                 }
  40.             }
  41.             else
  42.             {
  43.                 bdr.BorderThickness = new Thickness(2, 0, 0, 0);
  44.                 bdr.Margin = new Thickness(-1, 0, 0, 0);
  45.                 obj.VerticalContentAlignment = VerticalAlignment.Stretch;

  46.                 Point dpt = chart.View.PointToData(pnt);
  47.                 obj.DataPoint = new Point(dpt.X, double.NaN);
  48.                 ellipseDataPoint.X = dpt.X;
  49.             }

  50.             bdr.IsHitTestVisible = false;
  51.             obj.Content = bdr;

  52.             return obj;
  53.         }
复制代码

2.初始化竖直线,以及调用ChartPanel的MouseMove事件。
代码:
  1. var pnl = new ChartPanel();
  2.             pnl.MouseMove += new MouseEventHandler(pnl_MouseMove);

  3.             var vmarker = CreateMarker(false, new Point());
  4.             pnl.Children.Add(vmarker);
  5.             vmarker.Action = ChartPanelAction.None;         
  6.            chart.View.Layers.Add(pnl);
复制代码

3.MouseMove事件里获取鼠标位置,并重新画线。
  1. void pnl_MouseMove(object sender, MouseEventArgs e)
  2.         {
  3.             ChartPanel cnp = sender as ChartPanel;
  4.             Point pnt = e.GetPosition(chart);
  5.             test = pnt;
  6.         
  7.             var rect = chart.View.PlotRect;

  8.             if (rect.Contains(pnt))
  9.             {
  10.                 cnp.Children.Clear();

  11.                 var vmarker = CreateMarker(false, pnt);
  12.                 cnp.Children.Add(vmarker);
  13.             }
  14.            
  15.         }
复制代码

这个只要修改代码就可以完成需求。
请点击评分,对我的服务做出评价!  5分为非常满意!

葡萄城控件服务团队

官方网站: http://www.gcpowertools.com.cn
回复 使用道具 举报
cf10082007
初级会员   /  发表于:2014-8-22 10:50:00
板凳
回复 2楼Alice的帖子

你好,这个对于一条线是可以实现的,但对于两条线就不行了。这两条线我是得分开移动的,得有选择的过程。可现在新添加的线会将前一个完全覆盖掉,我无法操作原来的线
回复 使用道具 举报
Alice
社区贡献组   /  发表于:2014-8-22 12:32:00
地板
回复 3楼cf10082007的帖子

这已经不是产品的问题了,这是计算机算法的问题。
看到这个问题你已经提出多次都无法解决,我花时间帮助你写了这个算法,其实就是在MouseDown的时候去计算当前鼠标的位置接近哪条线,然后全局变量记下这条线的Index。在MouseMove的时候判定鼠标是否按下,然后修改这条线的DataPoint的X的值。
代码参考:
  1.         private int lineIndex = 0;
  2. void pnl_MouseDown(object sender, MouseButtonEventArgs e)
  3.         {
  4.             ChartPanel cnp = sender as ChartPanel;
  5.             Point pnt = e.GetPosition(chart);
  6.             Point dpt = chart.View.PointToData(pnt);

  7.             for (int i = 0; i < cnp.Children.Count;i++ )
  8.             {
  9.                 double x = cnp.Children[i].DataPoint.X;
  10.                 //判断哪条线接近鼠标,这里的横坐标轴刻度间隔是1,所以取了误差0.1。可以根据自己项目修改。
  11.                 if (Math.Abs(x - dpt.X) < 0.1)
  12.                 {
  13.                     lineIndex = i;
  14.                 }
  15.             }
  16.             
  17.         }

  18.         void pnl_MouseMove(object sender, MouseEventArgs e)
  19.         {           
  20.             ChartPanel cnp = sender as ChartPanel;
  21.             Point pnt = e.GetPosition(chart);

  22.             Point dpt = chart.View.PointToData(pnt);
  23.             var rect = chart.View.PlotRect;

  24.             if (rect.Contains(pnt)&&e.LeftButton== MouseButtonState.Pressed)
  25.             {
  26.                 cnp.Children[lineIndex].DataPoint = new Point(dpt.X, double.NaN);
  27.             }           
  28.         }
复制代码

评分

参与人数 1满意度 +5 收起 理由
cf10082007 + 5 非常感谢

查看全部评分

请点击评分,对我的服务做出评价!  5分为非常满意!

葡萄城控件服务团队

官方网站: http://www.gcpowertools.com.cn
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 立即注册
返回顶部