You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C# WinForms中Form2无法获取Form1填充的Spelers列表问题求助

问题:Form2中无法获取Form1填充的Spelers列表内容

我是编程新手(刚学完通用编程逻辑课程),正在用C# WinForms开发猜词游戏,Form1负责游戏设置(玩家数量、命名),用Spelers类实现面向对象,但Form2里访问Form1填充的Spelers列表时为空。

操作流程

  • 默认加载Form1,输入玩家数量并命名,通过Spelers类方法将玩家添加到列表;
  • 完成命名后关闭Form1并打开Form2(通过布尔开关在Program.cs中执行Application.Run(form2)保证程序运行);
  • 在Form2中创建新的Spelers对象获取列表,但列表完全为空。

相关代码

Form1代码

using System;
using System.Security.Cryptography.X509Certificates;
using System.Windows.Forms;

namespace Pictionary
{
    public partial class Form1 : Form
    {
        public bool Form2Loaded { get; set; }
        private int aantalKliks = 0;
        private int aantalSpelers = 0;

        public Spelers speler1 = new Spelers();
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }

        private void pictionaryTitle_Click(object sender, EventArgs e)
        {
            
        }

        private void buttonSpelregels_Click(object sender, EventArgs e)
        {
            MessageBox.Show(
                $"1 - Kies of iedereen voor zichzelf speelt of in teams.{Environment.NewLine}2 - Geef de namen van de spelers in of een team naam per team.{Environment.NewLine}3 - Er word een speler of team gekozen om het woord uit te beelden. Druk op de knop om het woord zichtbaar/onzichtbaar te maken. Druk op de start knop om de ronde te beginnen.{Environment.NewLine}4 - De andere spelers/team hebben 60 seconden de tijd om het woord te raden. Kies de juist optie om de punten toe te voegen.{Environment.NewLine}5 - Druk op de knop stop spel om het spel te stoppen en de punten te laten zien.",
                "Spelregels");
        }

        private void buttonFreeforall_Click(object sender, EventArgs e)
        {
            flowLayoutPanel1.Show();
            buttonBack.Show();
            buttonTeams.Hide();
            buttonFreeforall.Hide();
            buttonSpelregels.Hide();
        }

        private void buttonBack_Click(object sender, EventArgs e)
        {
            flowLayoutPanel1.Hide();
            buttonBack.Hide();
            buttonTeams.Show();
            buttonFreeforall.Show();
            buttonSpelregels.Show();
            radioButton2.Checked = false;
            radioButton3.Checked = false;
            radioButton4.Checked = false;
            radioButton5.Checked = false;

        }

        private void radioButton2_CheckedChanged(object sender, EventArgs e)
        {
            flowLayoutPanel1.Hide();
            buttonBack.Hide();
            textBox1.Show();
            buttonAddName.Show();
            aantalSpelers = 2;
        }


        private void radioButton3_CheckedChanged(object sender, EventArgs e)
        {
            flowLayoutPanel1.Hide();
            buttonBack.Hide();
            textBox1.Show();
            buttonAddName.Show();
            aantalSpelers = 3;
        }

        private void radioButton4_CheckedChanged(object sender, EventArgs e)
        {
            flowLayoutPanel1.Hide();
            buttonBack.Hide();
            textBox1.Show();
            buttonAddName.Show();
            aantalSpelers = 4;
        }

        private void radioButton5_CheckedChanged(object sender, EventArgs e)
        {
            flowLayoutPanel1.Hide();
            buttonBack.Hide();
            textBox1.Show();
            buttonAddName.Show();
            aantalSpelers = 5;
        }

        private void buttonAddName_Click(object sender, EventArgs e)
        {
            if (textBox1.Text == "" || textBox1.Text == "Speler Toegevoegd!")
            {
                MessageBox.Show("Naam mag niet blanco zijn!");
            }

            else
            {
                switch (aantalKliks)
                {
                    case 0:
                        speler1.naamSpeler = textBox1.Text;
                        speler1.SpelerNaarLijst();
                        break;

                    case 1:
                        speler1.naamSpeler = textBox1.Text;
                        speler1.SpelerNaarLijst();
                        break;

                    case 2:
                        speler1.naamSpeler = textBox1.Text;
                        speler1.SpelerNaarLijst();
                        break;

                    case 3:
                        speler1.naamSpeler = textBox1.Text;
                        speler1.SpelerNaarLijst();
                        break;

                    case 4:
                        speler1.naamSpeler = textBox1.Text;
                        speler1.SpelerNaarLijst();
                        break;

                }

                textBox1.Text = "Speler Toegevoegd!";

                aantalKliks = aantalKliks + 1;
            }
            if (aantalKliks == aantalSpelers)
            {
                this.Close();
                Form2Loaded = true;

            }
        }
    }
}

Form2代码

using System;
using System.Collections.Generic;
using System.Windows.Forms;

namespace Pictionary
{
public partial class Form2 : Form

#region generatedCode

{
    public Spelers speler1 = new Spelers();

    public Form2()
    {
        InitializeComponent();
    }

    private void Form2_Load(object sender, EventArgs e)
    {
     
    }


    private bool buttonSwitch = false;

    private void buttonToggleWord_Click(object sender, EventArgs e)
    {
        buttonSwitch = !buttonSwitch;

        if (buttonSwitch == true)
        {
            labelWoord.Text = "Woord: test";

        }

        else
        {
            labelWoord.Text = "Woord: ";
        }
    }

}
#endregion

Spelers类代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Pictionary
{
public class Spelers
{
    //Attributes
    public string naamSpeler;
    public List<string> spelerLijst = new List<string>();


    //constructors

    //methods
    public void SpelerNaarLijst()
    {
        spelerLijst.Add(naamSpeler);
    }

}

问题原因

核心问题是你在Form1和Form2中分别创建了独立的Spelers实例。这两个实例是完全不同的对象,各自拥有独立的spelerLijst列表:

  • Form1里填充的是Form1内部speler1实例的列表;
  • Form2里新建的speler1是一个全新的、未填充数据的实例,所以列表为空。

解决方案

方案1:通过构造函数传递Spelers实例

这种方式适合仅在Form1和Form2之间传递数据的场景,逻辑清晰:

  1. 修改Form2的构造函数,接收Spelers实例作为参数:
public partial class Form2 : Form
{
    private Spelers _spelers;

    // 修改构造函数,接收外部传入的Spelers实例
    public Form2(Spelers spelers)
    {
        InitializeComponent();
        _spelers = spelers;
    }

    // 可以在Form2_Load中测试数据是否传递成功
    private void Form2_Load(object sender, EventArgs e)
    {
        MessageBox.Show($"已添加玩家数量:{_spelers.spelerLijst.Count}");
    }

    // 原有代码保持不变...
}
  1. 修改Form1中启动Form2的逻辑,直接传递已填充的Spelers实例:
    在Form1的buttonAddName_Click方法中,替换原有的关闭逻辑:
// 替换原来的 this.Close(); Form2Loaded = true;
Form2 form2 = new Form2(speler1); // 把Form1的speler1实例传给Form2
form2.Show();
this.Hide(); // 隐藏Form1而非直接关闭,避免程序退出
  1. 调整Program.cs的启动逻辑,默认启动Form1即可:
static void Main()
{
    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);
    Application.Run(new Form1());
}

方案2:将Spelers设计为单例类

如果需要在整个程序的多个页面共享玩家数据,可以把Spelers改成单例模式,确保全局只有一个实例:

  1. 修改Spelers类为单例:
public class Spelers
{
    // 静态字段存储唯一实例
    private static Spelers _instance;
    // 私有构造函数,禁止外部创建新实例
    private Spelers() {}

    // 公共属性获取唯一实例
    public static Spelers Instance
    {
        get
        {
            if (_instance == null)
            {
                _instance = new Spelers();
            }
            return _instance;
        }
    }

    public string naamSpeler;
    public List<string> spelerLijst = new List<string>();

    public void SpelerNaarLijst()
    {
        spelerLijst.Add(naamSpeler);
    }
}
  1. 在Form1中使用单例实例:
    替换Form1中的public Spelers speler1 = new Spelers();,直接通过Spelers.Instance操作:
// 在buttonAddName_Click的switch分支中
Spelers.Instance.naamSpeler = textBox1.Text;
Spelers.Instance.SpelerNaarLijst();
  1. 在Form2中使用同一个单例实例:
    替换Form2中的public Spelers speler1 = new Spelers();,直接访问Spelers.Instance:
private void Form2_Load(object sender, EventArgs e)
{
    MessageBox.Show($"已添加玩家数量:{Spelers.Instance.spelerLijst.Count}");
}

额外优化建议

  • Spelers类的命名建议改为SpelerManager或PlayerCollection,更符合其管理玩家列表的语义;
  • 避免使用公共字段(如naamSpeler、spelerLijst),改成封装后的属性,防止外部误操作数据:
public class Spelers
{
    private List<string> _spelerLijst = new List<string>();
    // 只读属性,外部只能读取列表不能直接修改
    public List<string> SpelerLijst => _spelerLijst;

    // 封装添加玩家的方法,做参数校验
    public void AddSpeler(string naam)
    {
        if (!string.IsNullOrWhiteSpace(naam))
        {
            _spelerLijst.Add(naam);
        }
    }
}

内容的提问来源于stack exchange,提问作者Excynic

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 23:40:19