简体   繁体   中英

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). 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 . I then call the saveAddDelete.cs class in Form1.cs under the designated button click events. 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. 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:

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

and in each event handler pass 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.

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. 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. You wind up with 2 different Form1's, neither of which know anything about the other one.

If you want to do it this way, you will need to pass a reference to the existing Form1 to the SaveAddDelete class:

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:

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." In this case, "this" refers to your existing Form1 object. In the bottom sample, notice that the save method expects a Form1 object named "f" as a parameter. It does not create a new Form1 - it uses the one you pass to it.

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. 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.)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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