最近在研究WPF下绘制K线图的功能,由于WPF下图表控件很少,且大多都是收费的,如果自己从头开始写比较复杂,所以在网上看到了这篇文章,WPF中使用amCharts绘制股票K线图 年代比较久远,他用的是amCharts Stock Chart for WPF这个控件,但这个现在看来已经不维护了,或者找不到更新了。于是下载了上文中的代码,研究了一下其中的 AmCharts.Windows.Stock.dll。
C#程序如果不进行加密或者混淆,是可以使用一些反编译工具直接查看源代码的,比如在.NET开源之前,我们可以直接借助一些工具比如Reflector查看.NET的源代码。我这里先抱着试一试的想法,先用Reflector查看一下这个dll,看能否查看源代码。
使用.NET Reflector
.NET Reflector这个工具,想必大家都很熟悉,使用方法也很简单,直接打开,然后指定到要查看的dll即可。
可以看到,这个dll并没有加密,能够直接查看dll,更进一步,这个工具可以支持直接导出源代码:
这里,点击Export Source Code,就能直接导出源代码。
这里有个问题是,用.NET Reflector导出的源代码可能会有一些错误提示,需要我们自己进行修复,而且有时还会遇到各种问题。
- 生成的源代码文件结构和命名空间都很奇怪,需要我们自己调整。
- 直接生成的代码可能会报很多语法错误,另外由于命名空间的奇怪嵌套,可能会出现有些对象找不到定义的情况,需要重新组织命名空间。
- 对于WPF程序,对xaml文件以及资源文件的反编译欠缺支持,这个是致命的,会导致源代码即使能编译通过,可能也无法正确运行,会报一些语法错误,比如XamlParseException。
在修复完这些错误,在调试的时候即使项目文件是Debug模式,在调试时仍然会报无法调试Release,原因是需要移除Properties文件夹AssemblyInfo.cs文件中的这一句代码:
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
这就是.NET Reflector遇到的问题,作为一个工具用来查看程序源代码可以,但是直接反编译,可能还是会遇到一些麻烦。
大杀器ILSpy
ILSpy是开源的,可以直接在Github上下载一个最新的Release版本然后在本机安装,它的操作界面跟.NET Reflector很相似。
首先打开需要反编译的dll,然后在右键菜单里直接点击保存代码就可以了。导出来的代码里面,比如文档结构,XAML文件,资源文件等等都非常完美,直接使用Visual Studio打开就能编译通过。相当完美。
有了源代码之后,就能自己进行修改了,正如代码里的license.txt所说,这个dll是一个商业软件。在使用的时候,如果没有购买license,在左上角会显示注册地址的logo。
这个问题,原博主调研后发现他只会在第一个chart里显示,所以进行了一个巧妙的回避,就是建一个空的chart,然后将其隐藏。
stockChart.Charts[0].Collapse();
因为我有源码,所以最简单的方法就是,直接修改代码:
这里需要说明:我们一定要遵守著作权法,否则带来的251后果自负。😂
修改之后,这个左上角的注册地址就没有啦。
可以说是相当完美。
虽然这个K线图出来的,但其实还有很多细节需要调整,比如下方成交量的Y坐标的值,比如鼠标移上去的效果,这些都需要调整,我这里贴出xaml的页面,供大家参考。
<Window x:Class="StockAnalyse.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Stock Analyse" Height="450" Width="700" xmlns:ams="http://schemas.amcharts.com/stock/wpf/2009/xaml" xmlns:stockanalyse="clr-namespace:StockAnalyse" Loaded="Window_Loaded">
<Grid Margin="10,0,10,0">
<Grid.RowDefinitions>
<RowDefinition Height="40" />
<RowDefinition />
</Grid.RowDefinitions>
<StackPanel Grid.Row="0" Orientation="Horizontal">
<Label Margin="0,5,0,5" Content="打开:"></Label>
<TextBox Name="txtFilePath" Margin="0,5,0,5" Width="250" Height="22"></TextBox>
<Button Name="btnOpenFile" Margin="10,5,0,5" Width="30" Content="..." Height="24"
Click="btnOpenFile_Click">
</Button>
</StackPanel>
<ams:StockChart Name="stockChart" Grid.Row="1" PlotAreaBackground="#111111"
Foreground="White" ZoomModifierKeys="Ctrl" ZoomInOnWheelDown="True"
BalloonBackground="Aqua" PeriodSelectorVisibility="Hidden" ScrollerVisibility="Visible">
<ams:StockChart.DataSets>
<ams:DataSet Name="stockSet1" Brush="#7f8da9"
ItemsSource="{Binding Data}"
DateMemberPath="date"
OpenMemberPath="open" HighMemberPath="high"
LowMemberPath="low" CloseMemberPath="close"
ValueMemberPath="close" VolumeMemberPath="volume"
/>
</ams:StockChart.DataSets>
<ams:StockChart.Charts>
<ams:Chart Title="股票价格" GridHeight="2*" PlotAreaBackground="Black" ShowEventBalloons="False">
<ams:Chart.Graphs>
<ams:Graph GraphType="Candlestick"
NegativeBrush="#00FD00" PositiveBrush="Red"
LegendItemType="Ohlc" LegendPeriodItemType="Ohlc"
CursorBrush="Blue" CursorSize="6"/>
</ams:Chart.Graphs>
<ams:Chart.LeftValueAxis>
<ams:ValueAxis Name="PriceChartLeftValueAxis" ValuesForeground="#CCCCCC" StrokeThickness="0" TickLength="0" ValuesInside="True" />
</ams:Chart.LeftValueAxis>
<ams:Chart.LeftValueAxisGrid>
<ams:ValueGrid Stroke="#111111" >
</ams:ValueGrid>
</ams:Chart.LeftValueAxisGrid>
<ams:Chart.DateTimeAxis>
<ams:DateTimeAxis ValuesForeground="#CCCCCC" StrokeThickness="0" TickLength="0" />
</ams:Chart.DateTimeAxis>
<ams:Chart.DateTimeAxisGrid>
<ams:DateTimeAxisGrid Stroke="#111111" />
</ams:Chart.DateTimeAxisGrid>
<ams:Chart.Legend>
<ams:Legend
PositiveValueForeground="Red" NegativeValueForeground="#00FD00"
IsDateVisible="True"/>
</ams:Chart.Legend>
</ams:Chart>
<!--成交量的Chart-->
<ams:Chart Title="成交量" PlotAreaBackground="Black">
<ams:Chart.Graphs>
<ams:Graph GraphType="Column"
LegendItemType="Value" LegendPeriodItemType="Value"
DataField="Volume" PeriodValue="Sum"
CursorBrush="Blue" CursorSize="6" PositiveBrush="Red" NegativeBrush="#00FD00"
/>
</ams:Chart.Graphs>
<ams:Chart.DateTimeAxis>
<ams:DateTimeAxis ValuesEnabled="False" StrokeThickness="0" />
</ams:Chart.DateTimeAxis>
<ams:Chart.DateTimeAxisGrid>
<ams:DateTimeAxisGrid Stroke="#111111" />
</ams:Chart.DateTimeAxisGrid>
<ams:Chart.LeftValueAxis>
<ams:ValueAxis ValuesForeground="#CCCCCC" StrokeThickness="1" TickLength="1" />
</ams:Chart.LeftValueAxis>
<ams:Chart.LeftValueAxisGrid>
<ams:ValueGrid Stroke="#111111" >
</ams:ValueGrid>
</ams:Chart.LeftValueAxisGrid>
<ams:Chart.Legend>
<ams:Legend PositiveValueForeground="Red" NegativeValueForeground="Cyan" />
</ams:Chart.Legend>
</ams:Chart>
</ams:StockChart.Charts>
</ams:StockChart>
</Grid>
</Window>
后台代码直接查看文章开头博文里的即可,我这里不放出源码了。
amCharts Stock Chart for WPF这个控件用来绘制股票图形还是可以的,但是他缺少文档,基本的使用方法可以看文章开头的那篇博文。有了源代码之后就能更好的进行定制化修改了,如何进一步使用了进行探索。
总结
WPF下图形控件很少,第三方的图形控件虽然强大但是大部分是要收费的。本文在前人的使用amCharts Stock Chart for WPF来绘制K线图的基础上,对这个控件使用ILSpy进行了源码反编译,可以对它的代码进行学习以及进一步修改以满足自己的要求。
参考资料:
- https://www.cnblogs.com/shenyixin/p/3842853.html
- https://www.cnblogs.com/technology/archive/2011/04/19/2020910.html
- https://blog.csdn.net/qsbqing/article/details/90237580
老师,能否指导一下使用AmCharts.Windows.Stock.dll,如何调整鼠标移到K线图上去的效果,变成十字交叉型,并且开高低收价变成提示框的形式显示,谢谢