子类化.NET图表控件

时间:2016-08-23 12:03:15

标签: c# .net winforms

我已经创建了System.Windows.Forms.DataVisualization.Charting.Chart的子类。在构造函数中,我设置了一个默认的图表区域和系列:

System.Windows.Forms.DataVisualization.Charting.ChartArea chartArea1 = new System.Windows.Forms.DataVisualization.Charting.ChartArea();
System.Windows.Forms.DataVisualization.Charting.Series series1 = new System.Windows.Forms.DataVisualization.Charting.Series();

chartArea1.AxisX.Title = "Time (s)";
chartArea1.AxisY.Title = "Value(%)";
chartArea1.Name = "MainChartArea";
series1.ChartArea = "MainChartArea";
series1.ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.FastLine;
series1.Name = "Series1";
Series.Add(series1);

我已经在子类中添加了一组函数来使用ChartAreas [0]。这一切都很好。

现在在VS2010中我创建了一个新控件,转到工具箱并添加我的自定义图表控件。似乎发生了什么是VS将我的默认图表区域和系列复制到父控件的InitializeComponent函数。

当我执行代码时,父控件的InitializeComponent函数中有一个异常,说明图表的子类已经有一个名为“MainChartArea”的图表区域,并且已经有一个名为“Series1”的系列。

如果我现在编辑父控件InitializeComponent代码来更改它构建的名称并运行得很好。

但是,如果我现在返回并对父控件进行任何更改VS再次重新复制默认图表区域和系列设置,从而导致同样的问题。

我知道我可以简单地从父控件的InitializeComponent函数中删除代码,但是我没有在图表控件的设计器中获得可视化表示,并且手动编辑它似乎是不好的做法。

子类化Chart控件的正确方法是什么,以便我可以在子类上设置区域和系列?

2 个答案:

答案 0 :(得分:1)

如果您只想更改一些属性,可以尝试创建包含图表的UserControl,然后向该控件添加一些属性,以根据需要修改图表。实际上,只有当你有很多常见的变化但很少有具体的变化时,这才有用。

或者,您可能有一个辅助类,您可以在加载表单时调用它,并在运行时应用一些更改。设计师不会显示图表的实际外观。

正如评论中所提到的,当您从它们派生时,并非所有控件都按照需要(在设计器中)运行。有可能通过编写大量代码来处理设计时版本和序列化来解决一些问题,但我基本上没有经验。

通常,如果一个控件必须管理子控件或列表,那么从该控件派生可能会导致问题...对于简单的控件,通常它可能只是不太理想,因为某些属性可能被设置两次... < / p>

答案 1 :(得分:1)

要实现目标,您需要定义一个派生自System.Windows.Forms.Design.ControlDesigner的类,并将其指定为自定义Chart类的Designer。所有初始ChartAreaSeriesLegend的创建都应在ControlDesigner类方法InitializeNewComponent中执行,而不是自定义Chart的构造函数。

using System;
using System.Threading.Tasks;
using System.Windows.Forms.DataVisualization.Charting;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
    [System.ComponentModel.Designer(typeof(MyChartDesigner))]
    public class MyChart : Chart
    {
    }

    // Add Project Ref:  System.Design
    internal class MyChartDesigner : System.Windows.Forms.Design.ControlDesigner
    {
        public override void InitializeNewComponent(System.Collections.IDictionary defaultValues)
        {
            if ((this.Control != null) && this.Control is Chart)
            {
                Chart control = (Chart)this.Control;
                if ((control.ChartAreas.Count == 0) && (control.Series.Count == 0))
                {
                    ChartArea chartArea1 = new System.Windows.Forms.DataVisualization.Charting.ChartArea();
                    Series series1 = new System.Windows.Forms.DataVisualization.Charting.Series();

                    chartArea1.AxisX.Title = "Time (s)";
                    chartArea1.AxisY.Title = "Value(%)";
                    chartArea1.Name = "MainChartArea";
                    series1.ChartArea = "MainChartArea";
                    series1.ChartType = SeriesChartType.FastLine;
                    series1.Name = "Series1";

                    control.ChartAreas.Add(chartArea1);
                    control.Series.Add(series1);
                }
            }
            base.InitializeNewComponent(defaultValues);
        }
    }
}