ComponentOne For WPF学习心得-光标功能
写在前面
上一篇文章写了关于缩放功能的理解,感觉写的不是很好,这次关于光标功能,我准备用边打代码边写的方式,把一个简单的光标功能项目做出来,然后写下相应的心得,开始简单的创建WPF项目,引用相关程序集和添加License就不加以累述了,直接开始主要的部分
创建图表并自定义数据
这里我用的是折线图,因为工作需要一直用的就是这个图,所以比较熟悉。数据呢,我用的是Random类(也叫做随机数生成器),那就开始吧。
创建图表,我是直接在工具箱里拖一个C1Chart控件,上代码
<c1:C1Chart Grid.Row="1" Name="Chart" ChartType="Line" MouseLeftButtonDown="Chart_MouseLeftButtonDown" MouseMove="Chart_MouseMove" MouseLeftButtonUp="Chart_MouseLeftButtonUp">
<c1:C1Chart.View>
<c1:ChartView>
<c1:ChartView.AxisX>
<c1:Axis>
<c1:Axis.ScrollBar>
<c1:AxisScrollBar Visibility="Collapsed" />
</c1:Axis.ScrollBar>
<c1:Axis.Title>
<TextBlock Text="Time(sec)" TextAlignment="Center" Foreground="Black"/>
</c1:Axis.Title>
</c1:Axis>
</c1:ChartView.AxisX>
<c1:ChartView.AxisY>
<c1:Axis>
<c1:Axis.ScrollBar>
<c1:AxisScrollBar Visibility="Collapsed" />
</c1:Axis.ScrollBar>
<c1:Axis.Title>
<TextBlock Text="Amplitude-V" TextAlignment="Center" Foreground="Black"/>
</c1:Axis.Title>
</c1:Axis>
</c1:ChartView.AxisY>
</c1:ChartView>
</c1:C1Chart.View>
</c1:C1Chart>
这应该算比较简单的空白图表了,接下来就要创建自定义数据,然后添加到图表的数据源中,上代码
void AddData()
{
Chart.BeginUpdate();
Chart.Data.Children.Clear();
//做一些基础配置
Chart.View.AxisX.AutoMin = true;
Chart.View.AxisX.Max = 100;
Chart.View.AxisY.Min = -10;
Chart.View.AxisY.Max = 10;
Random random = new Random();//随机数生成器
double[] valuesX = new double[];
double[] valuesY = new double[];
for (int i = 0; i < 100000; i++)
{
valuesX[i] = i / 100.0;
valuesY[i] = ((rand.NextDouble() - 0.5) * 10.0);
}
XYDataSerise ds = new XYDataSerise();//C1Chart专用的数据类
ds.XValuesSource = valuesX;
ds.ValuesSource = valuesY;
ds.RenderMode = RenderMode.Bitmap;//数据呈现模式,不同模式对数据的渲染方式不同
Chart.Data.Children.Add(ds);
Chart.EndUpdate();
}
这样我们就完成了最简单的一张图表,我这边用的数据量比较多,也可以只用100个点,比较清楚。其中最重要的应该是这两句代码Chart.BeginUpdate() ,Chart.EndUpdate(),这两句代码是让图表实时变化的关键。 最费解的应该是ds.RenderMode = RenderMode.Bitmap;//数据呈现模式,不同模式对数据的渲染方式不同,有些同学可能不知道什么叫渲染模式,这里先不用知道含义,记住有这么个东西就行,后面项目完成我们在回头来说。
创建光标并跟随鼠标移动
其实一开始接触到一些项目,用的光标不是简单的线性光标,而是一些为了满足需求,写的比较复杂的光标样式,也不是很简单的用Border完成的光标,而是通过装饰模式根据需求自定义的一些光标,但在这个实例里面,我们只讲最简单的Border光标。
创建光标,上代码
ChartPanelObject CreateCursor(bool _isHorizontal)
{
var obj = new ChartPanelObject();
var bdr = new Border()
{
BorderBrush = Background = new SolidColorBrush(Color.FromArgb(150, 255, 2, 2)),
Padding = new Thickness(2),
};
var tb = new TextBlock();
var bind = new Binding();
bind.Source = obj;
if (isHorizontal)
{
bdr.BorderThickness = new Thickness(0, 1, 0, 0);
bdr.Margin = new Thickness(0, -1, 0, 0);
obj.HorizontalContentAlignment = HorizontalAlignment.Stretch;//水平轴
bind.StringFormat = "y={0:#.##}";//设置显示格式
bind.Path = new PropertyPath("DataPoint.Y");//绑定到Y坐标
obj.DataPoint = new Point(double.NaN, 0.5);//初始化在哪
}
else
{
bdr.BorderThickness = new Thickness(1, 0, 0, 0);
bdr.Margin = new Thickness(-1, 0, 0, 0);
obj.VerticalContentAlignment = VerticalAlignment.Stretch;
bind.StringFormat = "x={0:#.##}";
bind.Path = new PropertyPath("DataPoint.X");
obj.DataPoint = new Point(0.5, double.NaN);
}
tb.SetBinding(TextBlock.TextProperty, bind);
bdr.Child = tb;
bdr.IsHitTestVisible = false;
obj.Content = bdr;
return obj;
}
这样就可以根据参数分别创建,一个水平的光标和一个垂直的光标。
然后就是将这两个光标放到图表里,并让他跟随鼠标动起来了,上代码
var pnl = new ChartPanel();
vmarker = CreateMarker(false);
pnl.Children.Add(vmarker);
vmarker.Action = ChartPanelAction.MouseMove;//将光标的移动绑定到鼠标移动事件上
hmarker = CreateMarker(true);
pnl.Children.Add(hmarker);
hmarker.Action = ChartPanelAction.MouseMove;
Chart.View.Layers.Add(pnl);
hmarker.Attach = vmarker.Attach = ChartPanelAttach.DataX;//X轴主动,Y轴从动
这样,一个简单的光标功能就完成了。这里最难理解的代码应该是hmarker.Attach = vmarker.Attach = ChartPanelAttach.DataX;//X轴主动,Y轴从动,这段代码是的两个光标,一个光标跟随鼠标的移动而移动,另一个光标根据前一个光标的移动找出对应的点,做出移动。ChartPanelAttach还有几个不同的枚举值,想了解的同学们可以尝试一下。
tips:当然不能忘记遗留问题啦,什么是数据呈现模式,RenderMode是一个枚举,他有三个不同的枚举值,我们用的是Bitmap,你可以尝试一下用不同渲染方式来画这个图,特别是在数据多的情况下。