I am trying to execute a certain string of commands on the start of a program, but it is not running. I have tried multiple things but my code right now looks something similar to this
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;
using System.IO;
namespace scriptname
{
public partial class Form1 : Form
{
public List<string> stringName = new List<string>();
public int stringCount = 0;
public Form1()
{
InitializeComponent();
}
//this code needs to run on app startup.
//--------------------------------------------------------------------------
public Awake()//this is from my knowledge with Unity
{
if (!Directory.Exists(#"C:\Example"))
{
Directory.CreateDirectory(#"C:\Example");
StreamWriter exampleText = new StreamWriter(#"C:\Example\Example.txt");
}
else
ReadFromFile();
}
//--------------------------------------------------------------------------
}
}
Note, I am using visual studio forms as my base.
I am trying to get the highlighted text to run on startup, but every time I check, the folder isn't made. All I can think is that the code isn't running.
I really don't know how to initialize it on startup, and I was hoping for some help. I can make it run on a button press, but then where is the fun of that?
Awake is something that works with unity. Thats not going to work on a Forms app
public Form1()
{
InitializeComponent();
Awake(); // This will call awake when the form starts. Consider renaming it
}
public Form1() is the constructor of this form class. It will always be called when ever you load the form. Everytime you run this form that method will be called. If you only want the code to be run once regardless of how many instances of the form you create at run time you should move the code to the Main method in the default Program.cs.
You should also not save or create directories right in the C: drive. You should use the App data folder.
The best way is to use the proper events to trigger on the point in time you want. There is a event that are actually fairly close to what Unity has with it's Awake function. It is called OnLoad and is run whenever the Load event happens (which is right before the form is shown for the first time)
public partial class Form1 : Form
{
public List<string> stringName = new List<string>();
public int stringCount = 0;
public Form1()
{
InitializeComponent();
}
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e); //You must remember to call base.OnLoad(e) when you override
if (!Directory.Exists(#"C:\Example"))
{
Directory.CreateDirectory(#"C:\Example");
StreamWriter exampleText = new StreamWriter(#"C:\Example\Example.txt");
}
else
ReadFromFile();
}
}
Related
I'm pretty new with C#, and I was wondering if it would be possible to move parts of code (from my main Form) to an external .cs file (still in the same solution), with the same level of access to variables and functions from my form1.cs file, as my original form1.cs file.
I'm working with the latest version of the .NET-framework and I have no other references to (external) code.
Here is a simple example of what I'm looking for:
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 Code1
{
public partial class Form3 : Form
{
public Form3()
{
InitializeComponent();
}
// variables
text1 = "Hello"
public void ExternalCode()
{
this.BackgroundImage = null;
Btn1.Text = "Click me";
Lbl1.Text = text1;
}
private void Btn1_Click(object sender, EventArgs e)
{
ExternalCode();
}
}
}
This form only has a button named "Btn1" and a label named "Lbl1" in it.
I would like the code inside the method SeparateCode to be in a separate file, but still with the ability to access the variables and controls from Form3, and for Form3 to still be able to execute the method in the external file (ExternalCode).
I thought of making this file a daughter of the Form3.cs, but as I said, I'm still pretty new at this so I don't really know how to.
Yes, that is possible, because the class has been declared as partial, here:
v-----v
public partial class Form3 : Form
This keyword means that the file you grabbed that code from can be one of many, all declaring their own partial content for this class.
So what you can do is add yet another file to your project, and make sure it contributes to this class. To do that you must:
Declare the class inside the file as belonging to the same namespace as the original
Declare the class inside to be the same class as the original
Note that you don't have to mention inheritance, such as the part with : Form from your original, as this will still be understood from your original file.
So, if you add a file with this content:
namespace Code1 // <-- this has to be the same
{
public partial class Form3 // <-- as does this
{
public void ExternalCode()
{
this.BackgroundImage = null;
Btn1.Text = "Click me";
Lbl1.Text = text1;
}
}
}
then you can remove ExternalCode from your original file, and it should still work just fine.
The compiler will treat all of these files as building up the same, one, class, Form3.
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.csclass, 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.csclass that has all my code for the "Save", "Add", and "Delete" buttons, which I transferred over from Form1.cs. I then call the saveAddDelete.csclass in Form1.csunder 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.)
I'm sure this is something simple that I am just overlooking, but I can't figure it out. I am new to C# and I'm trying to create a calculator application. I have created my form with all of my buttons/textbox on it. Now I'm creating a new class to handle all of my methods and whatnot. My problem is that whenever I'm trying to reference controls on the form in the second class, I get the "does not exist in the current context" error. How can I solve this?
An example:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WindowsFormsApplication2
{
public class Calculator
{
decimal currentValue = Decimal.Parse(displayValue.text);
}
}
displayValue receives the error. Thank you for any help.
The Controls can be called only from the .cs file which is linked with the form controls.
What you can do is create a parameterized constructor of your Calculator class like this:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WindowsFormsApplication2
{
public class Calculator
{
public Calculator(string displayValue)
{
decimal currentValue = Decimal.Parse(displayValue);
}
}
}
Now, you can call this class in the form .cs where you have buttons and textboxes like this:
Calculator calculate = new Calculator(displayValue.Text);
When you create a new Windows Form Application, there's a designer (which you can interact with to add your buttons and textboxes) and the code-behind (a .cs file).
This .cs file is a partial class, meaning it is also defined by the form you are interacting with. (you can see the nitty gritty details in your .Designer.cs file)
Once you name your buttons and textboxes, you can refer to their names in the code in your partial class!
And when you compile this, your button text will change to "Hello World!"
Hope this helps.
You will find this control in partial class of the form. You can take values from it and do your operation
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
string s = textBox1.Text;
}
}
In C#, let's say there are two forms: the first and the second. The first form is what the program starts by using, and it basically is the overlord in relation to the other forms. The second form is a specific-use thing that will spawn modally (correct word?) when a certain button is clicked on the first form. All the second form does is get a selection from the user. It can be represented easily as either an int or a string. Now when that second form closes (which happens when the user hits the only button on that form to lock in their choice), there's the little issue about that variable which stored the choice being lost without ever being copied over to the first form. How do I alleviate this problem? I would prefer for the variable to actually only be in the class of the first form, not the second, unless that would cause more than a couple of extra lines of code.
Two forms. Form1 and Form2. Form2 spawns modally, using ShowWindow(this), this parameter insures Form2 that only the form Form1 has spawned it, so in that case, it sets up internal properties (for short). As a plus, properties are declarerd internal, for use in one assembly, and writeable by Form2 only.
The best way to achieve desired result is like that.
Form1:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace test1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
//declate private varliables
int parameter1;
string parameter2;
private void button1_Click(object sender, EventArgs e)
{
// create form
Form2 form2 = new Form2();
if (form2.ShowDialog(this) == DialogResult.OK)
{
// if the button is pressed
parameter1 = form2.Parameter1;
parameter2 = form2.Parameter2;
}
}
}
}
Form2:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace test1
{
public partial class Form2 : Form
{
public Form2()
{
InitializeComponent();
}
//declate internal parameters
internal int Parameter1 { get; private set; }
internal string Parameter2 { get; private set; }
private void button1_Click(object sender, EventArgs e)
{
// if the button is pressed
Form1 form1 = this.Owner as Form1;
if (form1 != null)
{
// sets the local parameters
Parameter1 = -1;
Parameter2 = "John Doe";
this.DialogResult = DialogResult.OK;
Close();
}
}
}
}
Forms are classes. They can have public properties. Have the first form create the second form, then set a property with the variable's value. The second form can then use the property.
If I understand correcly then you want to update FORM1 values FROM FORM2 so you can use either of following way, Parent Form() or Delegate to update.
To use parent form you need something like,
(ParentForm as Form1).MyProperty = 123;
//This will work if you working in MDI like scenario.
I would suggest to use delegate.
I just posted a question about how to get a delegate to update a textbox on another form. Just when I thought I had the answer using Invoke...this happens. Here is my code:
Main Form Code:
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.IO;
using System.Data.OleDb;
using System.Collections.Specialized;
using System.Text;
using System.Threading;
delegate void logAdd(string message);
namespace LCR_ShepherdStaffupdater_1._0
{
public partial class Main : Form
{
public Main()
{
InitializeComponent();
}
public void add(string message)
{
this.Log.Items.Add(message);
}
public void logAdd(string message)
{ /////////////////////////// COMPILER ERROR BELOW ///////////
this.Invoke(new logAdd(add), new object[] { message }); // Compile error occurs here
}////////////////////////////// COMPILER ERROR ABOVE ///////////
private void exitProgramToolStripMenuItem_Click(object sender, EventArgs e)
{
Application.Exit();
}
private void aboutToolStripMenuItem1_Click(object sender, EventArgs e)
{
Form aboutBox = new AboutBox1();
aboutBox.ShowDialog();
}
private void settingsToolStripMenuItem_Click(object sender, EventArgs e)
{
}
private void settingsToolStripMenuItem1_Click(object sender, EventArgs e)
{
settingsForm.settings.ShowDialog();
}
private void synchronize_Click(object sender, EventArgs e)
{
string message = "Here my message is"; // changed this
ErrorLogging.updateLog(message); // changed this
}
}
public class settingsForm
{
public static Form settings = new Settings();
}
}
Logging Class Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace LCR_ShepherdStaffupdater_1._0
{
public class Logging
{
static Main mainClass = new Main();
static logAdd logAddDelegate;
public static void updateLog(string message)
{
logAddDelegate = mainClass.logAdd;
logAddDelegate(message);
}
}
}
Compile Error:
InvalidOperationException was
unhandled - Invoke or BeginInvoke
cannot be called on a control until
the window handle has been created.
I already tried to create a handle on the Log item...but that didn't work. The problem is I have NO CLUE what I am doing and I have searched Google extensively only to find vague answers.
Please tell me how to create the handle before I invoke this delegate. While you are at it, give me some ways I can make this code more simple. For example, I dont want two Add functions... I had to do that because there was no way for me to find an item to invoke from the Logging class. Is there a better way to accomplish what I need to do?
Thank you!!!
EDIT:
My project is fairly large, but these are the only items causing this specific problem.
Log is my RichTextBox1 (Log.Items.Add(message)) I renamed it to Log so it is easier to retype.
I am calling updateLog(message) from a different form though...let me update that in here (although it makes no difference where I call updateLog(message) from it still gives me this error)
You guys are going to have to make things more simpler for me...and provide examples. I don't understand HALF of everything you guys are saying here...I have no clue on how to work with Invoking of methods and Handles. I've researched the crap out of it too...
SECOND EDIT:
I believe I have located the problem, but do not know how to fix it.
In my logging class I use this code to create mainClass:
static Main mainClass = new Main();
I am creating a entirely new blueprint replica to Main(), including Log (the richtextbox I am trying to update)
When I call updateLog(message) I believe I am trying to update the Log (richtextbox) on the second entity of Main() otherwise known as mainClass. Of course, doing so will throw me this exception because I haven't even seen that replica of the current Main I am using.
This is what I am shooting for, thanks to one of the people that gave an answer:
Main mainClass = Application.OpenForms.OfType<Main>().First();
logAddDelegate = mainClass.logAdd;
logAddDelegate(message);
I need to create mainClass not with the new() operator because I dont want to create a new blueprint of the form I want to be able to edit the current form.
The above code doesn't work though, I can't even find Application. Is that even C# syntax?
If I can get the above code to work, I think I can resolve my issue and finally lay this problem to rest after a couple of HOURS of seeking for answers.
FINAL EDIT:
I figured it out thanks to one of the users below. Here is my updated code:
Main Form Code:
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.IO;
using System.Data.OleDb;
using System.Collections.Specialized;
using System.Text;
using System.Threading;
delegate void logAdd(string message);
namespace LCR_ShepherdStaffupdater_1._0
{
public partial class Main : Form
{
private static Main mainFormForLogging;
public static Main MainFormForLogging
{
get
{
return mainFormForLogging;
}
}
public Main()
{
InitializeComponent();
if (mainFormForLogging == null)
{
mainFormForLogging = this;
}
}
public void add(string message)
{
this.Log.Items.Add(message);
}
public void logAdd(string message)
{
this.Log.BeginInvoke(new logAdd(add), new object[] { message });
}
private void exitProgramToolStripMenuItem_Click(object sender, EventArgs e)
{
Application.Exit();
}
private void aboutToolStripMenuItem1_Click(object sender, EventArgs e)
{
Form aboutBox = new AboutBox1();
aboutBox.ShowDialog();
}
private void settingsToolStripMenuItem_Click(object sender, EventArgs e)
{
}
private void settingsToolStripMenuItem1_Click(object sender, EventArgs e)
{
settingsForm.settings.ShowDialog();
}
private void synchronize_Click(object sender, EventArgs e)
{
add("test");
Logging.updateLog("testthisone");
//DatabaseHandling.createDataSet();
}
}
public class settingsForm
{
public static Form settings = new Settings();
}
}
Logging Class Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace LCR_ShepherdStaffupdater_1._0
{
public class Logging
{
static Main mainClass = Main.MainFormForLogging;
static logAdd logAddDelegate;
public static void updateLog(string message)
{
logAddDelegate = mainClass.logAdd;
logAddDelegate(message);
}
}
}
Right, I'm going to start again.
In order to understand what is happening, you need to understand how .NET and Windows relate to one another. .NET runs on Windows and wraps many of the native, Win32 concepts like a window, a listview, an editbox (the Win32 name for a standard textbox). This means that you can have a valid .NET instance of a TextBox or a Form, but not have the underlying Windows version of that item (EditBox, or Window) yet. When HandleCreated is true, the Windows version of the item is created.
Your issue is occurring because something is leading to the logAdd method being called before the Form's Window has been created. This means somewhere during your startup after the Form instance has been instantiated but before the Window handle has been created, something is trying to call logAdd. If you add a breakpoint to logAdd, you should be able to see what is doing that call. What you will find is that the call is being made on the Main instance you create in your logger class and NOT the Main instance that is actually running. As the logger instance never gets shown, the window handle is not created, and so you get your error.
The general way an application runs is to call Application.Run(new Main()) in your startup method, which is usually in the Program class and called Main. You need your logger to point to this instance of main.
There are several ways to get the instance of the form, each with its own caveats, but for simplicity you could expose the instance off the Main class itself. For example:
public partial class Main : Form
{
private static Main mainFormForLogging;
public static Main MainFormForLogging
{
get
{
return mainFormForLogging;
}
}
public Main()
{
InitializeComponent();
if (mainFormForLogging == null)
{
mainFormForLogging = this;
}
}
protected void Dispose(bool disposing)
{
if (disposing)
{
if (this == mainFormForLogging)
{
mainFormForLogging = null;
}
}
base.Dispose(disposing);
}
}
I have solved this in the past using the following method:
private void invokeOnFormThread(MethodInvoker method)
{
if (IsHandleCreated)
Invoke(new EventHandler(delegate { method(); }));
else
method();
}
Call invokeOnFormThread instead of Invoke. It will only use the form's thread if a handle has already been created, otherwise it will use the caller's thread.
When you get this error, it almost always means that you've attempted to act on a control or form before it was actually created.
In WinForms, GUI elements have two semi-independent lives: as classes in memory and as entities in the operating system. As such, it's possible to reference a control in .net that hasn't actually been created yet. The "handle being created" refers to having a number assigned to the control by the OS to allow programs to manipulate its properties.
In this case, most errors can be eliminated by setting a flag at the end of the form's load event and only attempting to manipulate the form's controls after that flag has been set.
It's a runtime error, not a compiler error.
Your Form, "Main", has to be displayed (hence a window handle created) before you can make calls to BeginInvoke or Invoke on it.
What I usually do in these situations is leave it up to the Form to determine if it needs to use a call to BeginInvoke or Invoke. You can test that with a call to InvokeRequired (check MSDN).
So for starters, I'd get rid of the logAddDelegate call in the Loggin class's updateLog method. Just make a straight call to the form to add a log. Like so:
public partial class Main : Form
{
public Main()
{
InitializeComponent();
}
private delegate void AddNewLogMessageEventHandler(string message);
public void AddLogMessage(string message)
{
object[] args = new object[1];
args[0] = message;
if (InvokeRequired)
BeginInvoke(new AddNewLogMessageEventHandler(AddLog), args);
else
Invoke(new AddNewLogMessageEventHandler(AddLog), args);
}
private void AddLog(string message)
{
this.Log.Items.Add(message);
}
}
}
So you can see, the Form itself is in charge of determining if it needs to call the method asynchronously or not.
However, this still won't fix your runtime error, because you're making a call to the form before its been displayed. You can check to see if the form's Handle is null or not, and that will at least allow you to verify whether or not you're dealing with a valid Form.
That error tends to happen if you invoke on a window that has not yet been 'shown'. Are you sure you're not creating a second instance of the main class with your code in the Logging class (specifically, the first line)? It may be that the main form you are calling log on is NOT the main form you are looking at. If you want to check, add a call to "MainClass.Show()" just inside your logging call. If you get a second copy of the main form popping up, then the problem is that your logging class is not referencing the right 'instance' of your form.
Think of the class as a 'blueprint'. Each instance of the class (created with the word 'new') is another object, created from the blueprint. Just because two objects (in this case, your two main forms) share the same blueprint, doesn't mean that you can use them interchangeably. In this case, you already have a main form, and you want to 're-use' it. You can try:
MainClass myMainForm = Application.OpenForms.OfType<MainClass>().First();
logAddDelegate = myMainForm.logAdd;
logAddDelegate(message);
inside your log function instead of what you currently have. The difference is that the call to Application.OpenForms.OfType().First will go into your application, and retrieve the ACTUAL main form that you are seeing (technically, it will retrieve the first instance of it) and make your invocation on that form, directly.
Hope this helps.
This is to help in case any other person got caught up with this.
My problem:
VB.net: “Invoke or BeginInvoke cannot be called on a control until the window handle has been created.”
I closed a form which has a handler for the event am calling to update the delegate, without removing the handler for the event.
What I did: When I close the form, I removed all the handlers, and assigned them back when i opened the form. It solved the problem.
logAddDelegate(message);
I think you are calling this before the Form_Load event has been raised. Fix your code to wait for the form to load before calling logAddDelegate(...) i.e. before calling Logging.updateLog()
Is this your exact code? You are calling this.Log.Items.Add(message); in your add(string) method, but your logging class is called Logging, not Log. Have you got another form called Log perhaps? If that form hasn't been created when you call the add method, you will get this exception.
I found the InvokeRequired not reliable, so I simply use
if (!this.IsHandleCreated)
{
this.CreateHandle();
}