Using sender to determine what button is pressed in ListView - c#

I have a ListView that has Update and Cancel buttons. Both of these buttons have a CommandName of Cancel, so they fire the same ListView event handler (ListView_ItemCanceling).
Inside this event handle I execute my stored procedures. The issue I am having is since both buttons fire the same event handler they both update. Even if there are no changes being made.
I would like to try to determine the button that has fired the event at the start of the event handler (possibly using sender?), but I cannot figure out how to do this.
This is what I was currently trying to do in the ListView_ItemCancelling event handler:
Button newButton = (Button)sender;
if(newButton.Text == "Cancel")
{
Console.Write("this worked");
}
When I execute this code I get an error message telling me that I cannot convert the sender object from ListView object to a Button object.
Any help will be greatly appreciated!

You can define to command names for each button to detect the which one is click for example:
define the first as "Cancel1" and the other "Cancel2"
and in the code you can check like that:
if(CommandName == "Cancel1")
{
// do some thing
}
else if(CommandName == "Cancel2")
{
// do other staff
}
or if both at doing the same job but you need to determine the sender
if(CommandName == "Cancel1" || CommandName == "Cancel2")
{
// do some thing common
}
if(CommandName == "Cancel1")
{
// do some thing if button 1 clicked
}
if(CommandName == "Cancel2")
{
// do some thing if button 2 clicked
}

I came to the answer with help from #paqogomez. He suggested I use the ItemCommand event handler for the ListView to get the button that is being clicked for the listview.
Inside the ItemCommand event handler I checked them command argument and used the appropriate code thereafter.
protected void LV_Tickets_ItemCommand(object sender, ListViewCommandEventArgs e)
{
if(e.CommandName == "Update")
{
//code here
}
}

The sender seems to be your ListView, not Button. Try using Button_OnClick event instead of ListView_ItemCancelling.
Or try doing some reseach on ListView_ItemCancelling, such as using ListViewCancelEventArgs e parameter, maybe it can help you in this situation. You can read more about it on MSDN.

Related

MessageBox appearing twice on clickevent

I have this code here,
When I click on the Modify button, I got a message box. After I click on the x button to close it, the message box appears again. I really don't know why this happens.
private void dataGridUsers_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
if (dataGridUsers.Columns[e.ColumnIndex] is DataGridViewButtonColumn &&
e.RowIndex >= -1 && dataGridUsers.Columns[e.ColumnIndex].Name == "Modify")
{
MessageBox.Show("");
}
}
My Guess: You are re-assigning the event handler again and again somewhere in your code. That is the problem you are getting the message box triggered twice.
dataGridUsers.CellContentClick += new DataGridViewCellEventHandler(dataGridUsers_CellContentClick);
To fix the issue, you need to assign the above event handler only in the function where you need.

How to know what Item of a MenuStrip is being clicked?

I'm using c# and I have a MenuStrip control but I don't know how to identify what item of it is being clicked. For example, I used to group all click(buttons) events in one or two methods like "btnActions_click()" or "btnNavigation_click()". Then, inside of the method I identify the button clicked by parsing the sender as a button and placing it on a button var, then I check if the name of that button var is equal to "btnFoo" or "btnBar".
So, in this case, how could I know what item of the MenuStrip controls is being clicked in order to group all click events in only one method?
I apologyze if my english isn't correct. If you can't understand me I can try again or post some code.
Thanks.
Edit: I didn't post any code because I thought that there was not necessary in this question but someone suggest me to do it, so I'll do it. Here's an example of what I do to identify what button has been clicked.
private void btnNavegation_Click(object sender, EventArgs e)
{
Button btn = sender as Button;
if (btn.Name == "btnNext")
//go to next item of the list
else if (btn.Name == "btnPrevious")
//go to previous item of the list
}
I think that you need to subscribe to ItemClicked event (inherited from ToolStrip), instead of subscribing to Click event (inherited from Control).
The example provided by Microsoft's documentation show you how to determine the clicked item on each call (ToolStripItemClickedEventArgs::ClickedItem):
private void ToolStrip1_ItemClicked(Object sender, ToolStripItemClickedEventArgs e)
{
System.Text.StringBuilder messageBoxCS = new System.Text.StringBuilder();
messageBoxCS.AppendFormat("{0} = {1}", "ClickedItem", e.ClickedItem );
messageBoxCS.AppendLine();
MessageBox.Show(messageBoxCS.ToString(), "ItemClicked Event" );
}

Radio button checked changed event fires twice

Please read my question its not a duplicate one.
I've three radio buttons on windows form and all these buttons have common 'CheckedChanged' event associated. When I click any of these radio buttons, it triggers the 'CheckedChanged' event twice.
Here is my code:
private void radioButtons_CheckedChanged(object sender, EventArgs e)
{
//My Code
}
I inserted the breakpoint and the whole code within this event iterates twice.
Please tell me why it is behaving like this?
As the other answerers rightly say, the event is fired twice because whenever one RadioButton within a group is checked another will be unchecked - therefore the checked changed event will fire twice.
To only do any work within this event for the RadioButton which has just been selected you can look at the sender object, doing something like this:
void radioButtons_CheckedChanged(object sender, EventArgs e)
{
RadioButton rb = sender as RadioButton;
if (rb != null)
{
if (rb.Checked)
{
// Only one radio button will be checked
Console.WriteLine("Changed: " + rb.Name);
}
}
}
To avoid it, just check if radioButton is checked
for example:
private void radioButton1_CheckedChanged(object sender, EventArgs e)
{
if (radioButton1.Checked)
//your code
}
CheckedChanged is raised whenever the Checked property changes. If you select a RadioButton then the previously selected RadioButton is unchecked (fired CheckedChanged), and then the new RadioButton is checked (fired CheckedChanged).
It's triggering once for the radio button transition from checked to unchecked, and again for the radio button transitioning from unchecked to checked (i.e. any change in checked state triggers the event)
You could set the AutoCheck property true for each RadioButton then catch the Click event instead of the CheckChanged event. This would ensure that only one event is fired, and the logic in the handler can cast the sender to type RadioButton if needed to process the click. Often the cast can be avoided if the handler logic is simple. Here is an example which handles three controls, rbTextNumeric, rbTextFixed and rbTextFromFile:
private void rbText_Click(object sender, EventArgs e)
{
flowLayoutPanelTextNumeric.Enabled = rbTextNumeric.Checked;
txtBoxTextFixed.Enabled = rbTextFixed.Checked;
flowLayoutPanelTextFromFile.Enabled = rbTextFromFile.Checked;
}
{
public partial class Form3 : Form
{
public Form3()
{
InitializeComponent();
}
int click = 0;
private void radioButton1_Click(object sender, EventArgs e)
{
click++;
if (click %2==1)
{
radioButton1.Checked = true;
}
if (click %2==0)
{
radioButton1.Checked = false;
}
if (radioButton1.Checked==true)
{
label1.Text = "Cheked";
}
if (radioButton1.Checked==false)
{
label1.Text = "Uncheked";
}
}
}
}
The other answers are correct but miss the reason for the underlying problem.
When a radio button is checked the first event sent is the change from the unchecked item
however if you check its state by its control name you will still see its old checked status because the form has not been updated yet. To see its true status you need to cast the sender object.
This allows you to perform any actions relating to the condition which is being deselected should you need to do so.
In the not uncommon scenario below multiple radio buttons are sent to the same handler event.
Simply checking the state of the sender for checked will not work here as we need to perform different actions depending on which radio button has been pressed.
So first we ignore any sender that has just been unchecked.
then we identify the checked sender by control name to process the correct action.
private void ModeChangedExample(object sender, EventArgs e)
{
// multiple radio buttons come here
// We only want to process the checked item.
// if you need to something based on the item which was just unchecked don't use this technique.
// The state of the sender has not been updated yet in the form.
// so checking against rdo_A check state will still show it as checked even if it has just been unchecked
// only the sender variable is up to date at this point.
// To prevent processing the item which has just been uncheked
RadioButton RD = sender as RadioButton;
if (RD.Checked == false) return;
if (rdo_A.Name == RD.Name)
{
//Do stuff
}
if (rdo_B..Name == RD.Name)
{
// Do other stuff
}
if (rdo_C.Name == RD.Name)
{
// Do something else
}
}
This problem of double checking happens when there is a series of RadioButton Clicks in succession.I had this same problem.The last click will give two results.To overcome this i made a dummy click in the end.The double click stopped.Try this method.
Venkatraman

Set focus to element

There are a button and a textbox. I added a "KeyDown" event to textbox so that when "enter" is pressed button gets clicked. Good, then I tried to give focus to textbox again but failed. In the code below I tried three ways but neither is working.
private void txt_addRemove_KeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.Return)
{
btn_BC_add.RaiseEvent(new RoutedEventArgs(Button.ClickEvent));
// 1.way
// IInputElement focusedElement = FocusManager.GetFocusedElement(txt_addRemove);
// 2.way
// Keyboard.Focus(txt_addRemove);
// 3.way
// txt_addRemove.Focus();
}
}
Add this
if (!textBox1.Focus())
{
textBox1.Focus();
}
What this does:
1. We check if the textbox is NOT focused.
2. If it is not focused, focus the control.
EDIT: How about this:
btn_BC_add.PerformClick()
Try focusing the textbox after the event handler is finished using:
Dispatcher.Invoke(() => { txt_addRemove.Focus(); })
couldnt you also try changing the focus from the button event handler? this might not be desirable if you dont want the focus to be on your textbox after a normal click of the button, but it should work.
Im guessing that your button click is generating a post back before the focus can be changed

Pressing Enter on TextBox in Silverlight

I am working on a silverlight app that you need to enter information into a textbox and then just hit enter. Well there is no onclick event, that I could find, so what I did was use the onkeypressup event and check if it was the enter key that was pressed if so do "blah".
It just feels like there is a better way to do this. So the question is, is there?
I thinks that's the way to catch Key.Enter.
Also, you're code will be more readable if you use the KeyDown event instead of the KeyUp event.
If you only care about catching Key.Enter for a single control then your approach is correct.
You can also catch the Key.Enter for a group of related controls by using the KeyDown event of their container ("Event Bubbling").
Do you really want it in the textbox? I would put a onkeyup handler on the container (e.g. Grid, Canvas) to press the button anywhere on the form.
This will work if you use want to bind the Command property instead of using the Click event. Start by creating an event handler for Click (see below) and then in the KeyUp do:
private void MyTextBox_KeyUp(object sender, KeyEventArgs e)
{
if (e.Key == Key.Enter) SomeButton_Click(this, null);
}
private void SomeButton_Click(object sender, RoutedEventArgs e)
{
ICommand cmd = SomeButton.Command;
if (cmd.CanExecute(null))
{
cmd.Execute(null);
}
}
I use the following implementation when using the command pattern:
private void MyTextBox_KeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.Enter)
{
BindingExpression b = MyTextBox.GetBindingExpression(TextBox.TextProperty);
if (b != null)
b.UpdateSource();
ICommand cmd = SomeButton.Command;
if (cmd.CanExecute(null))
cmd.Execute(null);
}
}
When you press Enter, the data source of the textbox is not updated and the command uses an old value. Therefore you have to call UpdateSource before executing the command.
Of course you can catch the event on a higher level than the textbox.
Well, Im preaty new to Silverlight and I created HitEnter beahaviour for button which have one DependencyProperty Button.
And I manulay wire up Button and Behavior (in code behind) and then when enter is hit I inovke the command on the button.

Categories

Resources