linking winform btn to different class - c#

i have a form holding a button that, when clicked, needs to perform the actions within another class.
for example,
the user clicks a btn thats says BookNow.
the coding within the btn needs to point to the BookNow class which has information for booking.
can anyone help me with this issue please?

You need to create an instance of the BookNow class and call the function on it, from the button event handler.
public void button1_click(object sender, EventArgs e)
{
BookNow bn = new BookNow();
// Call methods/properties on bn
}
I would avoid calling the button with the same name of the class, as you will run into namespace and naming conflicts.

May be you are looking for command design pattern
http://www.dofactory.com/Patterns/PatternCommand.aspx#_self1

Related

Access a ListView located in a UserControl from the MainForm in Winforms

I have an app that uses a side menu, and for each button (there are 3) on the left side menu, it changes the pages shown.
I tried doing it with multiple panels, but it's a nightmare to maintain in designer, and it's probably not a very good programming habit, I expect.
So I search and found what seemed to be a great idea: UserControl.
But as usual, it's not that simple (for a badly self-taught guy like me)
The general flow of the program is as follows:
a Btn_uc1_Check button that gathers informations and displays them in a uc1_ListView,
a Btn_uc2_Seek button that gathers informations on the net based on the uc1_ListView , and displays them on uc2_ListView,
a Btn_uc3_compile that compiles the info from uc2_ListView into a file,
a Clear button that clears the ListView depending on the UserControl on screen.
Now to the problem:
How on earth do I gain access to a ListView located in a UserControl to be able to read, clear, and add items from the MainFrom or from another UserControl?
I searched and honestly found nothing corresponding to what I needed?
Quite many questions.
You can gain access to any controls in UC. Just change the property "Modifiers" of the ListView in your UC to "Public".
Set that method to public. Do not use keyword "static". Each control
in your form is an instance of a class, not a static class actually. In the main form, create a button and double click on it in VS designer. A method will automatically generated, something like private void button1_Click. When the button is clicked, all of the code lines in button1_Click will run.
Create a public event handler of your user control, then pass the method in main to the handler.
So the UC class will be similar to this:
public event EventHandler button_UC_Click_handler;
public UserControl1()
{
InitializeComponent();
}
private void button_UC_Click(object sender, EventArgs e)
{
button_UC_Click_handler.Invoke(sender, e);
}
In main form:
public MainForm()
{
InitializeComponent();
userControl11.button_UC_Click_handler += UserControl11_button_UC_Click_handler;
}
private void UserControl11_button_UC_Click_handler(object sender, EventArgs e)
{
MessageBox.Show("You have clicked it!");
}
Good luck!

Can't pass a Button as a parameter

What I'm trying to do here is really simple but it's not working for me. I've looked up many examples of very similar or matching questions on stackoverflow and others and their solutions haven't worked for me.
Basically (in a very simplified form), I have a button with some text in it. I'd like it so when this button is clicked, a message box shows up displaying the text. However, I have 9 of these buttons (think numbers on a calculator), and I'd like to create a single method that handles all of these clicks, and outputs the correct text depending on the button.. which is why I need to pass the button as a parameter.
Here's the code I have for the method that handles it so far:
private void btn_Click(object sender, EventArgs e, Button b)
{
MessageBox.Show(b.Text);
}
The above small code snippet is the same solution that others have used and had working. However, for me this code doesn't compile and shows an error that says No overload for 'btn_Click' matches delegate 'System.EventHandler'.
When I double click on that error, it takes me to the Designer.cs page for the form, and this is the line of code that has the error:
this.btnN7.Click += new System.EventHandler(this.btnN7_Click);
I have no clue what the overload and delegate parts mean, sorry I'm pretty new to this. I was thinking that maybe overload has to do with constructors but even if that's correct, I'm unsure of what the next step would be.
I have System.Windows.Forms; included properly so the issue shouldn't be that the Button object wasn't recognized.
If you could provide any insight as to what I'm missing or doing wrong, that'd be very sweet! Please let me know if you need any additional information to continue.
And lastly, this is unrelated to my issue but it's a small question that's been irking me ever since I started using VS a week ago: Are the control parameters object sender and EventArgs e that are automatically created for controller events even necessary? Most of the examples I've looked up online omit them. I've just kept them in since they were created by default but I don't really know what kind of function they provide, and I've never had to use those parameters in my methods.
Thanks all! =)
You just need to use sender parameter.You can't subscribe an event handler if the method signature doesn't match with the EventHandler delegate.
private void btn_Click(object sender, EventArgs e)
{
var currentButton = sender as Button;
if(currentButton != null) MessageBox.Show(currentButton.Text);
}
sender will be assigned to an object that triggers the event.So for instance when your button2 is clicked, it will be assigned to button2.Ofcourse you need to attach this event handler to button2's Click event.I have also used the as operator to ensure that a button is triggered the event.In the future if you call this method manually like btn_Click(this, EventArgs.Empty) then the explicit cast will throw an InvalidCastException.Using as operator is always better to avoid this.If the type of the sender is different than Button then currentButton will be null.
which is why I need to pass the button as a parameter.
You don't really have to create that extra parameter. What you need is already there.
object sender is a source of the event, so just call
var btn = (Button) sender;
MessageBox.Show(btn.Text);
and you should be fine.
Are the control parameters object sender and EventArgs e that are automatically created for controller events even necessary?
So now you have a part of an answer for this question. The second part (EventArgs) are needed for passing additional information. Read more about event args on MSDN.
You have two options here:
If you want to access to the button that fired the event, you can do it trough sender
private void btn_Click(object sender, EventArgs e)
{
Button b = (Button)sender;
MessageBox.Show(b.Text);
}
Otherwise, access directly through the button name (in case you know it)

Registering to event and create a new method at run time - c#

How can I register to event and do some actions at runtime?
For example when the user click on a button I want to register to OnMyEvent and run MyFunc that let's say initialize some textBox with the OnMyEvent args.
I'm using winforms and .NET 4.
EDIT
Maybe I was unclear... I need the ability to register to existing event and add a new method that will run when the event will fire. All at runtime.
EDIT2
i'll try to give an example...
lets say that i have a class named "A" that have many events OnDataRecived OnDataSend etc...
when the application running the user can choose form a combobox event name to register (i got the events list via reflection because they not constracts, they are generated from xml file) and which data to update when the choosed event is fired.
so for the example the user choose to register to the OnDataReceived and he choose to update property named DataStream. some code...
in run time upon user choosing:
A.OnDataReceived += (s,e) => MyRunTimeMethod(s,e);
private void MyRunTimeMethod(object sender, EventArgs e)
{
DataStream = e.Data.Value
}
You are asking how to create a method dynamically at runtime - once you have a reference to that method in a delegate, the question of how to register it to an event is trivial.
MSDN describes how to do this with MSIL instructions. I doubt that's what you're looking for, but it is an option.
The C# FAQ blog has a much more interesting solution using expression trees. I suppose this is the one you were referring to by originally tagging your post with expression-tree.
But I would reconsider using dynamic methods at all. How exactly is the user going to specify what action to perform on the event of his choice? I suspect that the options are limited enough that you can get by with something simpler:
protected void btnRegister_Click(object sender, EventArgs e) {
switch (cmbEvents.SelectedText) {
case "OnLoad":
MyControl.OnLoad += (s, e) => SomeSelectedControl.Text = SomeInputControl.Text;
break;
//... other cases
}
}
If you're using windows forms, double clicking a button will bring you to a created on_click event. If you bring up the properties window for the button, theres an events tab. Viewing this will show you which events are available for a control.
I found the best way to understand this, was to look at the code created when adding the events.
Update:
As noted, I completely missed the point with my answer. The syntax for subscribing to an event at runtime is the same way as it's done on form Initialize. So I don't get any terminology wrong, here's the link to the msdn documentation;
http://msdn.microsoft.com/en-us/library/ms366768.aspx
What you want to achieve, does not require you to "Register to event at run time".
If button1 is the button of interest here, simply use.
button1.Click += buton1_ClickHandler;
button1_ClickHandler should be defined in the same class as your button1. and it should have the signature of the RoutedEventHandler. So, it should be
private void button1_ClickHandler(object sender, RoutedEventArgs e)
{
//method code here
}

Execute 'Form_Shown' event handler more than once?

I am currently developing a Windows app with several forms. I use Form_Shown in one of those forms to execute some code to initialize (refresh) the form before showing it.
In Form.Shown Event on MSDN, it states that the event is raised only the first time the form is shown. However, I want to be able to execute code to initialize my form every time that I call Form.Show() in some of the forms. Here's an example.
From a form named Game. Contains an event handler Game_Shown and a button that when clicked shows a form named Menu:
private void btnMenu_Click(object sender, EventArgs e)
{
this.Hide();
Formulaires.formMenu.Show();
}
private void Game_Shown(object sender, EventArgs e)
{
Code here...
this.Refresh();
}
From the form named Menu. Contains a button that when clicked shows the form named Game:
private void lblGame_Click(object sender, EventArgs e)
{
this.Hide();
Formulaires.formGame.Show();
}
It is behaving by design.
From the docs:
The Shown event occurs whenever the form is first shown.
Also, you should not handle the Shown event in your class, rather you should override OnShown.
To achieve what you want, you might try overriding the OnVisibleChanged method. Inside the method, if the form is visible, then execute your code.
Like the Shown event, you should not handle it in your form class, instead override the appropriate method:
From the docs:
The OnVisibleChanged method also allows derived classes to handle the event without attaching a delegate. This is the preferred technique for handling the event in a derived class.
What you want requires some detailed knowledge about which event happens when in the WinForm lifecycle. That may be documented somewhere, I don't know.
This is how I would find out:
create a small test project with 2 forms (Main and helper)
add the show and hide buttons and make sure it works.
Add Debug.Print("EventName") to all the candidate events of the helper form.
Look at the log in the output window and pick your event.
Candidate events would be FormClosing, FormClosed, (De)Activated, Enter, Leave, Load, ... go through the list.
When you find the right one, please post it here in an answer.

Do I have to define an event in this case?

I've got a form with several controls (to make things simple, say it's a couple of textboxes), which I need to be updated by clicking on two buttons - a Forward button and a Backwards button.
Now, the general idea is that the information to be displayed is stored in some kind of array of objects, and is shown according to the value of some counter. That is, a user clicks on the Forward button -> the counter is incremented -> the corresponding array item is shown on the form. Same goes for the Backwards button.
So, the question is - should I define any specific event in this case? Or is it sufficient to use the standard
private void button1_Click(Object sender, EventArgs e) {}
event which is provided when double-clicking on a button control? I mean, what would be the right thing to do?
I think it's a pretty dumb question, still I appreciate your advice here, thanks in advance!
The click event is an ok place for that logic, however, it's a good practice to extract that forward/backward logic in a separate method (maybe you'll want to go forward by pressing the right arrow?) to something like this:
private void btnForward_Click(Object sender, EventArgs e)
{
GoForward();
}
private void GoForward()
{
// the forwarding code here
}
And, make a habit of naming controls as early as possible, because VS uses the control name to name the event handler, and button1_Click is not very descriptive :)

Categories