Pucho Pucho - 18 days ago 9
C# Question

C# Exception error when changing datagridview font size using another form

I have two forms, one contains the datagridview and the other one contains a trackbar to change the font size of the datagridview like this:
enter image description here

I created the following code to allow Form2 to access Form1 datagridview:

//This is for Form1, the one that contains the datagridview:
public partial class Form1: Form
{
public Form1()
{
Form2 f = new Form2();
f.dataGridFromForm1 = dataGridView1;
}

//This is for Form2, the one that contains the trackbar:
public partial class Form2: Form
{
public DataGridView dataGridFromForm1 { get; set;}
private void trackBar1_Scroll(object sender, EventArgs e)
{
dataGridFromForm1.RowsDefaultCellStyle.Font =
new Font(dataGridFromForm1.RowsDefaultCellStyle.Font.FontFamily,
float.Parse(trackBar1.Value.ToString()));
label1.Text = trackBar1.Value.ToString() + "pt";
}
}


During the build I do not get any errors, however when I try to slide the trackbar I get the following exception:
enter image description here

I'm not exactly sure what I'm missing out here as I thought I had already instantiated the datagridview. Any help would be appreciated.

Answer

This is because you are creating a new Form2 and then discarding it. In other words, your constructor for Form1 does this:

public Form1()
{
    Form2 f = new Form2();   // creates a new Form2
    f.dataGridFromForm1 = dataGridView1; // sets the property
    // f is now out of scope
}

Your f is a local variable inside the constructor. When you are showing the form later (presumably by calling Form2 f = new Form2(); again followed by f.Show()) it has no idea what the dataGridFromForm1 is (in fact its null by default).

You haven't shown enough code (your method to show the slider form is missing), but that code should probably set the slider. Perhaps something like:

private void btnShowSlider_Click(object sender, EventArgs e)
{
      using (var f = new Form2()) {
         f.dataGridFromForm1 = this.dataGridView1;
         f.ShowDialog(this);
      }
}

Note that in the above, the slider form will be a modal window and you won't be able to click back to it until you've closed it (which is probably a good thing)

Outside of that you could have a class instance variable inside Form1 that keeps track of your Form2 form showing/hiding/disposing of it as necessary. Another option would be to pass an instance of Form1 into the constructor for Form2, so it has a reference directly. That could look like this:

public partial class Form2 : Form {
    private Form1 _form1;
    public Form2(Form1 otherForm) {
          _form1 = otherForm;
    } 
    private void trackBar1_Scroll(object sender, EventArgs e)
    {
        _form1.dataGridFromForm1.RowsDefaultCellStyle.Font =
        new Font(form1.dataGridFromForm1.RowsDefaultCellStyle.Font.FontFamily, 
        trackBar1.Value);
        label1.Text = trackBar1.Value + "pt";
    }
}

and creating it in Form1 like:

 Form2 f = new Form2(this);
 f.Show();

making sure to dispose/etc when you are done.

Also note that TrackBar.Value is already an int and so you shouldn't need to convert it to a string and parse it again. Something like this should suffice:

new Font(..., trackBar1.Value)
Comments