子类化.net图表控件

本文关键字:控件 net 子类 | 更新日期: 2023-09-27 18:03:39

我已经创建了system . windows . forms . datavvisualize . charts . 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函数中删除代码,但这样我就无法在图表控件的设计器中获得可视化表示,并且手动编辑它似乎是糟糕的做法。

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

子类化.net图表控件

要完成您的目标,您将需要定义一个从System.Windows.Forms.Design.ControlDesigner派生的类,并将其指定为自定义图表类的设计器。所有初始的ChartArea, SeriesLegend的创建都应该在ControlDesigner类方法InitializeNewComponent中执行,而不是在自定义图表的构造函数中执行。

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);
        }
    }
}

如果您只希望能够更改一些属性,那么一个解决方法可能是创建一个包含图表的UserControl,然后向该控件添加一些属性,以便根据需要修改图表。在实践中,只有当您有很多常见的更改,但很少有特定的更改时,这将是有用的。

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

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

通常,如果控件必须管理子控件或列表,从该控件派生可能会导致问题…对于简单的控件,它可能只是有点不太理想,因为有些属性可能会设置两次…