从第二种形式的主表单控制图表 [英] Control chart on main form from second form

查看:65
本文介绍了从第二种形式的主表单控制图表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试添加和删除从第二个表单在主表单上初始化的图表的系列。



下面的代码编译,但系列数据被添加到另一个图表实例,而不是主窗体上的那个。如何在主窗体上引用图表实例来控制它,并从其他窗体控制图表?



我尝试过:



  //  主窗体中添加/删除系列数据的方法 

public static void PLOT_PAYOFF(List< string> lstGREEK,List< string> lstSTRATEGY) // 允许从第二种表单访问的静态方法
{
nmCHART.clsCHART oCHART = new nmCHART.clsCHART();

图表chrtPAYOFF = new Chart(); // 创建新实例将系列数据放在此新图表上,而不是主要图表
chrtPAYOFF.Series.Clear(); // 在chrtPAYOFF之前放置'Main'会产生编译错误Main.chrtPAYOFF.Series.Clear();

int S,G;
string GREEK,STRATEGY,SeriesName;
double [] Y = new double [ 20 ];

// 获取X轴数据
double [] X = new double [ 20 ];
X = oCHART.GET_X_SERIES();

for (G = 0 ; G < = lstGREEK.Count - 1 ; G ++)
{
for (S = 0 ; S < = lstSTRATEGY.Count - 1 ; S ++)
{
GREEK = lstGREEK [G];
STRATEGY = lstSTRATEGY [S];
SeriesName = STRATEGY + - + GREEK;
// 获取Y轴数据
Y = oCHART.GET_Y_SERIES(GREEK,战略);
chrtPAYOFF.Series.Add(SeriesName);

chrtPAYOFF.Series [SeriesName] .ChartType = SeriesChartType.Line;
chrtPAYOFF.Series [SeriesName] .Points.DataBindXY(X,Y);
}
}

// 要调用的第二个表单上的方法主表单上的方法

private void cmdPROCESS_Click( object sender,EventArgs e)
{
List< string> lstSTRATEGY = new List< string>();
List< string> lstGREEK = new List< string>();


foreach object itemChecked in chkbxGREEKS.CheckedItems)
{
lstGREEK.Add(itemChecked.ToString());
}

foreach object itemChecked in chkbxSTRATEGIES.CheckedItems)
{
lstSTRATEGY.Add(itemChecked.ToString());
}

Main.PLOT_PAYOFF(lstGREEK,lstSTRATEGY);

}

解决方案

首先,移动创建图表实例

 nmCHART.clsCHART oCHART =  new  nmCHART.clsCHART(); 
图表chrtPAYOFF = new Chart();

之外的静态方法,并放入Form范围:现在您每次在主窗体上调用静态方法时都要创建这些图表对象的新实例:这些新实例永远不会添加到窗体的ControlCollection中,并且它们将被丢弃(您没有引用它们)在主窗体中该方法的范围之外。



其次,想想你真正想做的事情:imho,你想能够打电话给从第二种形式更新方法。为什么不考虑将方法体注入第二种形式,让你直接在主窗体上调用方法,而没有使用'静态(即恕我直言,代码味)的业务。



这里有一个简单的策略示例,可以最大限度地减少两个表单的依赖关系(我在教授私人学生时使用这种类型的例子):



主窗体:

 命名空间 YourNameSpace 
{
public partial class MainForm:Form
{
private Form2 f2;

public MainForm()
{
InitializeComponent();

f2 = new Form2();
f2.SendData = DataReceiver;
f2.Show();
}

private void DataReceiver(List< string> list1 ,List< string> list2)
{
// 在这里放置一个断点,检查参数
}
}
}

第二个表格:

 命名空间 YourNameSpace 
{
public partial class Form2:Form
{
public Form2()
{
InitializeComponent ();
}

public 操作< List< string> ;, List< string>> SendData { set ; get ; }

public List< string> List1 = new 列表< string>
{
一个
two
};

public 列表< string> List2 = new 列表< string>
{

four
};

private void button1_Click(对象发​​件人,EventArgs e)
{
// 假设两个列表都必须是否为空?
如果(SendData!= null && ; List1!= null && List2!= null
SendData(List1,列表2);
}
}
}





注意:



1.此处使用的操作< List< string>,List< string>> 实际上是创建委托类型和声明的捷径它的一个例子。 Action 一个具有调用列表的完整代表,并且向所有订阅者进行多播。



2.主表单通过在Main表单上直接分配对私有方法的引用,将其DataReceiver方法的引用注入到第二个Form的'SendData Action公共属性中...注意我们不必使用+ =。我们也可以使用lambda表达式。



使用这样的注入方法就是创建回调的一个例子。



所有这一切的目标是将最小内部状态和Form1的对象暴露给Form2,将Form2暴露给Form1:这是封装和松散耦合。


I am trying to add and delete series to a chart initialized on the Main form from a second form.

The code below compiles, but series data is added to another chart instance, not the one on the main form. How do I reference the instance of the chart on the Main form to control it, and also control the chart from other forms?

What I have tried:

// Method in Main form to add/delete series data

 public static void PLOT_PAYOFF(List<string> lstGREEK, List<string> lstSTRATEGY)         // Static method to allow access from second form
        {
            nmCHART.clsCHART oCHART = new nmCHART.clsCHART();

            Chart chrtPAYOFF = new Chart();     // creating a new instance put series data on this new chart, not the chart on Main
            chrtPAYOFF.Series.Clear();          // placing 'Main' before chrtPAYOFF gives a compile error   Main.chrtPAYOFF.Series.Clear(); 

            int S, G;
            string GREEK, STRATEGY, SeriesName;
            double[] Y = new double[20];

            // Get X Axis data
            double[] X = new double[20];
            X = oCHART.GET_X_SERIES();

            for (G = 0; G <= lstGREEK.Count - 1; G++)
            {
                for (S = 0; S <= lstSTRATEGY.Count - 1; S++)
                {
                    GREEK = lstGREEK[G];
                    STRATEGY = lstSTRATEGY[S];
                    SeriesName = STRATEGY + "-" + GREEK;
                    // Get Y Axis data
                    Y = oCHART.GET_Y_SERIES(GREEK, STRATEGY);
                    chrtPAYOFF.Series.Add(SeriesName);

                    chrtPAYOFF.Series[SeriesName].ChartType = SeriesChartType.Line;
                    chrtPAYOFF.Series[SeriesName].Points.DataBindXY(X, Y);
                }
            }

// Method on second form to call method on Main form

 private  void cmdPROCESS_Click(object sender, EventArgs e)
        {
            List<string> lstSTRATEGY = new List<string>();
            List<string> lstGREEK = new List<string>();


            foreach (object itemChecked in chkbxGREEKS.CheckedItems)
            {
                lstGREEK.Add(itemChecked.ToString());
            }

            foreach (object itemChecked in chkbxSTRATEGIES.CheckedItems)
            {
                lstSTRATEGY.Add(itemChecked.ToString());
            }

            Main.PLOT_PAYOFF(lstGREEK, lstSTRATEGY);

        }

解决方案

First, move the creation of instances of the charts

nmCHART.clsCHART oCHART = new nmCHART.clsCHART();
Chart chrtPAYOFF = new Chart();

outside of the static method, and put in Form scope: right now you are creating new instances of those chart objects every time you call the static method on the Main Form: those new instances are never added to the ControlCollection of the Form, and they are disposed of (you have no reference to them) outside the scope of that method in the Main form.

Second, think about what you really want to do here: imho, you want to be able to call the update method from the second form. Why not consider injecting a method body into the second form that lets you call the method on the main form directly, without this business of using 'static (which is, IMHO, a code smell).

Here's a bare-bones example for a strategy that minimizes the dependency of the two Forms (I use this type of example in teaching private students):

The Main Form:

namespace YourNameSpace
{
    public partial class MainForm : Form
    {
        private Form2 f2;
        
        public MainForm()
        {
            InitializeComponent();
        
            f2 = new Form2();
            f2.SendData = DataReceiver;
            f2.Show();
        }
        
        private void DataReceiver(List<string> list1, List<string> list2)
        {
            // put a break-point here, examine the parameters    
        }
    }
}

The second Form:

namespace YourNameSpace
{
    public partial class Form2 : Form
    {
        public Form2()
        {
            InitializeComponent();
        }

        public Action<List<string>, List<string>> SendData { set; get; }

        public List<string> List1 = new List<string>
        {
            "one",
            "two"
        };

        public List<string> List2 = new List<string>
        {
            "three",
            "four"
        };

        private void button1_Click(object sender, EventArgs e)
        {
            // assume both Lists have to be non-null ?
            if (SendData != null && List1 != null && List2 != null) 
SendData(List1, List2);
        }
    }
}



Notes:

1. the Action<List<string>,List<string>> used here is really a short-cut for creating a Delegate Type and declaring an instance of it. An Action is a full-fledged Delegate with an Invocation List, and multi-casting to all subscribers.

2. the Main form injects a reference to its DataReceiver method into the second Form's 'SendData Action public Property by direct assignment of a reference to a private method on the Main form ... note we didn't have to use += . We could also use a lambda expression.

Using an injected method like this is an example of creating a "call-back."

The goal of all this is to expose the minimum internal state and objects of Form1 to Form2, and Form2 to Form1: that's encapsulation, and loose-coupling.


这篇关于从第二种形式的主表单控制图表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆