C# NET图表控件的子类化
我已经创建了System.Windows.Forms.DataVisualization.Charting.Chart的子类。在构造函数中,我设置了默认图表区域和系列:C# NET图表控件的子类化,c#,.net,winforms,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.DataVisu
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代码,以更改它生成和运行的名称,就可以了
但是,如果现在返回并对父控件进行任何更改,则会再次复制默认图表区域和系列设置,从而导致相同的问题
我知道我可以简单地从父控件的InitializeComponent函数中删除代码,但是我没有在图表控件的设计器中获得可视化表示,手动编辑它似乎是一种不好的做法
对图表控件进行子类化的正确方法是什么,以便我可以在子类上设置区域和系列?如果您只想更改一些属性,解决方法可能是创建一个包含图表的
UserControl
,然后向该控件添加一些属性,以便根据需要修改图表。实际上,只有当您有很多常见的更改,但很少有特定的更改时,这才有用
或者,您可能有一个helper类,在加载表单时调用该类,并在运行时应用一些更改。设计者不会显示图表的实际外观
如注释中所述,当您从控件派生时,并非所有控件(在设计器中)的行为都符合要求。也许可以通过编写大量代码来处理设计时版本和序列化来解决一些问题,但我基本上没有这方面的经验
通常,如果控件必须管理子控件或列表,则从该控件派生可能会导致问题。。。对于简单的控件,通常情况下可能会有点不太理想,因为某些属性可能会设置两次…如果您只想更改一些属性,解决方法可能是创建一个包含图表的
UserControl
,然后向该控件添加一些属性,以便根据需要修改图表。实际上,只有当您有很多常见的更改,但很少有特定的更改时,这才有用
或者,您可能有一个helper类,在加载表单时调用该类,并在运行时应用一些更改。设计者不会显示图表的实际外观
如注释中所述,当您从控件派生时,并非所有控件(在设计器中)的行为都符合要求。也许可以通过编写大量代码来处理设计时版本和序列化来解决一些问题,但我基本上没有这方面的经验
通常,如果控件必须管理子控件或列表,则从该控件派生可能会导致问题。。。对于简单的控件,它通常可能只是有点不太理想,因为某些属性可能会设置两次…为了实现您的目标,您需要定义一个派生自
System.Windows.Forms.Design.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);
}
}
}
为了实现您的目标,您需要定义一个派生自System.Windows.Forms.Design.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);
}
}
}
带有花式设计器的控件(如图表)在从它们派生时往往会出现错误行为。他们的设计器无法区分您在构造函数中添加的系列与使用设计器添加的任何系列之间的差异。因此,它也尽职尽责地序列化了您在构造函数中创建的一个。当您在designer中创建一个系列时,您不太可能希望这样。更糟糕的是,您的构造函数也在运行时运行,现在您有两个不需要的序列。修复此问题需要与设计师进行修补。完全不实际,它是没有文件记录的,而且非常复杂。别再帮忙了,谢谢。我也很害怕。有花哨设计师的控件,比如图表,当你从它们派生出来时,往往会表现不好。他们的设计器无法区分您在构造函数中添加的系列与使用设计器添加的任何系列之间的差异。因此,它也尽职尽责地序列化了您在构造函数中创建的一个。当您在designer中创建一个系列时,您不太可能希望这样。更糟糕的是,您的构造函数也在运行时运行,现在您有两个不需要的序列。修复此问题需要与设计师进行修补。完全不实际,它是没有文件记录的,而且非常复杂。别再帮忙了,谢谢。我也很害怕。