如何在两个表单之间共享整数声明?

时间:2016-12-16 19:18:04

标签: c# winforms

我目前正在WFA中使用c#进行一些基本的增量游戏。这是代码:

namespace Xadrs
{
public partial class Form1 : Form
{


    public void Ref()
    {
        label2.Text = Points.ToString();
        button2.Text = "Level up! (" + Upgradeprice.ToString() + ")";
        label4.Text = Upgrade.ToString();
        label6.Text = Upgradeautoclick.ToString();
        button4.Text = "Level up PPS! (" + Upgradeautoclickprice.ToString() + ")";
    }
    public int ach_beginner = 0;
    public int ach_intermediate = 0;
    public int ach_expert = 0;
    public int ach_master = 0;



    int Points = 0; 
    int Upgrade = 1;
    int Upgradeautoclick = 0 ;
    int Upgradeautoclickprice = 110;
    int Upgradeprice = 25;


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

    private void timer1_Tick(object sender, EventArgs e)
    {
        if (Upgrade == 5)
        {
            Points++;
            Ref();
        }


    }

    private void button1_Click(object sender, EventArgs e)
    {
        Points += Upgrade;
        Ref();


    }



    private void button2_Click(object sender, EventArgs e)
    {
        if (Points >= Upgradeprice)
        {
            Upgrade += 1;
            Points -= Upgradeprice;
            Upgradeprice += Upgradeprice / 4;

        }
        else
        {
            MessageBox.Show("Not Enough Nico points...");
        }
        Ref();

        if (Upgrade == 5)
        {
            MessageBox.Show("Beginner: Reach 5 PPS.\nReward: AutoClick!", "ACHIEVEMENT UNLOCKED!");
            ach_beginner = 1;
            timer1.Enabled = true;
            Upgradeautoclick = 1;
            button4.Visible = true;
            Ref();
        }
    }

    Form2 achievements = new Form2();

    private void button3_Click(object sender, EventArgs e)
    {
        Form2.Show();            
    }

    private void button4_Click(object sender, EventArgs e)
    {
        if (Points >= Upgradeautoclickprice)
        timer1.Interval = timer1.Interval / 2;
        Points -= Upgradeautoclickprice;
        Upgradeautoclickprice += Upgradeautoclickprice;
    }

并且在form2中我希望:

    if (ach_beginner = 1) 
    {
        //Text in this label = something like: Beginner - Reach 5 Points per click
        labelwithachievement.Visible = true;
    }

ach_beginner未在form2中声明。我想以某种方式" connect"这个整数来自form1form2的声明。

2 个答案:

答案 0 :(得分:1)

您只需要一个参数。您调用Form2.Show方法。与任何其他方法一样,Form2的方法可以成为参数。因此,在Form2中,您可以执行以下操作:

public void Show(int ach_beginner)
{       
   //Do sth. with your int

   this.Show();
}

如果您现在在Form1上调用Form2,则可以传递整数:

private void button3_Click(object sender, EventArgs e)
{
   Form2.Show(ach_beginner);            
}

我认为这是最简单的方法。您可以创建属性,而不是覆盖Show Method。在Form2声明:

public int AchBeginner {get;set;}

在Form1中,在调用Show Method之前设置此值:

private void button3_Click(object sender, EventArgs e)
{
   Form2.AchBeginner = ach_beginner;
   Form2.Show();            
}

正如大卫在评论中所解释的那样,价值不会在Form2上更新。如果要实现此目的,可以使用界面:

public interface IBeginner
{
   int AchBeginner{get;set;}
}

public void Form1 : Form, IBeginner
{
   public int AchBeginner{get;set;}

   //The place you create Form2
   Form2.Beginner = this;
}

public void Form2 : Form
{
   public IBeginner Beginner{get;set;}

   //Here you can access
   int achBeginner = Beginner.AchBeginner:
}

<强>更新

基于问题作者的评论,我认为一个事件将是最有用的思考。因此,您可以告诉您的Form2您的Form1上的角色达到5级。例如:

public class LevelEventArgs : EventArgs
{
   public int Level {get;}

   public LevelEventArgs(int level)
   {
      Level = level;
   }
}

//Form1 need to implement an Event which later can notify any subscriber (Form2 in this case)
public class Form1 : Form
{
   public event EventHandler<LevelEventArgs> LevelUp;

   //When your character reach new level do following:
   LevelUp?.Invoke(this, new LevelEventArgs(ach_beginner));

   //Show Form2
   Form2 form = new Form2(this);
   form.Show();
}

Form2现在需要订阅此活动。为此,您需要将Form1放入Form2(或更好的接口,如上所述)

public class Form2 : Form
{
   public Form2(Form form1)
   {
       //Register Event LevelUp from Form1
       form1.LevelUp += (args) => 
       {
          if (args.Level == 5)
          //Level 5 reached
       }
   }
}

答案 1 :(得分:1)

不要将其视为共享整数本身,而是将其视为Form2依赖于Form1中的某些内容。

由于变量当前是 public (我们将在一分钟内完成),最简单的方法就是为Form2提供对实例的引用Form1。在Form2上放置一个属性,并在其构造函数中需要一个值:

private Form1 form1Instance;

public Form2(Form1 form1)
{
    this.form1Instance = form1;
}

然后,当您创建Form2的实例时,将其传递给Form1的当前实例:

Form2 achievements = new Form2(this);

然后在Form2中,您可以引用其新的成员变量来获取Form1的信息:

if (this.form1Instance.ach_beginner == 1)

关于公共变量的注意事项......通常认为最佳做法是公开公开属性而不是变量。所以替换这个:

public int ach_beginner = 0;

用这个:

public int Ach_Beginner { get; set; }

并相应地更新对它的引用。这有多种原因,但最终的想法是,一个类应该隐藏它的值并提供对它们的访问,而不是仅仅提供它们自己的值。

这是为对象提供依赖关系的一个非常简单的开始,你可以从这里找到许多地方。例如,如果您不希望将整个表单作为依赖项传递(因为它们包含的内容比依赖项所需的数据/功能要多得多),您可以将值封装在自己的对象中并传递给那个对象作为依赖。

从那里推断,您可以继续将业务逻辑与UI元素(如表单和控件)分开,并开始将逻辑移动到那些业务逻辑对象和组件中。这将使您的逻辑更易于移植到其他UI平台上,更易于测试等。

例如,假设您有一个类,如:

public class LevelInfo // guessing on an appropriate name here
{
    public int Ach_Beginner { get; set; }
    public int Ach_Intermediate { get; set; }
    public int Ach_Expert { get; set; }
    public int Ach_Master { get; set; }
}

然后在Form1中使用该对象:

private LevelInfo levelInfo = new LevelInfo();

// elsewhere...

levelInfo.Ach_Beginner = 1;
// etc.

然后Form2可能需要引用 对象:

private LevelInfo levelInfo;

public Form2(LevelInfo level)
{
    this.levelInfo = level;
}

并使用该对象:

if (this.levelInfo.Ach_Beginner == 1)

此时LevelInfo从UI解除耦合,可以包含可移植的业务逻辑/信息。