I have a GUI that contains 10 radio buttons and a textbox, into which the user has to make his input. The RadioButton.CheckedChanged event gets subscribed on runtime depending on the user input (textbox). So, in my case there over 50 possible methods that can subscribe to the CheckedChanged event. Ok, I can unsubscribe every single method one by one (see excerpt from my code), but isn't there are any less time consuming and more efficent way to do this? Something like for instance:
unsubscribe all methods from the CheckedChanged event at once. Or: determine the method that currently subscribes to this event und unsubscribe this method.
I was already searching for an existing solution and found this: How to remove all event handlers from an event but in my case this solution does not works. As I mentioned, in my case there radio buttons, not normal buttons.
Excerpt from my code:
public List<RadioButton> RbList
public Form1()
{
InitializeComponent();
WindowState = FormWindowState.Maximized;
RbList = new List<RadioButton>
{
radioButton1, radioButton2, radioButton3, radioButton4, radioButton5, radioButton6, radioButton7,
radioButton8, radioButton9, radioButton10
};
}
private void Unsubscribe()
{
for (int i = 0; i < RbList.Count; i++)
{
RbList.ElementAt(i).CheckedChanged -= Method1;
RbList.ElementAt(i).CheckedChanged -= Method2;
...
}
}
Additional information regarding to the asked questions:
The last subscribed method does not get unsubscribed. With the radio buttons specific PDFs gets called. In the background is still the last subscribed method as long as another method is not get subscribed. So, if the user change the input in the textbox and the input does not matched anymore so that any other method can't be subscribed, the last method ist still there and the with the method associated PDFs can be accessed and that's exactly what I want to stop. I wouldn't have the problem, if the PDFs could by only accessed by clicking on the radio button. Then I could simply make all the radio buttons unvisible/unaccessible. But this is not the case, there is another option to the user to call the PDFs, which I dont mentioned - additionally there is a second textbox and if the input in this textbox is equal to the RadioButton.text the associated radio button gets also checked and the associated PDF to this radio button gets called and this is where the problem starts.
Related
I get data from the data base then i show it in a datagrid (wpf) , the user can make quick search (filter) from a textbox after clicking on Enter.
I use this event to handle the button -Enter- click
(OnSearch - This event is spawn whenever the search button is clicked or the Enter key is pressed.)
the problem is when the user don't write anything, the event will not be launched even when he click on Enter-Button !
how can i proceed to make it work
public MainWindow()
{
InitializeComponent();
//m_txtTest is a SearchTextBox
m_txtTest.OnSearch += new RoutedEventHandler(m_txtTest_OnSearch);
}
void m_txtTest_OnSearch(object sender, RoutedEventArgs e)
{
//to get the entered string
SearchEventArgs searchArgs = e as SearchEventArgs;
....
....
....
....
}
So when your user types something in and presses enter it is the textbox handling the Event.
When they don't type anything though the textbox doesn't have focus and cant handle the event.
What I would do is create an event for searching on the window or grid.
Somthing like this
this.OnPreviewKeyDown += new OnPreviewKeyDownEvent;
http://msdn.microsoft.com/en-us/library/ms748948.aspx
You can think of it like this
Window has focus
->Grid has focus
-->textbox has focus
What ever the last thing that has focus (or the most inner element, think of it like a cake) is will be the thing that sees the event first. If you have that event registered for that UI element it will handle it.
The textbox isn't focused so it wont see the event
In my C# Windows form MyForm I have some TextBoxes.
In these TextBoxes, we have to detect if the TextChanged event occurs,
if there're changes in these TextBoxes and click close button, it will ask if we want to cancel the changes when we close the form.
However, when I run the MyForm, I can't know text change for each textbox caused by user typing for without textchanged event property.
But I am thinking how do I make the TextBox's TextChanged know the
event cuased by user typing without textchanged event?
Thanks for help.
Sorry for my English.
There is no (decent) way of knowing what's typed without a TextChanged or a Leave event.
You need to use one of these events to get the typed content. Doing this enable you to set a "dirty" flag that you can check at close and clear at save.
Comparing old and new value has no point without this cause you won't know what the value should be set to without knowing something was changed.
With one exception: If your original data came from a database you could use the compare old/new approach as you would compare the textbox of that which came from the database.
Update:
Addressing this comment:
"Because Myform have many textboxes and if no text change ,this will
not display the confirm message.If I catch textchanged event for all
textboxes, this is so many code."
You can use a common handler to collect the changes for all textboxes in one single method. Use the sender object (cast it to Textbox) to identify which textbox is changed, if needed, or simply set a dirty flag for whatever textbox has a change.
bool isDirty = false;
void SomeInitMethod() //ie. Form_Load
{
textbox1.TextChanged += new EventHandler(DirtyTextChange);
textbox2.TextChanged += new EventHandler(DirtyTextChange);
textbox3.TextChanged += new EventHandler(DirtyTextChange);
//...etc
}
void DirtyTextChange(object sender, EventArgs e)
{
isDirty = true;
}
void Form1_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
if (isDirty) {
//ask user
}
}
// to clear
void Save()
{
SaveMyDataMethod();
isDirty = false;
}
If you have a lot of textboxes in the form loop through the forms control collection and use typeof to address the textboxes. If you have textboxes requiring different approaches use the Tag property of the textbox to distinguish.
A possible approach is using the timer. Have a timer that ticks every 1000 ms (say) and checks the textBox.Text.
A second possible approach is overriding WndProc for the textbox (by inheriting a new class) and handling the change text message. This would be the same as overriding TextBox.OnTextChanged.
Why dont you use a timer which will check after a few intervals if the textboxes do contain any text
My UserControl contains various controls. I made an event handler for its click event. I want the event handler to fire / be called when the user clicks anywhere on my user control.
This is the method I use to add my UserControl to my WinForms application.
private void addContact(some parameters here)
{
//This is my usercontrol
contactsListItem.contactsListItem contact = new contactsListItem.contactsListItem();
//
//some codes here
//
//Adding an event handler for the click event
contact.Click += new EventHandler(contact_Click);
//Adding the UserControl to my application
flowLayoutPanel_contactsList.Controls.Add(contact);
}
The contact_Click(...) event handler should change the background of my UserControl. I have tried stepping into the code to see if the event handler fires and I found out that it doesn't fire no matter where I click on my UserControl.
I have searched through the internet. I encountered terms like delegate, subscribers and publishers.
What should I do to make the event handler for my UserControl's click event to fire?
What is the structure of your user control? Click events are not bubbled in WindForms, hence if you are clicking on a control WITHIN your user control, the latter won't fire any Click event.
EDIT:
The simplest solution is to manually bubble the event from each child by attaching a handler in your user control:
child1.Click += new EventHandler(child_Click);
child2.Click += new EventHandler(child_Click);
child3.Click += new EventHandler(child_Click);
and inside child_Click fire off your Click event:
this.OnClick(e);
You seem to be on the right track however it is not clear what your contact here is. Typically you use delegates (essentially pointers to functions) for methods that have arguments to be passed:
if (bDeleteRdClick)
DeleteRD.Click -= delegate { DeleteRDClick(this.Object); };
DeleteRD.Click += delegate { DeleteRDClick(this.Object); };
where you are sure to remove pre-existing delegates, otherwise they will 'stack-up', firing multiple methods when not required.
For the method above, using an EventHandler seems to me to be the right approach, but as I state above, a check on whether contact is of the correct type would not go unmissed:
if (this.contact.GetType() == typeof(RibbonButton))
{
RibbonButton Rb = (RibbonButton)contact;
Rb.Click += new EventHandler(contact_Click);
}
I hope this is of some help.
E.g. instead of having a button to initiate the method, the method automatically happens without any user interaction - automatically.
private void button13_Click(object sender, EventArgs e)
{
try
{
ServiceController sc = new ServiceController();
sc.ServiceName = "Spooler";
if (sc.Status.ToString().ToLower() == "stopped")
{
serviceStatusLabel.Text = "Installed but stopped";
}
if (sc.Status.ToString().ToLower() == "running")
{
serviceStatusLabel.Text = "Installed and started";
}
}
catch
{
serviceStatusLabel.Text = "Service not installed";
}
}
I just want the Label object to show the service status when the form is loaded up, without using a button
EDIT: Given your comment, are you actually after the Form.Load event? It sounds like it. Any event handlers subscribed to that event will be executed "when the form is displayed for the first time".
(The confusing thing is that your title talks about "On-Load" of an object whereas it sounds like you really want the method to be called when the form is loaded.)
It's not really clear what you mean by "when its output on the form" but you might want to look at the TextChanged and VisibleChanged events. That's if you want something to happen when the label is altered.
If you're looking for when the service status is altered, it doesn't look like there's an event raised for that, I'm afraid. Note that it would be much cleaner to switch on the enum value rather than to convert it to a string, lower it, and then compare that with hard-coded constants.
... Do I get your question correctly?
You want a piece of code to be executed when an object or the form is loaded?
Well that's easy :p
Click on your object (or form) in the designer, in the properties dock, click the lightning bolt icon, go to the Load or Show event, and double-click the box.
A new piece of code should now be created in the code view, something like this:
private void Object_Load(blabla) handles Object.Load
{
}
Whatever code is in that event will be executed when the object is loaded or shown.
If you create a handler for the Load event, it will run when the form gets loaded.
An application I'm writting in silverlight/c# consists of 13 permanent buttons that when clicked perform a simple navigation to another page.
The problem is my code behind has 13 different event handlers(alot of code) for a nearly identical purpose.
Is there a way to detect which button was pressed so that a single event handler gets fired, and a simple if statement within could determine which page to go to?
yes: you can use the same method for all buttons, and use the parameter "sender" as "sender.Name" to get the name of the pressed button.
In the designer code of your program, tack on the same event handler for all 13 buttons (look for the code that has += and put the same event handler for all of them).
Notice that the event handler has an object (s) parameter. You can use this parameter as follows:
if(s.Name = "Button1") {//button 1 stuff}
else if (s.Name = "Button2") {button 2 stuff}
etc..
EDIT: should have been s.Name = "Button1, 2, 3, etc.."
Test the sender parameter of the button click event handler - you'll be able to test which button was the sender.
Use a Dictionary using 'sender' as key. The 'value' could be the page to navigate to.
If you have lots of code in your event handler you should break that out to a separate method anyway and send the button specific parameters to that method.
But you can still have one event handler if you look at the sender argument.