Changing button name and event handling at run time - c#

In my winform, in the designer.cs section of the form i have
this.Button1.Text = "&Click";
this.Button1.Click += new System.EventHandler(this.Button1_Click);
in form.cs
private void Button1_Click(object sender, System.EventArgs e)
{
//Code goes here.
}
In one part of the form i have a treeview and when that treeview contents are expanded, i need to rename the above button and wire up a different event
Button1.Name = "ButtonTest";
ButtonTest.Click += new System.EventHandler(this.ButtonTest_Click);
However this fails saying ButtonTest is not found, how do i dynamicall change the name of the button and call a different click event method?
private void ButtonTest_Click(object sender, System.EventArgs e)
{
//Code goes here.
}
Once this is called ButtonTest_Click, I need to rename it back to Button1, any thoughts?

Button1 refers to a variable name. The variable points to an instance of the Button type which has a Name property. If you change the value of the Name property, it doesn't change the name of the variable. You'll still need to refer to the button as button1. In fact, it does nothing really to change the value of the button's Name property. The Name property only really only exists to aide the Windows Forms designer.
If you want to change an event handler from one method to another, you must first unsubscribe the original handler and then subscribe the new handler. Just change your code to this:
Button1.Name = "ButtonTest";
Button1.Click -= this.Button1_Click;
Button1.Click += this.ButtonTest_Click;

This can be done by several ways:
From the Menus: Edit -> Refactor -> Rename
By contextual Menu on the name of the Method: Refactor -> Rename
Put the cursor on the Method name and type Alt + Shift + F10 and then select Rename
Put the cursor on the Method name and press F2

Related

C# designer form not updating methods of form objects?

I've been following this tutorial to name the elements on a windows form page. From what I gathered, the form will auto generate methods based on the name of the elements on the designer form.
However, while most of the textboxes, labels do update their method name when I click them and hit ENTER, some of them still reference to the default name.
In the attached image the label named "Option" remains as "label3_clicked".
Much appreciated.
Attached image of problem.
I never experience the behavior where the name of the event (which can be anything) is automatically updated to match the name of the control.
This is because the name of the event can be just anything (label3.Clicked += Whatever_Click_Whatever or even without the click Part). There is no naming rules that the compiler can check. There is just the default for auto generated ones.
What if you have a custom name that you don't want to change when changing the control name? So there is no automatic behavior here.
So what you can do is go to Form1.Designer.cs find the event like this:
this.Load += new System.EventHandler(this.Form1_Load);
Then Right click => Rename or Ctrl + R, Ctrl + R and change the name. This changes it is your form's code also.
You created the click event handler method while the Label was called label3. To fix this highlight the method name in your code behind and F2. That will enable you to change (refactor) the name of the method which in turn, will change the form designer as well.
In future just name your objects first and then create your event handler methods and all should be good.
It is a simple issue. You can fix this by creating a function when form is loaded. Set the default value for the form object in Form1_Load() function to change it on RunTime. You can get that function from form events. For example, If I want to change the name of the form, then approach is like
private void Form1_Load(object sender, EventArgs e) {
this.Text = "Initial Text"
}
After that, On your event which you want to change the Form Name. For example, I'm taking some function name
private void updateFormName_click(object sender, EventArgs e) {
this.Text = "Updated Text"
}

Excel add-in ribbon click events bubbling

I am following this walkthrough on MSDN: Creating a Custom Tab by Using the Ribbon Designer
Looking at steps 3 and 4:
In step 3 it adds an event handler to the ribbon_Load function, basically adding a click event to a button in the ribbon:
private void MyRibbon_Load(object sender, RibbonUIEventArgs e)
{
this.button1.Click += new RibbonControlEventHandler(this.button1_Click);
}
Then, in step 4 they add another event handler in the way that I am more used to, like so:
private void button1_Click(object sender, RibbonControlEventArgs e)
{
MergeReportInterface ui = new MergeReportInterface();
ui.ShowDialog();
}
I am not really understanding the purpose of this, because all it does is cause the event to fire twice. If I comment out the event handler that was added to the load function the event occurs once.
Could someone please explain to me what the point of this is? if there is any, or if there is some error on the MSDN site. What should be the proper way to handle a ribbon click event?
private void button1_Click(object sender, RibbonControlEventArgs e)
{
MergeReportInterface ui = new MergeReportInterface();
ui.ShowDialog();
}
This is not adding an event handler. This is the method that your event will call.
this.button1.Click += new RibbonControlEventHandler(this.button1_Click);
This is saying 'When button1 fires its Click event, call this.button1_Click'.
Your code only sets up one event handler, it should only fire once.
However, it's likely you created the button1_Click method by double clicking a button on your form designer. This, behind the scenes, adds an additional event handler. This is why you're getting the event fired twice.
So you have two options:
Go back into the IDE and remove the click handler via your form designer. Go to your code and manually write the method button1_Click.
OR
Remove this line: this.button1.Click += new RibbonControlEventHandler(this.button1_Click);, as VisualStudio is doing that for you automatically.

C# Objects (Creating and Using)

In C# if you create an object on a button click, at the end of the click event, the object is no longer in scope. How do I create an object on the click of a button, but release it on the click of another button. Here is what I am trying to do:
Build an application that accepts user data and adds it to a database. The application contains two classes: Personal information and employer information. The personal information class object should be created when the "Start Application" button is pressed. The application then opens a tab that requests personal information. If the "Add Employer" button is selected, an instance of Employer is created. After they press submit at the end, it should close the one or two objects and return to the main menu. When the next person presses the button, it should go through the process again.
I can create objects on click or in the class itself, but how do you limit the life of the object between to button presses?
Thanks!
Use a class-scoped data member. Very quick example:
public class MyClass
{
private Foo foo;
private void Button1_Click(object sender, EventArgs e)
{
this.foo = new Foo();
}
private void Button2_Click(object sender, EventArgs e)
{
// I can access this.foo here. I can also dispose of it
// if it is IDisposable and/or I can set it to null.
// To check if button 1 was pressed, check to see if the object
// is null (if it is, button 1 wasn't pressed)
}
}
You can do this by defining one of the event handlers anonymously inside of the other event handler:
void button1_Click(object sender, EventArgs e)
{
Foo data = new Foo();
EventHandler handler = null;
handler = (s, args) =>
{
//Use Foo here
DoStuff(data);
button2.Click -= handler;
};
button2.Click += handler;
}
Note that we need to do some extra work to make sure to remove the event handler when it is clicked here. If you don't need to do that, then it does simplify the code.
Here the anonymous method is closing over the local variable, which will extend that variable's lifetime for the lifetime of the anonymous method. This approach, unlike those using a field, actually creates a variable who's lifetime lasts until the next button is clicked, and doesn't leave a variable lying around with a meaningless value before the first button is clicked or after the second is clicked.
Sounds like you're wanting to use properties?
Here's a link to MSDN, but there's lots out there if you just Google'C# properties'
I can create objects on click or in the class itself, but how do you limit the life of the object between to button presses?
Sadly you're pretty much stuck with putting it at class scope. There is no simply way to limit the scope of an object to just a few methods within a class. If your 2 event handlers can access your Employer, then so can every other method within the class. You just have to not use it.
However, out of curiosity I managed to hack around and produce the effect you want. I did a class with 2 event handlers, one for each button, as well as a private Employer variable.
public class ButtonHandler
{
private Employer employerData;
public void button1_Click(object sender, EventArgs e)
{
employerData = "set data here";
}
public void button2_Click(object sender, EventArgs e)
{
employerData = "use / clear data here";
}
}
Then I went to my Form.Designer.cs and manually changed the button.Click event handler from the default this.btnLoadPlaylist_Click to my functions within the ButtonHandler class above. The problem with this is it gets deleted every time the Designer.CS is regenerated by Visual Studio. So the effect is possible, just not convenient with the tools we are given.

How to generate events automatically for buttons without creating manually from properties if there are 'n' number of buttons?

IDE: Visual Studio 2010
Language: c# .net
I am generating events for buttons manually from properties. But, its becoming very lengthy process if there are suppose 20 buttons doing the same task like 'Mouse Hover' and 'Mouse Leave' . So, is there a way to copy events for all the other buttons ?
You can subscribe all your buttons to same event handler:
foreach(var button in Controls.OfType<Button>())
{
button.MouseHover += Button_MouseHover; // add handler
button.MouseLeave += Button_MouseLeave;
}
In that handler you can determine which exact button raised even by casting event source to button type:
private void Button_MouseHover(object sender, EventArgs e)
{
var button = (Button)sender; // sender is one of buttons
// use button.Name
}
Code above subscribes to events of all buttons. But if you want to filter them (e.g. by name) you can add filtering:
Controls.OfType<Button>().Where(b => b.Name.StartsWith("foo"))
Buttons can all share the same event, there's no need to have a seperate event for each button if they're doing similar tasks. (The object sender parameter will give you the Control which was clicked.
IF you select all the buttons (by keeping the ctrl key pressed) in the designer, you can then easily assign 1 event to all 20 buttons
In life you will not find shortcuts for everything,
In short there is no shortcut, but yes as mentioned in other post if you have same event handler and same action to be taken then this will help you reduce your work.
You don't have to do this manually, you can add event handlers from code as well. Also, if the logic is quite similar for all the buttons then you can use single event handler for all of them. Every event handler has sender property what will be set to the button that caused event.
Simple example would be something like this:
//at first assign event handlers
button1.Click += new EventHandler(Button_Click);
button2.Click += new EventHandler(Button_Click);
//single event handler
private void Button_Click(object sender, System.EventArgs e)
{
// Add event handler code here.
Debug.WriteLine("You clicked: {0}", sender);
}

TextChanged event doesn't work.

I have a textbox in Form and i want to detect when the text has changed but the code I have found is giving me no joy.
I am probably missing something in the proporties or something you have to define before.
Here is my code:
private void tbxparkingTimesS1_TextChanged(Object sender, EventArgs e)
{
MessageBox.Show("You are in the ToolStripItem.TextChanged event.");
}
Thanks for any help with this trivial problem.
To wire the TextChanged event to a particular method inside your code do the following
Click on the TextBox inside your form
Open the properties windows (press F4 or menu View -> Property Window )
Select the event page (lightning icon)
Double click on the TextChanged property line
Insert your code inside the template build for you by Visual Studio
Have you assigned the event handler to the textbox?
Normally this will be done "behind the scenes" by Visual Studio - with the result being an additional line of code in your .designer file.
Something like:
this.tbxparkingTimesS1.TextChanged += new System.EventHandler(tbxparkingTimesS1_TextChanged);
(It['s been a while since I've done webforms - so that might be slightly off)
Double Click on Text box it will generate text change event for you.
private void tbxparkingTimesS1_TextChanged(object sender, EventArgs e)
{
// implement your code here.
}
When you double click VS will create event handler in your designer.cs file as bellow
this.tbxparkingTimesS1.TextChanged += new System.EventHandler(this.tbxparkingTimesS1_TextChanged);
You can do the same by using property window events or create event on code behind.

Categories

Resources