C#/Visual Studio/.NET

Accessing one form’s controls from another form

September 16th, 2007

Here's the situation:

In a .NET appication I have a form containing several controls (lets call this MainForm). I want to allow the user to change many of the properties of this form, such as the background colour, the labels, the font, etc. To do this I have a separate form (PropertiesForm). The question is, how do I access the properties of the MainForm controls from within PropertiesForm.

You might think that it was a simple case of making the MainForm class and/or the control objects declared within MainForm public rather than private. But this isn't enough. Instead you need to declare an internal (or public) variable whose type is the name of the class you want to access (in my case MainForm) and then when you open the new form from MainForm set that variable to the MainForm form. That sounds complicated, but it's easier to show it than to explain it in writing.

 

Here's part of the PropertiesForm code from a file called Form2.cs:

namespace MyCsharpProgram
{
      public partial class PropertiesForm : Form
      {
            //Declare a variable for the main form:

            internal MainForm ParentForm;

            ...      

            private void buttonUpdateForm_Click(object sender, EventArgs e)
            {
                  //Change the text of the exit button:

                  ParentForm.buttonExit.Text = sExitButtonText;

                  ...
            }

      }

}

In the above code, clicking the "buttonUpdateForm" button on the PropertiesForm form changes the text of a button called buttonExit on the parent form.

Here's part of the MainForm code from a file called Form1.cs

namespace MyCsharpProgram
{
      public partial class MainForm : Form
      {

            ...

            private void linkLabelProperties_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
            {
                  PropertiesForm PropertiesForm = new PropertiesForm();
                  PropertiesForm.ParentForm = this;
                  PropertiesForm.ShowDialog();
            }

            ...

      }

}

Here, in MainForm, I have an event handler for a link label called linkLabelProperties. When this link label is clicked we create a new instance of PropertiesForm and we set the object called ParentForm to this form (i.e. MainForm). We then display the form.

What we're doing here is passing a reference to the MainForm form into the PropertiesForm form, so that you can access MainForm objects from PropertiesForm.

The Form1.Designer.cs file contains the definition of the buttonExit button, which is declared as internal, rather than private, so that we can access it from another class:

namespace VocabBuilder
{
      public partial class VocabBuilderForm
      {

            ...

            internal System.Windows.Forms.Button buttonExit;
            ...

      }
}

I should add that if you're writing serious code this is not the correct way to do this. How you should do it is to use delegates. This makes the classes and methods much more independent and makes it much easier to maintain them in a large body of code, and to reuse classes in other programs.  

Leave a comment

 

Writing to a log file in C#

August 21st, 2007    1 Comment

Here's a chunk of code that will write values to a log file. If the file doesn't exist, it creates it, otherwise it just appends to the existing file. You need to add "using System.IO;" at the top of your code, if it's not already there.

string strLogText = "Some details you want to log.";

// Create a writer and open the file:
StreamWriter log;

if (!File.Exists("logfile.txt"))
{
  log = new StreamWriter("logfile.txt");
}
else
{
  log = File.AppendText("logfile.txt");
}

// Write to the file:
log.WriteLine(DateTime.Now);
log.WriteLine(strLogText);
log.WriteLine();

// Close the stream:
log.Close();

Leave a comment



Variable-length arrays in C#

August 19th, 2007    4 Comments

Because I'm most familiar with Perl programming, whenever it's been a while since I've done any C# coding I often spend time re-remembering how to do variable-length arrays. In C#, if you want to use an array you've got to say up front how many elements it's going to contain. If, later in the code, you try to assign it more items than you said it would contain, you get an error.

But often you don't know how many items an array is going to need. It may vary every time you run the program. In this situation, you need to use C#'s ArrayList type. To use this you need to add:

using System.Collections;

up top of your code. You can then create a new ArrayList instance like this:

private ArrayList ResultsArrayList = new ArrayList();

Notice, you didn't have to give an elements limit to the list.

You can then add stuff to the ArrayList:

ResultsArrayList.Add(ResultRecord);

In this example, from code I've just been writing, ResultRecord is actually an array of field values. So here I'm creating a list of results, each of which contains a set of result values. I use this to capture search results where I know there's a fixed set of result fields for each search result (so I can use a simple array for each hit), but I don't know how many hits are going to come back from the search (so I need to use an ArrayList for the results set).

In the following code, to output my ArrayList of Arrays to the console, I do a for loop through each item in the ArrayList and within that (for each individual search result) I do a foreach loop to print out each item (or field) of data for that hit:

for (int i=0; i < ResultsArrayList.Count; i++)
{
    Console.WriteLine("HIT {0}:", i);
    // Note: ResultsArrayList[i] needs to be cast as a string[] before it can be assigned:
    string[] newarray = (string[])ResultsArrayList[i];
    foreach (string str in newarray)
    {
        Console.WriteLine("ITEM: {0}", str);
    }
}

The trouble with C# is that it's really difficult to Google for it. Google for "C#" and you get any page containing "C"! I've I've really got to try and remember about ArrayLists for when I do more C# stuff in 6 months or a year, to save myself trawling through pages and pages of stuff on arrays - none of which start with a simple redirection like: "If you don't know how many elements your array is going to need, use an ArrayList rather than an array."

Leave a comment



Case-insensitive substring search (C#)

August 18th, 2007

Problem:

You want to do an IndexOf search to check whether searchString occurs in chunkOfText. You want the match to be case-insensitive, but you don't want to have to convert both stings to lower case or upper case before doing the comparison because it slows things down.

Answer (in .NET):

Use the CompareInfo class from System.Globalization.

How to do it:

Add using System.Globalization; at the top of your code.

Then you can do something like

int searchResultInt = CultureInfo.CurrentUICulture.CompareInfo.IndexOf(chunkOfText, searchString, CompareOptions.IgnoreCase);

Where chunkOfText is the string you want to search through and searchString is the string you're looking for - that is, the substring. As with a normal IndexOf, this returns -1 if there's no match, or the index of the first character if a match is found.

Leave a comment



Matching braces

February 26th, 2006

Quick note to myself, because I always forget how to do this in Visual Studio. To match a brace, place the cursor just before or after it and press Ctrl + ] To select a block marked by braces, place the cursor just before or after it and press Ctrl + } It would be nice if Visual Studio automatically highlighted the matching brace when you placed the cursor beside a brace - like UltraEdit does - but you have to remember the shortcut. Now to add this to my bookmarks on delicious...

Potentially similar posts

Comments are closed.



^ back to top ^

Page 1 of 3123»