2016-08-23 112 views
0

我创建了System.Windows.Forms.DataVisualization.Charting.Chart的子类。在构造函数中我已经设置了一个默认的图表面积和系列:继承.NET图表控件

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函数中删除代码,但是在图表控件的设计器中没有获得可视化表示,而且手动编辑它似乎是不好的做法。

什么是子类图表控件,这样我可以设置在子类中的区域和一系列正确的方法是什么?

+2

与花哨的设计师(如Chart)一起进行控制时,如果从它们派生出来,往往会出现错误。他们的设计师无法分辨您在构造函数中添加的系列与您在设计师中添加的任何系列之间的区别。所以它会尽职尽责地序列化你在构造函数中创建的那个。当你在设计师中创建系列时,你不太可能想要这样做。更糟的是,你的构造函数*也*在运行时运行,现在你有*两个*系列你不想要的。解决这个问题需要修改设计师。完全不切实际,它是无证的,非常复杂。停止帮助吧。 –

+0

谢谢。我很害怕。 – Andy

回答

1

为了实现你的目标,你需要从System.Windows.Forms.Design.ControlDesigner定义派生的类并分配作为您的自定义图表类的设计者。最初ChartAreaSeriesLegend所有创作应在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); 
     } 
    } 
} 
1

如果您只希望能够更改一些属性,则解决方法可能是创建一个包含图表的UserControl,然后向该控件添加一些属性,以根据需要修改图表。在实践中,只有当你有很多共同的变化,但很少有具体的变化时,这才会有用。

或者,你可能有一个辅助类当表单是加载,你会调用,并适用在运行时的一些变化。设计师不会显示图表的实际外观。

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

通常情况下,如果控制必须管理的子控件或列表,从控制导出可能导致问题......对于简单的控制,往往可能只是少了几分最优的,因为一些属性可能会设置两次...