user10904507
user10904507

Reputation:

Winforms: Boolean logic not working properly

My situation is that I have Form 1 and Form 2. In Form 1 I have button1 and button2. I define a bool dtgmb to be false throughout Form1. However, if button2 is clicked then, dtgmb is true.

In Form 2 I have 1 DTG and button3 where all the data of the rows have been defined. Therefore, I run the instance whereby if dtgmb is false (button 1 is clicked), then display content of object[] rows and if dtgmb is true (button2 is clicked), then display content of object[] rows1 instead. Then button3 will be clicked to return to Form1.

However, if I click button1 first, then subsequently return to Form 1 and click button2, Form2 will show display content of object[] rows for both times. Then if I close the app and restart again and this time I click button2 first, then subsequently return to Form 1 and click button1, Form2 will show display content of object[] rows1 for both times.

Below is my code:

Form 1

public bool dtgmb = false;

private void button1_Click(object sender, EventArgs e)
{
    //Forms saved in class called FormsCollection
    FormsCollection.Form1.Hide();
    FormsCollection.Form2.Show();
}

private void button2_Click(object sender, EventArgs e)
{
    FormsCollection.Form1.Hide();
    dtgmb = true;
    FormsCollection.Form2.Show();
}

Form 2

private void Form2_Load(object sender, EventArgs e)
 {
   stuff(FormsCollection.Form1);
 }   

public void stuff(Form1 form)
{
    DataGridViewCheckBoxColumn check = new DataGridViewCheckBoxColumn();
    DataGridViewCheckBoxColumn check1 = new DataGridViewCheckBoxColumn();
    dataGridView4.ColumnCount = 1;
    dataGridView4.Columns[0].Width = 380;
    dataGridView4.Columns[0].Name = "Item";
    string[] row1 = new string[] { "Tables" };
    string[] row2 = new string[] { "Chairs" };
    string[] row3 = new string[] { "Lamps" };
    string[] row4 = new string[] { "Pillows" };
    string[] row5 = new string[] { "Blankets" };
    object[] rows = new object[] { row1, row2, row3, row4, row5 };
    object[] rows1 = new object[] { row1, row2, row3, row4 };

    if (form.dtgmb == false)
        foreach (string[] rowArray in rows)
        {
            this.dataGridView4.Rows.Add(rowArray);
        }
    else
        foreach (string[] rowArray in rows1)
        {
            this.dataGridView4.Rows.Add(rowArray);
        }

    check.HeaderText = "Pass";
    check1.HeaderText = "Fail";
    dataGridView4.Columns.Add(check);
    dataGridView4.Columns.Add(check1);
}

Upvotes: 0

Views: 85

Answers (1)

Yennefer
Yennefer

Reputation: 6224

The issue is due to dtgmb being marked as static. This means that all the instances regardless they life span will share the same value. Static variables are initialized when the application starts to their native default values (e.g. integers are initialized to zero, while booleans to false).

If you remove the static modifier, you will need to invoke the stuff method with a reference to a form. Since you are not showing us where you call stuff, I post here the refactor of what you posted.

Form1.cs:

public bool dtgmb = false;

private void button1_Click(object sender, EventArgs e)
{
    //Forms saved in class called FormsCollection
    FormsCollection.Form1.Hide();
    FormsCollection.Form2.Show();
}

private void button2_Click(object sender, EventArgs e)
{
    FormsCollection.Form1.Hide();
    dtgmb = true;
    FormsCollection.Form2.Show();
}

and Form2.cs

public void stuff(Form1 form)
{
    DataGridViewCheckBoxColumn check = new DataGridViewCheckBoxColumn();
    DataGridViewCheckBoxColumn check1 = new DataGridViewCheckBoxColumn();
    dataGridView4.ColumnCount = 1;
    dataGridView4.Columns[0].Width = 380;
    dataGridView4.Columns[0].Name = "Item";
    string[] row1 = new string[] { "Tables" };
    string[] row2 = new string[] { "Chairs" };
    string[] row3 = new string[] { "Lamps" };
    string[] row4 = new string[] { "Pillows" };
    string[] row5 = new string[] { "Blankets" };
    object[] rows = new object[] { row1, row2, row3, row4, row5 };
    object[] rows1 = new object[] { row1, row2, row3, row4 };

    if (form.dtgmb == false)
        foreach (string[] rowArray in rows)
        {
            this.dataGridView4.Rows.Add(rowArray);
        }
    else
        foreach (string[] rowArray in rows1)
        {
            this.dataGridView4.Rows.Add(rowArray);
        }

    check.HeaderText = "Pass";
    check1.HeaderText = "Fail";
    dataGridView4.Columns.Add(check);
    dataGridView4.Columns.Add(check1);
}

Keep in mind that sharing fields directly is not a good practice, but this is good to understand where the problem lies.

EDIT following the comments

It is unclear to me what you are trying to achieve. Your code does not work as you are trying to pass a type as a formal argument of a function. I refactored your code in order to compile (but I do not understand how it should behave):

Program.cs

    static void Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        new Form1().Show();
        Application.Run(new Form2());
    }

Form1.cs

public partial class Form1 : Form
{
    public bool dtgmb = false;

    public Form1()
    {
        InitializeComponent();

        FormCollection.Form1 = this;
    }


    private void button1_Click(object sender, EventArgs e)
    {
        //Forms saved in class called FormsCollection
        FormCollection.Form1.Hide();
        FormCollection.Form2.Show();
    }

    private void button2_Click(object sender, EventArgs e)
    {
        FormCollection.Form1.Hide();
        dtgmb = true;
        FormCollection.Form2.Show();
    }

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

    private void Form1_FormClosed(object sender, FormClosedEventArgs e)
    {
        FormCollection.Form1 = null;
    }
}

public static class FormCollection
{
    public static Form1 Form1;
    public static Form2 Form2;

}

Form2.cs

public partial class Form2 : Form
{
    public Form2()
    {
        InitializeComponent();

        FormCollection.Form2 = this;
    }

    private void Form2_Load(object sender, EventArgs e)
    {
        stuff(FormCollection.Form1);
    }

    public void stuff(Form1 form)
    {
        DataGridViewCheckBoxColumn check = new DataGridViewCheckBoxColumn();
        DataGridViewCheckBoxColumn check1 = new DataGridViewCheckBoxColumn();
        dataGridView4.ColumnCount = 1;
        dataGridView4.Columns[0].Width = 380;
        dataGridView4.Columns[0].Name = "Item";
        string[] row1 = new string[] { "Tables" };
        string[] row2 = new string[] { "Chairs" };
        string[] row3 = new string[] { "Lamps" };
        string[] row4 = new string[] { "Pillows" };
        string[] row5 = new string[] { "Blankets" };
        object[] rows = new object[] { row1, row2, row3, row4, row5 };
        object[] rows1 = new object[] { row1, row2, row3, row4 };

        if (form.dtgmb == false)
            foreach (string[] rowArray in rows)
            {
                this.dataGridView4.Rows.Add(rowArray);
            }
        else
            foreach (string[] rowArray in rows1)
            {
                this.dataGridView4.Rows.Add(rowArray);
            }

        check.HeaderText = "Pass";
        check1.HeaderText = "Fail";
        dataGridView4.Columns.Add(check);
        dataGridView4.Columns.Add(check1);
    }

    private void Form2_FormClosed(object sender, FormClosedEventArgs e)
    {
        FormCollection.Form2 = null;
    }
}

Please note that the code above has several issues: one for all it relies upon how forms are initialized.

Upvotes: 0

Related Questions