I am setting a .dll file to create a new form and a new button, but i want that button to do something. Is it possible to create a event handler in a dll file?
public static byte sbuton( string er, int by,int re)
{
Form fg = new Form();
fg.Show();
Button b1 = new Button();
fg.Controls.Add(b1);
b1.Text = er;
b1.Location = new Point(by, re);
return 0;
}
This is the code that creates a form with a button in it.
When I try to create a new event handler, as I would in a form, I get this error: "An object reference is required for the non-static field, method or property".
public static byte sbuton( string er, int by,int re)
{
Form fg = new Form();
fg.Show();
Button b1 = new Button();
fg.Controls.Add(b1);
b1.Text = er;
b1.Location = new Point(by, re);
b1.Click += new EventHandler(b1_click);
}
private void b1_click(object sender , EventArgs e)
{
}
This is the code from the form where I want use the dll
private void button1_Click(object sender, EventArgs e)
{
if (richTextBox1.Text.Contains("add") && richTextBox1.Text.Contains("buton") && richTextBox1.Text.Contains("text"))
{
form.sbuton("buton", 10, 10);
}
}
This creates a button, but nothing happens when the button is clicked, because no event handler is assigned to it in the .dll file.
And also,sorry for the bad english,it is not my native language.
What can i do?
Thanks!
It's not clear from your question what the context is. Without a good, minimal, complete code example it's difficult to provide a really good answer.
But in your example, it appears that your event handler is in the same DLL (and I assume, the same class) as the sbuton() method. If that's the case, then all you need to do in order to use the event handler is make it a static method:
private static void b1_click(object sender , EventArgs e)
{
}
Now, since you didn't post any of the code in the method, never mind the full context, it's not certain that would work. I.e. if there is a good reason for that method being a non-static method, then you will have to subscribe the event handler by referring to the method with a reference to an actual instance of the containing class. If that's the case, then the question commenter Daniel Kelley suggests, An object reference is required for the non-static field, method, or property?, may turn out to be appropriate for your needs after all.
Finally, note that none of this has anything to do with the code being in a DLL. You would have run into this same problem had your sbuton() method been in the same project from which you're calling it.
Related
Wierd behaviour when passing values to and from second form.
ParameterForm pf = new ParameterForm(testString);
works
ParameterForm pf = new ParameterForm();
pf.testString="test";
doesn't (testString defined as public string)
maybe i'm missing something? Anyway I'd like to make 2nd variant work properly, as for now - it returns null object reference error.
Thanks for help.
Posting more code here:
calling
Button ParametersButton = new Button();
ParametersButton.Click += delegate
{
ParameterForm pf = new ParameterForm(doc.GetElementById(ParametersButton.Tag.ToString()));
pf.ShowDialog(this);
pf.test = "test";
pf.Submit += new ParameterForm.ParameterSubmitResult(pf_Submit);
};
definition and use
public partial class ParameterForm : Form
{
public string test;
public XmlElement node;
public delegate void ParameterSubmitResult(object sender, XmlElement e);
public event ParameterSubmitResult Submit;
public void SubmitButton_Click(object sender, EventArgs e)
{
Submit(this,this.node);
Debug.WriteLine(test);
}
}
result:
Submit - null object reference
test - null object reference
pf.ShowDialog(this); is a blocking call, so pf.Submit += new ParameterForm.ParameterSubmitResult(pf_Submit); is never reached: switch the order.
Submit(this,this.node); throws a null object reference because no event is assigned to it (see above). Generally, you should always check first: if (Submit != null) Submit(this,this.node);
You should change ``pf.ShowDialog(this);topf.Show(this);` so that your main form isn't disabled while your dialog box is open, if that's what you want, or use the model below (typical for dialog boxes.)
I'm not sure what pf_Submit is supposed to do, so this might not be the best way to go about it in your application, but it's how general "Proceed? Yes/No" questions work.
Button ParametersButton = new Button();
ParametersButton.Click += delegate
{
ParameterForm pf = new ParameterForm(testString);
pf.ShowDialog(this); // Blocks until user submits
// Do whatever pf_Submit did here.
};
public partial class ParameterForm : Form
{
public string test; // Generally, encapsulate these
public XmlElement node; // in properties
public void SubmitButton_Click(object sender, EventArgs e)
{
Debug.WriteLine(test);
this.Close(); // Returns from ShowDialog()
}
}
When you want to use your second variant, you have to use a getString()-Method, where you can put the e.g. "testString". The way you wrote it, "testString" should be a method (and got brackets).
EDIT (a bit more precise):
You could write:
pf.getString(testString);
, if "pf" is an instance of your own class, otherwise you had to look up, whether you can retrieve a String in this class.
the thing was in line order :)
pf.Submit += new ParameterForm.ParameterSubmitResult(pf_Submit);
and
pf.Test = "test";
should have been set before
pf.ShowDialog(this);
my mistake thingking that parameter can be passed after 2nd form was displayed
thnx for answers
I'm running a main WinForm with most UI elements, and then an Add form is called when the Add button is picked. It should receive input, and send it back to the WinForm once accepted.
This code runs when you click the "Add" button on the main class:
public void addButton_Click(object sender, EventArgs e)
{
AddView newadd = new AddView();
newadd.Show();
}
This code (also in the main class) should run based upon a button in the AddView:
public void AddDashObject(string dashName, string dashIdentifier, int dashFunction, string dashFunctionInfo, int dashVerbosity)
{
DashObject tmp = new DashObject("","",0,"",0);
tmp.DashName = dashName;
tmp.DashIdentifier = dashIdentifier;
tmp.DashFunction = dashFunction;
tmp.DashFunctionInfo = dashFunctionInfo;
tmp.DashVerbosity = dashVerbosity;
dashloaded.Add(tmp);
ReloadDashObjects();
}
I'm not really sure how to communicate between the forms - I can use a type created in the main class, and also methods, but I'm pretty sure I'm creating a separate instance. How can I communicate with the existing one?
MainView mnfrm = new MainView();
MainView.DashObject tmp = new MainView.DashObject("","",0,"",1); // Defaults
private void button1_Click(object sender, EventArgs e)
{
mnfrm.dashloaded.Add(tmp); // Add the default DashObject to MainView's currently loaded DashObjects
mnfrm.ReloadDashObjects(); // Reload the list
}
Not sure how to proceed on this - any advice?
Since the Add dialog is expected to be modal, the decoupled way to do this is to only close the dialog with an OK status. I.e. the form is just an input control that doesn't actually "do" anything.
Then the main form can:
1) check how the dialog was closed right after ShowDialog(),
2) call some GetResult() function to get the values from the add form before disposing it.
3) call the business logic that actually creates and reloads the DashObjects.
I have a ToolStripMenuItem that I want to declare and instantiate with a String, a null value for an image, and an Event Handler for its Click event. This is the format Intellisense is expecting:
ToolStripMenuItem(string text, System.Drawing.Image image, EventHandler onClick).
But I am unable to assign the Event Handler and I do not know the proper syntax to do so. As a workaround, I assign the .Click event in the constructor like so...
class Timer
{
//The other WinForms objects and my methods are omitted.
private ToolStripMenuItem StartButton = new ToolStripMenuItem("Start Timer");
public Timer()
{
//I want the assignment of StartButton_Click in my declaration and initialization of StartButton, not here.
StartButton.Click += new EventHandler(StartButton_Click);
}
public void StartButton_Click(object sender, EventArgs e)
{
//The logic here is not relevant.
}
}
I tried the syntax below but I keep getting the error:
"CS0236 A field initializer cannot reference the non-static field, method, or property 'Timer.StartButton_Click(object, EventArgs)'"
new ToolStripMenuItem("Start Timer", null, new EventHandler(StartButton_Click));
Intelliense suggests I use the format
EventHandler(void(object,EventArgs)target)
but I do not know how to fill out the expected syntax property. How do I write the declaration of StartButton so that the method StartButton_Click is called after a Click event?
The correct place to instantiate it is in the constructor. Do it all at once, like this:
private ToolStripMenuItem StartButton;
public Timer()
{
StartButton = new ToolStripMenuItem("Start Timer", null, StartButton_Click);
}
As for that compiler error, you can read more about it here, although it's sparse on the details.
From Stack Overflow: You cannot use an instance variable to initialize another instance variable. Why? Because the compiler can rearrange these - there is no guarantee that reminder will be initialized before StartButton_Click, so the above line might throw a NullReferenceException.
Make the method static and you should be good to go.
I've been looking all over for a possible solution, but none seem to come close to what I actually need. I have a windows form which outputs to a class library (dll). I reference this dll into a console application and then launch the GUI in the dll. I want to be able to subscribe to a control event and do what ever code in my console application.
I have no problem when I want to read or write properties in the dll directly from my console app. Example:
MyDll.MyClass myObj = new MyDll.MyClass();
myObj.Textbox1.Text = "Hello World!";
However, I would like to subscribe to the TextChanged event in my dll and output the new text to my console app. Something along the lines of:
public void textbox1_TextChaned(object sender, EventArgs e)
{
Console.WriteLine(myObj.textbox1.Text);
}
Is there any way to subscribe directly to that event? or some other event?
Set the modifier of textbox1 to public
Subscribe to the TextChanged event:
myObj.Textbox1.TextChanged += textbox1_TextChaned;
The following code in a console app works for me. I'm referencing a Windows Form Application rather than a DLL, but I don't think there should be much difference:
class Program
{
static WindowsFormsApplication1.Form1 frm;
static void Main(string[] args)
{
frm = new WindowsFormsApplication1.Form1();
frm.textBox1.TextChanged += textBox1_TextChanged;
System.Windows.Forms.Application.Run(frm);
}
static void textBox1_TextChanged(object sender, EventArgs e)
{
Console.WriteLine((frm.textBox1.Text));
}
}
This doesn't answer your question directly, but it will solve your problem in a neater way, IMO.
In your DLL define an interface (IEventProcessor).
In your console
application implement the interface (ConsoleEventProcessor).
Pass an instance through the constructor of the form
call its methods from the events in the form.
In the console app:
IEventProcessor processor = new ConsoleEventProcessor();
MyDll.MyClass myObj = new MyDll.MyClass(processor);
Then in the form:
IEventProcessor _processor;
// constructor
public MyClass(IEventProcessor processor)
{
_processor = processor;
}
public void textbox1_TextChaned(object sender, EventArgs e)
{
// pass whatever parameters you need to use in the method
_processor.ProcessText1Changed(textbox1.Text);
}
I know this has to have an easy answer, but I'm utterly failing to fathom the wealth of information on custom events, event handlers, and delegates. I have a custom messagebox class. I am trying to add the capability to do something based off of the state of a check box if the OK button is clicked. The buttons and the checkbox are added dynamically based upon input into a static Show method somewhat like the following:
if (!String.IsNullOrWhiteSpace(suicideCheckboxID))
{
suicideCheckBox = new CheckBox();
suicideCheckBox.AutoSize = true;
suicideCheckBox.Text = "Do not show this message again.";
suicideCheckBox.Location = new Point(xMargin, label.Bottom + yMargin);
suicideCheckBox.Checked = false;
suicideCheckBoxHeight = suicideCheckBox.Height;
form.Controls.Add(suicideCheckBox);
}
Button okButton = NewButton(DialogResult.OK, scaleFactor);
int x = (form.Width - okButton.Width) / 2;
okButton.Location = new Point(x, buttonYPosition);
form.Controls.Add(okButton);
form.AcceptButton = okButton;
form.CancelButton = okButton;
That's not the exact code, but it's fairly representative. My impulse is to use okButton.Clicked += new EventHandler(OKButton_clicked), but if I do that, the event generated only carries arguments for object sender and EventArgs e and I really need it to operate off of the state of the checkbox and an additional piece of text to indicate which messagebox is being shown so that the values can be stored in the registry.
My first attempt was to do something like okButton.Clicked += processSuicideCheckbox(suicideCheckboxID, suicideCheckBox);, but that seems to just process the contents and allow one to return an EventHandler that points to a method with the signature of object sender and EventArgs e. What am I missing here? What is the best way to pass in the arguments actually relevant to me?
You don't get to choose what is in the event handler for the Click event. Microsoft has already done that. You are stuck with the (object sender, EventArgs e) signature.
You do have a couple options:
Simply store the state in the class itself; the event handler will have access to it because it is inside the class.
Utilize a closure to do the same thing:
myButton.Click += (s, e) => ActualFunction(checkBox1.Checked);
Note that using the closure (via a lambda expression) is just hiding the details of maintaining this state (creating the class-level variables).