C#创建类的全局对象以在多个表单上使用

时间:2017-02-19 18:35:55

标签: c# visual-studio global

我想创建一个类的多个对象,在一个表单上编辑它们,然后在多个表单上使用这些对象。希望下面的代码会尝试突出显示问题。

我创建了一个类......

public class Player
{
        public string name;
        public int goals;        
}

在Form1上我创建了tom和dan,并添加了按钮,这些按钮会在按下时增加其目标数。

public partial class Form1 : Form
{

    Player tom = new Player()
    {
        name = "Tom",
        goals = 5
    };

    Player dan = new Player()
    {
        name = "Dan",
        goals = 7
    };

    public void UpdateForm()
    {
        label1.Text = tom.name;
        label2.Text = dan.name;
    }


    public Form1()
    {
        InitializeComponent();
        UpdateForm();
    }

    private void button1_Click(object sender, EventArgs e)
    {
        tom.goals += 1;
    }

    private void button2_Click(object sender, EventArgs e)
    {
        dan.goals += 1;
    }
}

然后我希望能够在form2上显示他们的名字和新的目标数量。我遇到的问题是那些对象在该上下文中不存在。

{
public partial class Form2 : Form
{
       public void UpdateForm2()
    {
        label1.Text = tom.name;
        label2.Text = tom.goals;
        label3.Text = dan.name;
        label4.Text = dan.goals;
    }


    public Form2()
    {
        InitializeComponent();
        UpdateForm2();
    }
}
}

如何在表单之间使这些对象全局化并可编辑?我试图找到一个答案,但没有找到一个与这个用例完全匹配的答案。我将不胜感激任何帮助和建议。

6 个答案:

答案 0 :(得分:1)

您的Form1课程与其他课程一样。因此,您可以在其中创建2个属性:

public partial class Form1 : Form
{
    public Player Tom { get; private set; }
    public Player Dan { get; private set; }

    this.Tom = new Player()
    {
        name = "Tom",
        goals = 5
    };

    this.Dan = new Player()
    {
        name = "Dan",
        goals = 7
    };    

    // The rest of your code
}

Form2中引入属性:

public partial class Form2 : Form
{
    public Form1 CallingForm {get; set;}   
    public Form2()
    {
        InitializeComponent();
        UpdateForm2();
    }
}

在显示第二个表单之前设置该属性(将此代码放在第一个表单中):

Form2 f2 = new Form2();
f2.CallingForm = this;

然后在第二种形式中你可以像这样访问玩家:

label1.Text = CallingForm.Tom.name;

如果您有更多玩家,请改为创建List<Player>属性。

其他一些说明

尝试遵循.NET命名约定而不是公共字段,请使用属性。属性可用于数据绑定和封装,验证,也有其他好处。

public class Player
{
    private int goals;
    public string Name {get; set;}
    public int Goals 
    {
        get { return this.goals; }
        set 
        {
            if (value < 0)
            {
                throw new ArgumentException("Goals cannot be less than 0.");
            } 
            this.goals = value;
        }  
     }      
}

答案 1 :(得分:0)

您似乎需要一个包含List<Person>的服务类。然后让您的两个表单共享该服务的相同实例。或者懒惰的选项是使服务成为静态类。

<强>更新

您还可以考虑在服务中实现Observer模式。

http://www.dofactory.com/net/observer-design-pattern

答案 2 :(得分:0)

您需要了解命名空间的概念。如果在一个表单的命名空间中创建对象,则不能在不引用该特定表单的情况下使用该特定对象。

到目前为止,我可以看到,您已在player命名空间中创建了两个对象form的实例。但是form2命名空间中没有。因此,你得到了这个错误。

您可以使用常用的许多方法进行更新,例如

  • 调用子窗口的方法来更新值。
  • 使用调解员
  • 在价值变化时向form2添加事件监听器。

使用对象实例或静态对象的全局实例不是最佳实践。

答案 3 :(得分:0)

您可以在第二种形式的构造函数中传递玩家列表。

答案 4 :(得分:0)

是的,必须传输数据新表格。 Meybe使用 将参数发送到Form2 构造函数参数或使用 form2 Set Method

例如:

      private readonly Player _tom;
      private readonly Player _dan;

     public Form2(player tom, player dan) // or use List<Player> parameter
        {
            InitializeComponent();
            _tom = tom;
            _dan = dan;
        }

另一种方式

// Form2.cs

private Player _tom;
private Player _dan;

public void SetPalyers(Player tom, Player dan)
{
  _tom = tom;
 _dan = dan;
}

答案 5 :(得分:0)

考虑封装。您的Form2无法访问实例化的类对象,因为它们包含在Form1中。

撰写以下内容时:

label1.Text = tom.name;

编译器正在寻找对象Form2.tom,但它并不存在。

你必须告诉它在哪里看,如下:

label1.Text = Form1.tom.name;

要在不使用Form1前缀的情况下使这些对象可用于所有选定的类,所选的类必须是Form1的子类。除此之外,您必须按照我之前解释的方式回顾它们。