DotNet(C#)环境下使用和设置MSChart组件

写在前面:Microsoft Chart Control(简称MSChart)是一款很强大的Com组件,主要负责图形的展示,早在VB6的时候,它就已经是程序员非常喜欢的图形控件,在日常的开发时得到很多的应用,而在.Net平台下,虽然已经有了很多的纯.Net控件,不过,这一款传统的控件,依然是标准性的控件。它的设置和定义方法也是别的控件仿效的。.Net对传统的Com组件有很强大的支持,当然,会支持MSChart,下面介绍一下,在.Net平台下使用MSChart的方法。

打开一个Form,在工具箱上面,常规选项卡,右击,选择项,稍等一会,IDE会加载一个对话框,如下图所示,打开COM组件,并找到Microsoft Chart Control项(对于不同的操作系统,可能会有版本的不同),打勾,再点确定。这样,就可以成功加载控件。

在工具箱中,就会出现如下的图示,表示图形控件Chart Control加载成功。

把控件拖到Form中,然后把大小拉到最大,点右键,属性,就会出现下图的设置介面,根据操作系统版本的不同,属性下面的选项卡有可以是中文的。

控件拖出来的同时,请注意项目的引用,这里,会增加了好几个引用,如
AxMSChart20Lib,程序集AxInterop.MSChart20Lib
MSChart20Lib,程序集Interop.MSChart20Lib
MSDATASRC,程序集MSDATASRC
stdole,程序集stdole
这些,都是IDE自动为我们增加的,MSChart20Lib是原COM组件的引用,而AxMSChart20Lib是.Net对它的再封装,使它就像普通的控件一样。不是从工具箱拖出来,而直接引用Microsoft Chart Control控件,就不会出现AxMSChart20Lib的程序集的。

对控件进行设置
控件的默认名称Name为axMSChart1,添加引用,using MSChart20Lib;
在构造函数中调用方法InitMSChart(axMSChart1);
InitMSChart方法的定义如下,它只定义控件的样式,不定义数据。

void InitMSChart(AxMSChart20Lib.AxMSChart _MSChart)
        {
            //图表标题
            _MSChart.TitleText = "测试统计图表"; 
 
            //页底说明
            _MSChart.Footnote.Text = "说明:这是测试统计图表"; 
 
            //设置图例
            _MSChart.ShowLegend = true;
            _MSChart.Legend.Location.LocationType = VtChLocationType.VtChLocationTypeRight; 
 
            //设置主框图Plot 
 
            //设置Plot的Shadow
            _MSChart.Plot.Backdrop.Shadow.Style = VtShadowStyle.VtShadowStyleDrop;
            _MSChart.Plot.Backdrop.Shadow.Offset.Set(60, 60);//'设置Shadow的大小
            //设置Plot的边框
            _MSChart.Plot.Backdrop.Frame.Style = VtFrameStyle.VtFrameStyleSingleLine;
            //设置Plot的背景色
            _MSChart.Plot.Backdrop.Fill.Style = VtFillStyle.VtFillStyleBrush;
            _MSChart.Plot.Backdrop.Fill.Brush.FillColor.Set(255, 255, 255); 
 
            //取消竖的导航线
            _MSChart.Plot.get_Axis(VtChAxisId.VtChAxisIdX, 0).AxisGrid.MajorPen.Style = VtPenStyle.VtPenStyleNull;
            _MSChart.Plot.get_Axis(VtChAxisId.VtChAxisIdX, 0).AxisScale.Hide = true; 
 
            //关闭选择
            _MSChart.AllowSelections = false;
        } 
 

效果图
最后,可以看到的效果是如下

 

DevExpress的控件PivotGrid(XtraPivotGrid,AspxPivotGrid)连接Chart的方法之准备篇

写在前面:DevExpress的控件PivotGrid,无论是WinForm的XtraPivotGrid,还是WebForm的AspxPivotGrid,都能够实现强大的多维分析功能,完全可以当成一个决策分析工具来使用,不过,美中不足,而且很不足的就是没有关联到图形图表Chart,有了分析的结果,但是也没有图形图表更加直观地表达效果,为了把PivotGrid连接到Chart,下面介绍一个方法,不过先介绍一些准备的资源。连接的方法是利用PivotGrid自带的编程接口获取筛选属性,形成交差表,再使用Office Web Control(OWC)来展示图形。

OWC显示图形的例子
引用DLL

using OWC11; 
 
  //创建X坐标的值,表示月份 
        int[] Month ={ 1, 2, 3 };
        //创建Y坐标的值,表示销售额 
        double[] Count ={ 120, 240, 220 };
        string strDataName = "";
        string strData = "";
        //创建图表空间 
        ChartSpace mychartSpace = new ChartSpace(); 
 
        //mychartSpace.DataSource = oleReader;
        //mychartSpace.Border.DashStyle = ChartLineDashStyleEnum.chLineRoundDot;
        //在图表空间内添加一个图表对象 
        ChChart mychart = mychartSpace.Charts.Add(0);
        mychart.Border.DashStyle = ChartLineDashStyleEnum.chLineSolid;
        //设置每块饼的数据 
        for (int i = 0; i < Count.Length; i++)
        {
            if (i != Count.Length - 1)
            {
                strDataName += Month[i] + "\t";
                strData += Count[i].ToString() + "\t";
            }
            else
            {
                strDataName += Month[i];
                strData += Count[i].ToString();
            }
        }
        //设置图表类型,本例使用柱形 
        mychart.Type = ChartChartTypeEnum.chChartTypePie;
        //设置图表的一些属性 
        //是否需要图例 
        mychart.HasLegend = true;
        //是否需要主题 
        mychart.HasTitle = true;
        //主题内容 
        mychart.Title.Caption = "一季度总结";
        //添加图表块 
        mychart.SeriesCollection.Add(0);
        //设置图表块的属性 
        //分类属性         
        mychart.SeriesCollection[0].SetData(ChartDimensionsEnum.chDimCategories, (int)ChartSpecialDataSourcesEnum.chDataLiteral, strDataName);
        //值属性 
        mychart.SeriesCollection[0].SetData(ChartDimensionsEnum.chDimValues, (int)ChartSpecialDataSourcesEnum.chDataLiteral, strData);
        //mychart.Axes[1].Font.Bold = true;       
        mychart.Legend.Border.DashStyle = ChartLineDashStyleEnum.chLineDash;
        //显示百分比 
        ChDataLabels mytb = mychart.SeriesCollection[0].DataLabelsCollection.Add();
        //mytb.HasPercentage = true;
        //生成图片 
        mychartSpace.ExportPicture(Server.MapPath(".") + @"\test.gif", "gif", 500, 450);
        //加载图片 

显示的效果图

获取Pivot各个区域Area的值

#region 获取相应Area内容
    protected System.Collections.Generic.ICollection<PivotGridField> GetFilterFields(ASPxPivotGrid _grid)
    {
        return GetFieldsByArea(_grid, DevExpress.XtraPivotGrid.PivotArea.FilterArea);
    }
    protected System.Collections.Generic.ICollection<PivotGridField> GetColumnFields(ASPxPivotGrid _grid)
    {
        return GetFieldsByArea(_grid, DevExpress.XtraPivotGrid.PivotArea.ColumnArea);
    } 
 
    protected System.Collections.Generic.ICollection<PivotGridField> GetRowFields(ASPxPivotGrid _grid)
    {
        return GetFieldsByArea(_grid, DevExpress.XtraPivotGrid.PivotArea.RowArea);
    }
    protected System.Collections.Generic.ICollection<PivotGridField> GetDataFields(ASPxPivotGrid _grid)
    {
        return GetFieldsByArea(_grid, DevExpress.XtraPivotGrid.PivotArea.DataArea);
    } 
 
    protected System.Collections.Generic.ICollection<PivotGridField> GetFieldsByArea(ASPxPivotGrid _grid, DevExpress.XtraPivotGrid.PivotArea _area)
    {
        System.Collections.Generic.List<PivotGridField> _list = new List<PivotGridField>();
        foreach (DevExpress.Web.ASPxPivotGrid.PivotGridField _field in _grid.Fields)
        {
            if (_field.Area == _area)
            {
                _list.Add(_field);
            }
        }
        return _list;
    }
#endregion 

DotNet(C#)自定义运行时窗体设计器Runtime FormDesigner

写在前面:因为业务的需要,有时会使用到自定义运行时窗体设计器Runtime FormDesigner,实现的功能,就是IDE设计器的简化。设想一下,如果可以在程序运行时,再设计一个Form,然后编译代码,那是多么强大呀。下面介绍几个重要的Runtime FormDesigner,其中大部分来自了微软的官方网站或MSDN。

重要的链接资源
下面介绍有4个重要的Form设计器,它们是:
1,Designerhost
http://support.microsoft.com/?id=813808
INFO: 代码示例演示如何通过使用 VisualC # .NET 创建自定义窗体设计器
.Net1.1下运行的Form设计器

2,DesignerHosting
http://msdn.microsoft.com/msdnmag/issues/06/03/DesignerHosting/default.aspx
.Net2.0下运行的Form设计器

3,CustomFormsDesigner
http://download.microsoft.com/download/d/3/1/d31fff33-fd97-488f-9bbd-4b7402905716/CustomFormsDesigner.exe
.Net1.1下运行的Form设计器

4,Hosting
http://www.divil.co.uk/net/articles/designers/hosting.asp
来自divil.co.uk的Hosting
.Net2.0下运行的Form设计器

运行效果图
下面是1,DesignerHost就运行图,你是不是很震惊呢?反正,我第一眼看到这个运行时窗体设计器时,实在是太震惊了,一个只有20-30个源文件的项目,运行时,能够产生如此强大的界面,真是不敢相信,又万分喜悦,而其它三个FormDesigner也是产生相似的界面。这简直就是一个IDE系统,与VisualStudio2005一样啊,而且,它可以产生代码,可以产生C# Source,VB Source和XML。

功能介绍
工具的左边是工具箱,右边是属性设置窗口,中间是Form设计器,工具箱,跟平时使用的VisualStudio一样,多个选项卡,WindowsForms选项卡中有多个普通工具,有Components选项卡中有部件控件,而CustomControls选项卡中有用户自定义的控件,Datas选项卡中有系统的数据链接控件,如OleDbConnection之类,当然,也不仅仅是这些内容,你可以通过代码修改来增改左侧的控件。
往上一点看,有Design,C#Source,VB Source,XML四个视图的选择,Design是设计视图,指的就是当前看到的界面,C# Source,VB Source跟我们在IDE工具中使用查看源代码所得到的东西一样。而XML则是我们之前没有见到的。它用于描述当前的Form的内容,如Form的属性和值,布局,层次,Form中的控件等等。
菜单栏中,File下拉后,就是日常的保存,另保存,打开,退出等功能,而Edit就是编辑功能,如,复制,剪切,删除,对齐等,View就是视图界面,如Design,C#Source,VB Source,XML,Layout就是控件的层次移动等,Debug中,就是运行,编译等功能。

可以说上,这个控件是四个中做得比较好的。操作起来也方便。
精彩的文章还在继续,下一会,将介绍Runtime Form Designer的机制,编写,编译方法,请留意订阅首页的Rss

运行时窗体设计器Runtime Form Designer一出现,就会以其出色的表现,奇怪的代码吸引,怎么说是奇怪的代码呢?设计器所使用到的ImenuCommandService,InameCreationService,ItoolboxService,IUIService,IdesignerHost,IselectionService 这些接口,使用过没用?在设计一个运行时设计器时,忽然学得,自己是在学习一个新的语言,是使用.Net来表示的底层界面接口语言。简单而言,.Net已经帮助你写好了底层的底层,那就是编写设计的接口。你只要继承或重写代码,就可以实现设计器的功能。查看重要的Form设计器用这个网址:
http://www.myfirm.cn/News/DotNetUserInterface/20080221013104408.html
为了使用最简单的方式来说明问题,使用最简单的设计器来做说明,下面介绍Hosting

效果图

所有代码图

这个项目,相当的小,上面显示的就是所有的源文件,可以高兴地认为,只要学会了上面的类,就成功了。事实上,只要学会几个重要的类,就可以了。

重点研究的接口
在理解下面接口的时候,可以理解为,自己是微软的高级工程师,正在为VisualStudio开发工具箱,界面,界面,菜单等等界面功能。
IMenuCommandService
提供的方法用于管理设计模式下可用的全局设计器谓词和菜单命令,以及显示某些类型的快捷菜单。
简单说,就是新建的控件,在窗体Form中产生的命令,如移动,对齐,层次叠放,复制,剪切,粘贴
INameCreationService
提供可以生成对象的唯一名称的服务。
因为各个拖出来的控件都必须有唯一的名称,这样,才可以编译通过的。
IToolboxService
提供在开发环境下管理和查询工具箱的方法和属性。
这就是一个工具箱,一个同工具箱提供一样功能的服务。
IDesignerHost
提供用于管理设计器事务和组件的接口。
这是最重要的接口,所有的控件都是由这个接口发出,可以理解为,从这个接口可以找到所有控件的引用。
ISelectionService
为设计器提供用于选择组件的接口。
就是当程序运行时,在Form设计器选择控件时,产生的事件,它常常被用来更新属性窗口。
IUIService
启用与开发环境对象(正在承载设计器)的用户界面的交互。
PropertyGrid
这不是一个接口,这只是一个控件,不过,提供了属性设置服务,是用户交互最频繁的服务之一。

服务的加载
可以这样理解,运时时Form设计器,就是一个服务的集合,服务管理器ServiceContainer初始化之后,绑定DesignerHost,然后不断增加服务,如
InameCreationService,名字唯一服务
ItoolboxService,工具箱服务
ImenuCommandService,菜单命令服务
IselectionService,选择服务(同时产生选择变化事件,从而改变属性显示)
PropertyGrid,属性设置服务
最后,由DesignerHost做激活动作,host.Activate();

关于命令服务
在运行时设计器中,要删除选定的控件,只能使用命令接口提供的功能。如
menuService.GlobalInvoke(StandardCommands.Delete);
当然,一个很高明的做法是,一开始就将DesignerHost的所有可能的命令纳入线程的管理,在designerhost.exe,中有使用。你可以在上一篇介绍Runtime Form Designer的文章中,找到这个控件的链接。

下一篇,将介绍Runtime FormDesigner的运行和编译机制,不可错过。

之前已经有两篇文章对Form Designer运行了分析和展示,具体展示了几个重要的开源Form设计器,也介绍了最基本的Form设计器的编写方式。而在介绍Hosting设计器时,没有提及到代码的展示与编译运行机制,下面,本文就对运行时Form设计器的代码转换和编译机制进行分析和学习。下面介绍Designerhost工具。

界面效果图

代码的产生
将注意力投放到SampleDesignerLoader.cs类,上图中Design,C# Source,VB Source,XML视图的变化,都会产生事件,事件处理方法就是SampleDesignerLoader类的Flush方法,表示对当前控件与代码的刷新。
一个重要的类,类中的类
System.CodeDom.CodeCompileUnit
在.Net中,一个源文件,如C#写好的.cs文件,其实可以转化为一个类中类CodeCompileUnit,这个类中类有构造函数,方法体,属性,命名空间等等的定义。如引入System命名空间,你可以这样写Imports.Add(new CodeNamespaceImport("System")); CodeConstructor是用来定义构造函数的。可以说,一个类实体的定义,运行时本身就是一个CodeCompileUnit类的实例。类的序列化功能,就是由CodeCompileUnit发起的重要功能。
类的序列化可以将一个类变成一个文件如XML,而这个XML中记录了各个属性和值,在网络环境中,就可以作为一个传送的介质,这样,就可以实现类的远程调用。

重要的代码

RootDesignerSerializerAttribute a =       TypeDescriptor.GetAttributes(root)[typeof(RootDesignerSerializerAttribute)] as            RootDesignerSerializerAttribute;
Type t = host.GetType(a.SerializerTypeName);
CodeDomSerializer cds = Activator.CreateInstance(t) as CodeDomSerializer;
IDesignerSerializationManager manager =        host.GetService(typeof(IDesignerSerializationManager)) as IDesignerSerializationManager;
CodeTypeDeclaration td = cds.Serialize(manager, root) as CodeTypeDeclaration;


在设计界面拖动的控件和设置的属性都通过对根设计器的序列化,被完全提取出来,成为一个CodeCompileUnit的主体部分。再增加构造函数和其它属性就可以了。

编译与生成
要编译的话,就必须传入数据CodeCompileUnit,然后使用CsharpCodeProvider,
VBCodeProvider就可以生成相应代码,也就是说,在设计的时候,不必要先指定使用何种语言,在设计完Form之后,再选定就可以了。因为,Form设计器最后产生的,是CodeCompileUnit,而不是代码。
在SampleDesignerLoader.cs类上,也提供了Build方法,这就是生成DLL或EXE文件,因为在Windows平台上,可以正常使用类集合的,就只要用这两个扩展名。只要使用CompilerParameters类和当前的程序类,传入CodeCompileUnit就可以了。之后,就只是生成选择了。详情请查看Build方法

Posted on 2008-03-04 11:42  Chio  阅读(2945)  评论(0)    收藏  举报
©2008 Suprasoft Component Intelligence Inc., All right reserved.