Add button click event with the menu item instead of navigate url - c#

I'm trying to create dynamic menuitem driven from the database in ASP.NET. After creating the menuitem, I want to bind them with the button click event for each of the menuitem passing a parameter instead of NavigateUrl option.
MenuItem menuItem = new MenuItem
{
Value = row["MenuId"].ToString(),
Text = row["Title"].ToString(),
//NavigateUrl = row["Url"].ToString(),
//some logic to bind to onclick event
};

You can't add the click event to each menuItem you have to add it to the Menu and in the click event you verify which menuItem was clicked.
So make sure you add the MenuItemClick to your menu like this :
menu.MenuItemClick += Menu_MenuItemClick;
Then you can have a function that will create the MenuItems and in the event handler you can have something like this to verify which one was selected :
private void Menu_MenuItemClick(object sender, MenuEventArgs e)
{
if(e.Item.Text == "text1")
{
//Do what you need
}
else if(e.Item.Text == "text2")
{
//Do what you need
}
}

I resolved the issue. I had to add OnMenuItemClick event to Menu such as OnMenuItemClick="Menu_OnClick".Based on the click, I checked
protected void Menu_OnClick(object sender, MenuEventArgs e)
{
string value = e.Item.Value.ToString();
//OR
// string value = e.Item.Text.ToString();
//some logic
}

Related

WPF ContextMenu Closed Event, how to differentiate closing method

Inside my Canvas I have a ContextMenu with the expected functionality of closing when you select an option in the menu, or when you click outside of it. However I want my program to respond differently based on which of those methods was used to close the ContextMenu. From what I can tell the Closed Event on the ContextMenu fires in both scenarios. Is there any way to make that distinction?
Could you please explain more about problem?
I think it's obvious that you have to scenario. 1: click on ContexMenu options you created which will invoke an event fore sure and clicking outside it which will cancel the context Menu. by the way I made an answer base on my understanding of you problem. If I got it wrong please tell me.
The bellow code is Just a demo code , The logic Behind it is important.
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
// Windows Load event
private void MainWindow_OnLoaded(object sender, RoutedEventArgs e)
{
// Very Important Because by default it's null
this.ContextMenu = new ContextMenu();
// Making 3 sample Menu Item for ContextMenu
MenuItem firstMenuItem = new MenuItem()
{
Header = "FirsMenu"
};
//1st of three way to give event to Controls.
// Giving click Event to firstMenuItem to seprate it's click behavior from Other Menu Items
firstMenuItem.Click += (s, e) =>
{
// if Tag be Null on context Menu closing it's get that non of item selected so the click must be out side or lost focused
this.ContextMenu.Tag = 1;
MessageBox.Show("First Menu Clicked");
};
MenuItem secondMenuItem = new MenuItem()
{
Header = "SecondMenu"
};
//2nd of three way to give event to Controls.
// Giving click Event to secondMenuItem to seprate it's click behavior from Other Menu Items
secondMenuItem.Click += delegate
{
// if Tag be Null on context Menu closing it's get that non of item selected so the click must be out side or lost focused
this.ContextMenu.Tag = 1;
MessageBox.Show("Second Menu Clicked");
};
MenuItem thirdMenuItem = new MenuItem()
{
Header = "ThirdMenu"
};
//3rd of three way to give event to Controls.
// Giving click Event to thirdMenuItem to seprate it's click behavior from Other Menu Items
thirdMenuItem.Click += ThirdMenuOnClick;
this.ContextMenu.Items.Add(firstMenuItem);
this.ContextMenu.Items.Add(secondMenuItem);
this.ContextMenu.Items.Add(thirdMenuItem);
this.ContextMenu.Closed += ContextMenuOnClosed;
}
private void ThirdMenuOnClick(object sender, RoutedEventArgs e)
{
// if Tag be Null on context Menu closing it's get that non of item selected so the click must be out side or lost focused
this.ContextMenu.Tag = 1;
MessageBox.Show("Third Menu Clicked");
}
// Event for opening contextmenu on right mouse button click
private void MainWindow_OnMouseRightButtonDown(object sender, MouseButtonEventArgs e)
{
this.ContextMenu.IsOpen = true;
}
private void ContextMenuOnClosed(object sender, RoutedEventArgs e)
{
// if null means click must be out side or lost focused
if (((ContextMenu)sender).Tag == null)
{
MessageBox.Show("You Clicked OutSide");
}
// very Importnt code , because it will reset the context menu tag logically
((ContextMenu)sender).Tag = null;
}
}
Wish You bests, Heydar.

Event that would listen to any label click in form

Well, I'm making a chess game that's based on labels. I need to listen for label click, so when user clicks on an label, I get the name of label he clicked. I know I can do it for each label, but is there an universal event that would help me do the same thing for all of them in one event / loop?
Suppose you have taken 64 labels.
In windows form, on click event of Label1 you will write following code:
private void Label1_Click(object sender, EventArgs e)
{
var label = sender as Label;
MessageBox.Show(label.Name);
}
For remaining 63 Lables, In Design view, select all 63 lables by using Ctrl key --> Go to Property window --> Under Event option select Click option --> From dropdownlist select 'Label1_Click' option.
Just finish & run the application.
You can use a Panel
structure to group your labels and then call the desired event on that Panel, so it will trigger whenever you click one of it's elements.
Another solution would be to identify your label with the coordinates of the mouse click (the amount of code that requires depends how you placed them of course).
Like mentioned in the comments you can assign one event to all...
List<Label> lbls = this.Controls.OfType<Label>().ToList();
foreach (var lbl in lbls)
{
lbl.Click += lbl_Click;
}
void lbl_Click(object sender, EventArgs e)
{
Label lbl = sender as Label;
MessageBox.Show(lbl.Name);
}
You can assign these methods to every label you need to manage in the VS form designer (you go to events of controls, at the click line and select the method in the list instead of double click on it):
private void Label_Click(object sender, EventArgs e)
{
var nameLabel = ( sender as Label )?.Name ?? "Error";
// ...
}
private void Label_Enter(object sender, EventArgs e)
{
( sender as Label ).Cursor = Cursors.Hand;
}
private void Label_Leave(object sender, EventArgs e)
{
( sender as Label ).Cursor = Cursors.Default;
}
Cursor change added for convenience if you want.
If you want to dynamically assign events, you can use the #caner answer, and you can group all in a panel to parse Panel.Controls and assign event.
You can create a custom label class that inherits from Label. You can then subscribe to the Click event of the base class and do your thing.
public class MyLabel : Label
{
public MyLabel()
: base()
{
Click += ProcessClickEvent;
}
private void ProcessClickEvent(object sender, System.EventArgs e)
{
// Do what you want to do
}
}

how to retrieve text of buttons clicked in windows form with one single method

I have a windows form application with multiple buttons. I need to retrieve the text property of any button clicked in order to create a query to the database. the only way I know is to create a button click event and cast the sender as button then do a switch case for each button Id which seems very hectic since I probably will have more than 100 buttons in the entire application. So my question is there a generic key press method I can create which can retrieve the text property of any button pressed/clicked on the form? Please excuse me if the question is not very clear. Any help will be appreciate
Use a single click event handler for all similar kind of buttons. This way there will be click event subscribed for every button but only one method which will be executed for all buttons. You can determine which button was pressed as follows.
Using sender object as follows;
private void button_Click(object sender, EventArgs e)
{
var buttonText = ((Button)sender).Text;
//Query using buttonText
}
Update:
Above answer will still require you to subscribe click event for each button. If you don't want that then have a look at following approach;
You could use (ClickTransparentButton or) disable (Enabled=false) all these buttons and add click event on parent Form. Once you get click event you can get button which was clicked as follows;
private void Form1_Click(object sender, EventArgs e)
{
var p = PointToClient(Cursor.Position);
var control = GetChildAtPoint(p);
if(control is Button)
{
var buttonText = ((Button)control).Text;
//Query using buttonText
}
}
But this has few disadvantages such as, you will not be able to operate these buttons using keyboard.
and more...
Create some function as buttons click handler:
private void buttonClickHandler(object sender, EventArgs e)
{
string buttonName = (sender as Button).Text;
}
2A. Connect Click event of every button to this handler.
2B. To automate connection of button click handler use something like that:
private void connectButtonsHandlers()
{
foreach(var c in this.Controls)
{
if(c is Button)
{
(c as Button).Click += buttonClickHandler;
}
}
}
Add this code to form constructor to perform connection at program start.

Event handler for groupBox with radioButtons in C#

I have some radionButtons in groupBox and I need to do action what I could call "one of radiobuttons.checked changed" or find out from radiobutton what index is changed.
I've tryed to find it in list of events but I couldn't find the right one.
Edit:
To make it more clear: I need to know if exist some handel for what I'll write handler method for the goupBox not for single radioButton. I know how to use radiButton.checkedChanged, but it's not what I'm finding ..
Or differently I need to know what options have the groupBox in monitoring what happens inside this groupBox - I mean only the handlers for the groupBox. I'm finding handler "in the group box is something happens" or simimilar if any exist.
It's in WFA (Windows Presentation Application) in Visual studio 2012.
I think what you want to do is wire up all of the RadioButtons' CheckedChanged event to the same handler.
public Form1()
{
radioButton1.CheckedChanged += new EventHandler(radioButtons_CheckedChanged);
radioButton2.CheckedChanged += new EventHandler(radioButtons_CheckedChanged);
// ...
}
private void radioButtons_CheckedChanged (object sender, EventArgs e)
{
RadioButton radioButton = sender as RadioButton;
if (radioButton1.Checked)
{
// Do stuff
}
else if (radioButton2.Checked)
{
// Do other stuff
}
}
Nothing built in for that as far as I'm aware.
Set the tag property to some sort of indicator (0 to n) will do.
Add a CheckChangedHandler
Point all the buttons CheckChanged events at it.
then something like.
private void radioButtons_CheckedChanged (object sender, EventArgs e)
{
RadioButton radioButton = sender as RadioButton;
int buttonid = (int)radioButton.Tag;
switch (buttonid)
{
case 0 : // do something; break
}
}
If you've got a few of these I'd look at a radiogroup component.
I had the same problem: a group box named Button Type (gbxButtonType) with 6 radio buttons and another group box named Icon Type (gbxIconType) with 8 radio button. When the user selected one radio button from each group box, a MessageBox will appear with the selection applied after clicking the DisplayButton. My problem was that the group boxes didn't have a CheckedChanged event. The solution of AKN worked perfectly:
public Form1()
{
InitializeComponent();
for (int i = 0; i < gbxButtonType.Controls.Count; i++)
{
RadioButton rdb = (RadioButton)gbxButtonType.Controls[i];
rdb.CheckedChanged += new System.EventHandler(gbxButtonType_CheckedChanged);
}
for (int i = 0; i < gbxIconType.Controls.Count; i++)
{
RadioButton rdb = (RadioButton)gbxIconType.Controls[i];
rdb.CheckedChanged += new System.EventHandler(gbxIconType_CheckedChanged);
}
}
private void gbxIconType_CheckedChanged(object sender, EventArgs e)
{
if (sender == rdbAsterisk)
{
iconType = MessageBoxIcon.Asterisk;
}
else if (sender == rdbError)
{
iconType = MessageBoxIcon.Error;
}
...
else
{
iconType = MessageBoxIcon.Warning;
}
}
Similar to davenewza's answer (and likely should have been a comment, but I have insufficient reputation), but with the event firing only once for the entire group of radio buttons.
public Form1()
{
// Add a "CheckedChanged" event handler for each radio button.
// Ensure that all radio buttons are in the same groupbox control.
radioButton1.CheckedChanged += new EventHandler(radioButtons_CheckedChanged);
radioButton2.CheckedChanged += new EventHandler(radioButtons_CheckedChanged);
}
private void radioButtons_CheckedChanged (object sender, EventArgs e)
{
// Do stuff only if the radio button is checked (or the action will run twice).
if (((RadioButton)sender).Checked)
{
if (((RadioButton)sender) == radioButton1)
{
// Do stuff
}
else if (((RadioButton)sender) == radioButton2)
{
// Do other stuff
}
}
}
Groupbox will limit only one radio button checked
So Setp1: you can assign one "CheckedChanged" event handler to all you radio button
private void initRadio()
{
radio_button1.CheckedChanged += Radio_show_CheckedChanged;
radio_button2.CheckedChanged +=Radio_show_CheckedChanged;
}
And Setp2: implement this event handler like this (Filter by Radio Button's Text)
private void Radio_show_CheckedChanged(object sender, EventArgs e)
{
RadioButton radioButton = sender as RadioButton;
if (radioButton.Checked == true) { //limited only checked button do function
switch (radioButton.Text)
{
case "name1":
// do your stuff ...
break;
case "name2":
// do your stuff ...
break;
}
}
}
System.Windows.Forms.RadioButton.CheckedChanged
is the event you need
So do something like:
public Form1()
{
InitializeComponent();
this.radioButton1.CheckedChanged += new EventHandler(radioButton1_CheckedChanged);
}
private void radioButton1_CheckedChanged(object sender, EventArgs e)
{
// your action
}
I think your want to handle the selection of some radio buttons inside a groupbox using the groupbox control itself.
May be you wanted this basically to avoid code repetition.
(i.e) adding check change event for all the radio button in the designer which may be tedious when there are more control.
Since its already present under a group, why not use the group control object to manipulate controls with-in it and set the events.
This is how I understood your problem and hence the solution as indicated below.
Set a common handler for all radio button control in the group box
for (int i = 0; i < groupBox.Controls.Count; i++)
{
RadioButton rb = (RadioButton)groupBox.Controls[i];
rb.CheckedChanged += new System.EventHandler(evntHandler);
}
Inside the handler, you can determine which button was changed as indicated by others and do the necessary action.
//Here you go courtesy of Jock Frank Halliday
//^subscribe events to radio button check changed
private void seriesTxtBxEvent()
{
//Show txtBx
this.radBtn_RoomSeries.CheckedChanged += new EventHandler(showSeriesTxtBx_Event);
//Hide txtBx
this.radBtn_RoomNumber.CheckedChanged += new EventHandler(hideSeriesTxtBx_Event);
this.radBtn_RoomName.CheckedChanged += new EventHandler(hideSeriesTxtBx_Event);
this.radBtn_RoomLevel.CheckedChanged += new EventHandler(hideSeriesTxtBx_Event);
this.radBtn_RoomDep.CheckedChanged += new EventHandler(hideSeriesTxtBx_Event);
}
private void hideSeriesTxtBx_Event(object sender, EventArgs e)
{
tbx_SheetSeries.Visible = false;
}
private void showSeriesTxtBx_Event(object sender, EventArgs e)
{
tbx_SheetSeries.Visible = true;
}
//Form Start
void MainFormLoad(object sender, EventArgs e)
{
Control.ControlCollection locais = groupBoxLocalização.Controls;
foreach (CheckBox chkBox in locais)
{
chkBox.MouseUp += chkBoxLocais_MouseUp;
}
}
// Event
void chkBoxLocais_MouseUp(object sender, MouseEventArgs e)
{
//Tratar individualmente
CheckBox chk = (CheckBox)sender;
//ou para tratar todos objetos de uma vez
Control.ControlCollection locais = groupBoxLocalização.Controls;
foreach (CheckBox chkBox in locais) {
//chkBox....
}
}
You can maybe do it with Timer, but that's just bad for optimalization, the easy solution is that for every radiobutton you simply add only one function as ChekedChanged event.
Create a Checked event by double clicking on any of the radio buttons, copy the name of the method that Visual Studio creates for the event
Go to all radio buttons and change the event to the copied one from Properties Explorer > Events Section
In the generated method use the following code. This would fire event for all radio buttons but only "Do your thing" once
Code:
private void radioButtons_CheckedChanged (object sender, EventArgs e)
{
RadioButton rb = sender as RadioButton;
if (rb.Checked == false) return;
// Do your thing
}
Create Event Checked_Changed on one radio button from Designer Events list.
Add same event to each radio Button from dropdown in front of Checked_Changed
event of each radio
inside checked changed event use
private void CheckedChanged(object sender,EventArgs e)
{
var radio = groupBox.Controls.OfType<RadioButton>
().FirstOrDefault(r => r.Checked).Name;
}
you can get which radio is active now.

Which button pressed in flowlayoutpanel?

For my current project I am adding an variable amount of usercontrols : ucTask to my flowlayoutpanel : flpTasks
foreach (task t in tasks)
{
ucTask uct = new ucTask();
uct.id = t.task_id;
uct.date= t.date.ToString();
uct.btnNaam = t.task_id.ToString();
uct.OnButtonclick += new EventHandler(uct_OnButtonclick);
flpTasks.Controls.Add(uct);
}
Now I will have a couple of those usercontrols in the flowlayoutpanel, and I want to fire an event when I press that button. With the EventHandler I can fire an event, but I need to fire a different event for a different button.
void uco_OnButtonclick(object sender, EventArgs e)
{
lblStatus.Text = "TEST";
}
I don't know how to know which button (or usercontrol) I pressed. And I'm out of ideas, any suggestions?
Thanks,
Thomas
Sender of event is actually one of buttons. When you cast sender to Button type, you can access any of Buttons properties and determine which button was pressed:
void uco_OnButtonclick(object sender, EventArgs e)
{
Button button = sender as Button;
if (button == null)
return;
lblStatus.Text = button.Name;
}
UPDATE: after reading your question once again, I get that ucTask is actually UserControl, which rises event when button inside it was clicked.
So, first is naming. Good style for class names in c# is PascalCase. E.g. for task user control good name will be TaskControl. Next goes event naming. It's common to name events as EventName(-ing, -ed). If you want to raise event, then good style is protected method OnEventName(-int, -ed). And another remark - when you writing user controls, you are free to use business terms to name your events. E.g. TaskCreated, TaskChanged. And you also can pass any parameters to your event by creating custom EventArgs.
So, for your user control:
public class TaskChangedEventArgs : EventArgs
{
public TaskChangedEventArgs(int taskId)
{
TaskId = taskId;
}
public int TaskId { get; private set; }
}
public class TaskControl : UserControl
{
public event EventHandler<TaskChangedEventArgs> TaskChanged;
// raise it inside button click event handler
protected void OnTaskChanged(int taskId)
{
if (TaskChanged != null)
TaskChanged(this, new TaskChangedEventArgs(taskId));
}
}
When you use your user control, just subscribe to its TaskChanged event:
uct.TaskChanged += new EventHandler<TaskChangedEventArgs>(uct_TaskChanged);
And all parameters, that you passed via event argument will be available in that event handler:
void uco_TaskChanged(object sender, TaskChangedEventArgs e)
{
lblStatus.Text = e.TaskId.ToString();
}
Well, the sender should be the user control right? Then you can cast and determine the item through ucTask.id.
void uco_OnButtonclick(object sender, EventArgs e)
{
ucTask uc = sender as ucTask;
lblStatus.Text = uc.id.ToString();
}
This presumes that the OnButtonclick event of the user control sends a reference to the user control and not a reference to the pressed button as the sender of the event.

Categories

Resources