简体   繁体   English

通过使用类,按钮在Windows Forms C#中不起作用

[英]Buttons don't work in Windows Forms C# by using classes

So, I'm currently working on a game library app, where you can add and organize games that are a part of your game library. 因此,我目前正在开发一个游戏库应用,您可以在其中添加和组织属于游戏库的游戏。 So far I have three textboxes (one for game title, developer, and publisher), one checklistbox (to select which platform or system the game is on), three buttons ("Save Changes", "Add", and "Delete"), and finally a listview where the title of the game will be displayed whenever the user enters in the information and clicks the "Add" button. 到目前为止,我有三个文本框(一个用于游戏标题,开发者和发行者),一个复选框(用于选择游戏所在的平台或系统),三个按钮(“保存更改”,“添加”和“删除”) ,最后是一个列表视图,每当用户输入信息并单击“添加”按钮时,游戏标题就会显示在该列表视图中。 I was able to get it to work with no problems using the Form1.cs class, but figured it'd be best to organize the code using classes, which I've NEVER done with Windows Forms before (so I'm kinda a noob at this). 我可以使用Form1.cs类使它正常工作,但认为最好使用类来组织代码,而我以前从未使用过Windows Forms来做到这一点(所以我有点菜鸟在这)。 For consistency reasons for this post, I made a saveAddDelete.cs class that has all my code for the "Save", "Add", and "Delete" buttons, which I transferred over from Form1.cs . 出于一致性原因,我制作了一个saveAddDelete.cs类,其中包含我的所有“保存”,“添加”和“删除”按钮代码,这些代码是我从Form1.cs转移过来的。 I then call the saveAddDelete.cs class in Form1.cs under the designated button click events. 然后,在指定的按钮单击事件下,在Form1.cs调用saveAddDelete.cs类。 There are no errors, but when I run the program, I enter in the information and click on the buttons, but they do nothing. 没有错误,但是当我运行该程序时,我输入了信息并单击了按钮,但是它们什么也不做。 So I think I'm either missing code or misunderstanding how classes work in Windows Forms. 因此,我想我要么缺少代码,要么误解类在Windows窗体中的工作方式。 Here's the code below, and if anyone has any helpful feedback that would help me, I'd greatly appreciate it. 这是下面的代码,如果有人有任何有用的反馈对我有帮助,我将不胜感激。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace GameLibrary
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        public List<Library> Game = new List<Library>();
        public Library lib = new Library();

        public void saveBttn_Click(object sender, EventArgs e)
        {
            saveAddDelete save = new saveAddDelete();
            save.Save();
        }

        private void button1_Click(object sender, EventArgs e)//Add Button
        {
            saveAddDelete add = new saveAddDelete();
            add.Add();
        }

        private void deleteBtnClick_Click(object sender, EventArgs e)
        {
            saveAddDelete delete = new saveAddDelete();
            delete.Delete();
        }

    public class Library
        {
            public string gametitle
            {
                get;
                set;
            }
            public string developer
            {
                get;
                set;
            }
            public string publisher
            {
                get;
                set;
            }
            public string platform
            {
                get;
                set;
            }
        }

class saveAddDelete
    {
        Form1 f = new Form1();
        public void Save()
        {
            if(f.gameList.SelectedItems.Count == 1)
            {
                f.Game[f.gameList.SelectedItems[0].Index].gametitle = f.titleText.Text;
                f.Game[f.gameList.SelectedItems[0].Index].developer = f.developerText.Text;
                f.Game[f.gameList.SelectedItems[0].Index].publisher = f.publisherText.Text;
                f.Game[f.gameList.SelectedItems[0].Index].platform = f.platformCheckBox.CheckedItems.ToString();
            }
        }

        public void Add()
        {
            f.lib.gametitle = f.titleText.Text;
            f.lib.developer = f.developerText.Text;
            f.lib.publisher = f.publisherText.Text;
            f.lib.platform = f.platformCheckBox.CheckedItems.ToString();
            f.Game.Add(f.lib);
            f.gameList.Items.Add(f.lib.gametitle);
            f.titleText.Clear();
            f.developerText.Clear();
            f.publisherText.Clear();
            foreach(int i in f.platformCheckBox.CheckedIndices)
            {
                f.platformCheckBox.SetItemCheckState(i, CheckState.Unchecked);
            }
        }

        public void Delete()
        {
            Remove();
            f.titleText.Clear();
            f.developerText.Clear();
            f.publisherText.Clear();
            foreach (int i in f.platformCheckBox.CheckedIndices)
            {
                f.platformCheckBox.SetItemCheckState(i, CheckState.Unchecked);
            }
        }

        void Remove()
        {
            try
            {
                f.gameList.Items.Remove(f.gameList.SelectedItems[0]);
                f.Game.RemoveAt(f.gameList.SelectedItems[0].Index);
            }
            catch { }
        }
    }

Your helper class does not have reference to real form clicks are performed on (and hence do not get any values from the form). 您的帮助程序类没有引用实际执行的表单单击(因此不会从表单中获取任何值)。

One option - pass Form1 to each call instead of new'ing up Form1 in saveAndDelete class: 一个选项-将Form1传递给每个调用,而不是在saveAndDelete类中saveAndDelete Form1

 class saveAddDelete 
 {
   // Form1 f = new Form1(); - delete that line
   public void Save(Form1 f) {....} // pass Form1

and in each event handler pass this : 并在每个事件处理程序中传递this

    public void saveBttn_Click(object sender, EventArgs e)
    {
        saveAddDelete save = new saveAddDelete(this);
        save.Save();
    }

Note that you may consider using static methods for Save depending on your goals. 请注意,您可以根据自己的目标考虑使用static方法进行Save

In your Form1 code, you create a new child object of type SaveAddDelete, but when you use the methods you created, you aren't passing any data into them. 在您的Form1代码中,您将创建一个类型为SaveAddDelete的新子对象,但是当您使用所创建的方法时,您不会将任何数据传递给它们。 Instead, you are creating a new (empty) instance of Form1, which doesn't have any data to save or delete, and if you make any modifications to that new Form1, the original version of Form1 is not able to see those changes. 而是,您正在创建一个新的(空)Form1实例,该实例没有要保存或删除的任何数据,并且,如果您对该新Form1进行了任何修改,则Form1的原始版本将看不到那些更改。 You wind up with 2 different Form1's, neither of which know anything about the other one. 您将获得2个不同的Form1,但它们都不了解另一个。

If you want to do it this way, you will need to pass a reference to the existing Form1 to the SaveAddDelete class: 如果您想通过这种方式进行操作,则需要将对现有Form1的引用传递给SaveAddDelete类:

public void saveBttn_Click(object sender, EventArgs e)
{
    saveAddDelete save = new saveAddDelete();
    save.Save(this);
}

and your SaveAddDelete methods will have to be expecting to receive an object of type Form1: 并且您的SaveAddDelete方法将必须期望接收Form1类型的对象:

public void Save(Form1 f)
{
    if(f.gameList.SelectedItems.Count == 1)
    {
        f.Game[f.gameList.SelectedItems[0].Index].gametitle = f.titleText.Text;
        f.Game[f.gameList.SelectedItems[0].Index].developer = f.developerText.Text;
        f.Game[f.gameList.SelectedItems[0].Index].publisher = f.publisherText.Text;
        f.Game[f.gameList.SelectedItems[0].Index].platform = f.platformCheckBox.CheckedItems.ToString();
    }
}

Notice that in the top sample, I pass "this" to the method, which is C# code for "whatever class is calling the code." 请注意,在最上面的示例中,我将“ this”传递给该方法,该方法是“无论什么类都在调用该代码”的C#代码。 In this case, "this" refers to your existing Form1 object. 在这种情况下,“ this”是指您现有的Form1对象。 In the bottom sample, notice that the save method expects a Form1 object named "f" as a parameter. 在底部的示例中,请注意save方法将一个名为“ f”的Form1对象作为参数。 It does not create a new Form1 - it uses the one you pass to it. 它不会创建新的Form1-它使用传递给它的表单。

For this example, I would actually just leave all of those methods in your Form1 class, since they are all related to the controls in Form1. 对于此示例,我实际上只是将所有这些方法留在Form1类中,因为它们都与Form1中的控件相关。 New classes are generally used to model real-world objects - not to break out various pieces of code related to an existing class. 新类通常用于对现实世界的对象进行建模-不会破坏与现有类相关的各种代码。 Your "Library" class is a correct use of a separate class, since each instance of it represents a different game, and you have more than one of them that you need to keep track of separately (although I would call the class "Game" instead of "Library", since each instance of the class represents a single game, whereas the word library implies a collection of games.) 您的“库”类是对单独类的正确使用,因为它的每个实例代表一个不同的游戏,并且您需要单独跟踪多个类(尽管我将类称为“游戏”而不是“库”,因为该类的每个实例代表一个游戏,而词库则表示游戏的集合。)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM