在以多种形式调用方法时,类变量会重置

时间:2011-11-03 14:45:55

标签: c# winforms

已更新以反映我自己的来源

我正在使用c#构建我的第一个winform应用程序,并且我正在尝试找出构建我的类以便在我的表单中使用它们时顺利运行的最佳实践。 我有几个例子,我将尝试解释最好的方法。

在类中使用get / set变量时,最佳实践应该是这样的:

JobMove.cs

public class JobMove
{
    private List<string> jobNames { get; set; }
    public string Scanner;

    public JobMove()
    {
        this.Scanner = Properties.Settings.Default.Scanner;
    }

    public void ListSelected(ListBox lbx)
    {
        foreach (string jName in this.jobNames)
        {
            lbx.Items.Add(jName);
        }
    }

    public static List<string> GetCheckedJobs(ListView lw)
    {
        int countChecked = lw.CheckedItems.Count;
        int itemCount = 0;
        List<string> jList = new List<string>();

        foreach (ListViewItem item in lw.CheckedItems)
        {
            JobInfo jobInfo = Job.Find(Convert.ToInt32(lw.Items[item.Index].SubItems[1].Text));
            jList.Add(jobInfo.Name);
            itemCount++;
        }
        return jList;
    }
}

我的问题是,当我将其与我的表格结合起来并且我称之为,然后我会尝试做这样的事情:

MyForm1.cs

public partial class MyForm1 : Form
{
    private void btnMoveJobs_Click(object sender, EventArgs e)
    {
        Properties.Settings.Default.Scanner = cbxScanners.SelectedItem.ToString();

        JobMove moveJobs = new JobMove();

        frmMoveJobs FrmMoveJobs = new frmMoveJobs();
        FrmMoveJobs.ShowDialog();
    }
}

MyForm2.cs

public partial class frmMoveJobs : Form
{
    public frmMoveJobs()
    {
        InitializeComponent();

        JobMove moveJobs = new JobMove();
        lblFrom.Text = moveJobs.Scanner;
        moveJobs.ListSelected(lbxJobsToMove);

        cbxMjScanners.DataSource = System.Enum.GetValues(typeof(Scanners));
    }
}

但是当我在 MyForm2 中调用 MyClass 并且我想调用 DoSomethingElse 方法时,myString将重置为 null 值。这对我来说很有意义,但我该如何解决这个问题?

我试图找出在这里使用什么来更容易地解决我的代码中的这些缺陷,但我的知识太弱了,无法实现一个简单的解决方案。 我知道我可以将这个变量存储在Settings.settings中作为一个例子,但对我来说,这似乎是一个真正的重载这样一个简单的任务。

在这种情况下,我可能只需要在正确的方向上指出要做什么。

6 个答案:

答案 0 :(得分:4)

如果你确实做了MyClass myClass = new MyClass();,那么这些价值是独立且无关的。如果您想共享MyClass实例,那么传递表单之间的MyClass实例。也许:

using(var form2 = new Form2()) {
    form2.SensibleName = existingMyClassInstance;
    form2.ShowDialog();
}

(请注意上面的using顺便说一句;使用ShowDialog()时,确保表单处理是您的工作;只有在使用Show()时才会自动处理

答案 1 :(得分:3)

首先,它们是属性,而不是变量(变量是底层数据源)。

其次,get / set访问器的重点是,您可以在不需要辅助方法的情况下获取和设置值。

第三,关于你的问题,你要在每个表单中创建一个新的类实例(由new关键字提示),并且属性的值将是初始化的任何值。构造实例(或不。),即属性的值不在同一类型的不同实例之间共享。

想想一把钥匙的模具:我可以从“蓝图”中得到多个关键切割实例,但是受到的任何损害都不会被其他人反映出来 - 在这个意义上它们是独一无二的。 / p>

如果您希望表单同时访问该类型的同一实例,那么您需要将代码存储在代码中的某个位置,这两个实例都可以访问。

答案 2 :(得分:1)

一些选择:

  1. 在form2的构造函数中传入MyClass的实例。

  2. MyClass设为Form1Form2的静态属性,并通过其他表单访问该属性。

  3. MyClass静态(不推荐)

答案 3 :(得分:0)

如果您想使用MyClassMyForm1内创建的MyForm2实例,则需要将其提供给MyForm2

这样的事情会起作用:

public partial class MyForm2 : Form
{
    public MyForm2(MyClass given)
    {
        InitializeComponent();

        given.DoSomethingElse();
    }
}

答案 4 :(得分:0)

这是因为你的每个表单都有一个“MyClass”的新对象。

要实现您想要做的事情,请使用静态属性...这将不会被初始化并为MyClass的每个对象返回相同的值 看起来像这样

public class MyClass {
   public static string myString { get; set; }

   public void ChangeMyString(string newString)
   {
       myString = newString;
   }

   public void DoSomethingElse()
   {
       MessageBox.Show(myString);
   }

}

答案 5 :(得分:0)

简易解决方案:

private static string myString { get; set; } 

为什么:因为在初始化Form2时再次初始化类,它将创建一个新类。使用“static”关键字,您可以创建一个在此类的所有实例中都相同的属性。

但是:请在继续之前阅读一些书籍,这将是解决这个问题的方法,但却是许多其他人的来源。尝试首先了解C#和Forms,然后(或者与阅读/学习一起)开始编码!

相关问题