从其他类操作表单控件属性?

时间:2015-02-20 00:27:17

标签: c#

我正在尝试通过我的一个类来操作主窗体中控件的属性。

基本上我正在尝试更新标签,我已将其设置为公开,如下所示:

public Label DicerollLabel;

我在课堂上提到我的主要表格:

 private Form1 _mainForm;

当我尝试访问标签并为其设置值时:

_mainForm.DicerollLabel.Text = "Hello World!";

我收到以下错误: 发生了'System.NullReferenceException'类型的未处理异常。

我对调用的两个文件的完整代码如下:

主要表格:

namespace BettingGame
{
    public partial class Form1 : Form
    {
        private Player _playerOne;
        private Player _playerTwo;
        private DiceRoller _diceRoller;
        private decimal _prizePool;
        private Random _random;

        public int ProgressBar
        {
            get {return progressBar1.Value;}
            set { progressBar1.Value = value; }
        }

        public Label DicerollLabel;

        public Form1()
        {
            InitializeComponent();
            _playerOne = new Player() {PlayerName = "x", PlayerFunds = 100};
            _playerTwo = new Player() {PlayerName = "x", PlayerFunds = 100};
            _diceRoller = new DiceRoller();
            _random = new Random();

            playerOneFundsLabel.Text = "Funds: " + _playerOne.PlayerFunds.ToString(CultureInfo.CurrentCulture) + "$";
            playerTwoFundsLabel.Text = "Funds: " + _playerTwo.PlayerFunds.ToString(CultureInfo.CurrentCulture) + "$";
            PrizeAmountLabel.Text = "";
            diceRollLabel.Text = "";
        }

        private void button1_Click(object sender, EventArgs e)
        {
            _playerOne.PlayerBetAmount = (decimal) playerOneBet.Value;
            _playerTwo.PlayerBetAmount = (decimal) playerTwoBet.Value;

            if (!(_playerOne.PlayerBetAmount <= 0) || !(_playerTwo.PlayerBetAmount <= 0) 
                && (_playerOne.PlayerBetAmount > 0) && (_playerTwo.PlayerBetAmount > 0))
            {
                _prizePool = _playerOne.PlayerBet() + _playerTwo.PlayerBet();
                PrizeAmountLabel.Text = _prizePool.ToString(CultureInfo.CurrentCulture);
                FormUpdate();
            }
            else
            {
                MessageBox.Show("Invalid bets! Bet amount must be greater than 0!");
            }

        }

        private void FormUpdate()
        {
            playerOneFundsLabel.Text = "Funds: " + _playerOne.PlayerFunds.ToString(CultureInfo.CurrentCulture) + "$";
            playerTwoFundsLabel.Text = "Funds: " + _playerTwo.PlayerFunds.ToString(CultureInfo.CurrentCulture) + "$";
        }

        private void button2_Click(object sender, EventArgs e)
        {
            //for (int i = 0; i < 45; i++)
            //{
            //    int value = _random.Next(1, 50);
            //    diceRollLabel.Text = value.ToString();
            //    diceRollLabel.Update();
            //    Thread.Sleep(50);
            //}

            _diceRoller.RollDice();
        }
    }
}

和DiceRoller类:

    namespace BettingGame
{
    class DiceRoller
    {
        private Random _random = new Random();
        private Form1 _mainForm;

        public void RollDice()
        {
            _mainForm.DicerollLabel.Text = "Hello World!";
        }
    }

我做错了什么?请注意,我只是在编程的第二周,所以我还在学习!

2 个答案:

答案 0 :(得分:1)

更改您的DiceRoller类以定义以下构造函数:

public DiceRoller(Form1 host) {
  _mainForm = host;
}

然后在Form1中创建DiceRoller实例:

private DiceRoller _diceRoller = new DiceRoller(this);

这是一个非常可怕的长期设计。这绝对是我对新程序员所期望的代码 - 所以不要感觉不好。你做得很好。

将来尝试考虑可重用性。通过使DiceRoller依赖于Form1(以及Form1中的特定控件),您将面临以下两个挑战: 1.您无法在未经修改的情况下在其他项目中(或甚至可能在同一项目中)使用DiceRoller。 2.如果您更改DiceRoller所依赖的任何控件,您还必须更改DiceRoller。

我会让你考虑如何避免这些问题。我敢肯定,如果你需要帮助,你会发布另一个问题。 :)

答案 1 :(得分:1)

您需要引用已创建的Form1。这不是Form1,但是在Form1中你可以使用关键字“this”来引用它,你可以将它传递给DiceRoller类的构造函数。

class DiceRoller
{
    private Random _random = new Random();
    private Form1 _mainForm;

    public DiceRoller(Form1 f)
    {
        _mainForm = f;
    }

    public void RollDice()
    {
        _mainForm.DicerollLabel.Text = "Hello World!";
    }
}

然后在Form1的构造函数中调用它:

    public Form1()
    {
        InitializeComponent();
        _playerOne = new Player() {PlayerName = "x", PlayerFunds = 100};
        _playerTwo = new Player() {PlayerName = "x", PlayerFunds = 100};
        _diceRoller = new DiceRoller(this);
    ....

这些是使代码工作所需的最小更改。但是,您可以考虑其他更改,例如传入标签而不是表单。