I have 40 buttons in a application that I need custom hovers that will show in a status field. I have made a function for adding a certain message and one to remove, so upon a hover, it calls the function, and same with leaving the button.
I want 40 different messages and one way of doing that is to check which button is being hovered over by the mouse.
if(button1.hovered == true){
string message = "scenario1";
}
elseif(button2.hovered == true){
scenario2...etc
}
Is there a way to check if hovered? and check it in a if statement?
ive decided to add more info so it might be easier to get my point.
add message to listview when mouse hoover.
void messAdd(object sender, EventArgs e)
{
string now = DateTime.Now.ToString("M/d/yyyy") + " - " + DateTime.Now.ToString("HH:mm:ss tt");
string message = "message 1";
found = false;
ListViewItem item = new ListViewItem(message);
foreach (ListViewItem z in listView1.Items)
{
if (z.Text == message)
{ found = true; }
}
if (found == false)
{
item.SubItems.Add(now.ToString());
listView1.Items.Add(item);
listView1.EnsureVisible(item.Index);
}
else
{
DeleteIfNecessary(message);
}
}
delete message from listbox when mouse leave:
void messdel(object sender, EventArgs e)
{
string message = "message 1";
found = false;
ListViewItem item = new ListViewItem(message);
foreach (ListViewItem z in listView1.Items)
{
if (z.Text == message)
{ found = true; }
}
if (found == true)
{
DeleteIfNecessary(message);
}
}
I can make 4 of these functions for each buttons, but since i need 40 different messages, stupid yes, but there is no way to send a message argument through the function, so i need to use the if test and check witch button is hovered and then output the message to that specified button. and im using visual studio and windows forms, sorry for not mentioned.
There is a Control.MouseHover event. You can implement:
private void button_MouseHover(object sender, System.EventArgs e)
{
doSomething(sender);
}
and for all of your buttons, set event handler for MouseHover to button_MouseHover in IDE, or do it in code:
this.button1.MouseHover += new System.EventHandler(this.button_MouseHover);
By checking the sender parameter you can know which button is calling the event handler.
Update
According to your update in the question, I think you can just use messAdd as the event handler for MouseEnter event for all of your buttons, and use messdel as the event handler for MouseLeave. Again, you don't need to create a copy of these two methods for all of your buttons, you just need to assign the same event handler method for all the buttons, and check sender to know who is calling the event handler - then creating different messages.
The sender is your Button object. Just cast it to a Button and access what you want (text, tag, name, etc.) to know which Button is trying to add/remove message on the list view.
Update 2
Button button = sender as Button;
if (button == null) {
// not a button, do nothing
return;
}
string message = String.Empty;
if (sender.Equals(button1)) {
message = "message1";
} else if (sender.Equals(button2)) {
message = "message2";
} ...
I'm going to assume this is WinForms, since you didn't specify otherwise.
You can create an int hoveredId that represents which button is hovered (value -1 means nothing is hovered). When creating the buttons, set the Tag property to the button's id number.
Then register each button to both of these functions:
private void buttons_MouseEnter(object sender, System.EventArgs e)
{
Button btn = ((Button)sender);
hoveredId = (int)btn.Tag;
}
private void buttons_MouseLeave(object sender, System.EventArgs e)
{
Button btn = ((Button)sender);
if ((int)btn.Tag == hoveredId)
hoveredId = -1;
}
When checking which button is hovered, you can use a switch statement:
switch (hoveredId)
{
case 1:
string message = "scenario1";
break;
case 2:
scenario2...etc
break;
}
Related
Good day, anyone can help me with this problem... I have a combo box and a textbox. the textbox(txtFruitNo) will check the length of text under Leave event. It is ok. But if I click on the combo box while txtFruitNo is not yet completed. It needs me to complete first the length of txtFruitNo then only I can click the combo box.
I do not want to show the messagebox if I click on the combo box even if the length of the txtFruitNo is not yet completed.
Thanks
private void cmbFruitSelection_SelectedIndexChanged(object sender, EventArgs e)
{
DateTime thetime = DateTime.Now;
String varApple = "App-Red";
String varBanana = "Ban-Yellow";
if (cmbFruitSelection.SelectedItem.ToString() == "Apple")
{
txtFruitNo.Text = varApple.ToString() + thetime.ToString("yyyy");
txtFruitNo.SelectionStart = txtFruitNo.Text.Length;
txtFruitNo.MaxLength = 18;
}
else if (cmbFruitSelection.SelectedItem.ToString() == "Banana")
{
txtFruitNo.Text = varBanana.ToString() + thetime.ToString("yyyy");
txtFruitNo.SelectionStart = txtFruitNo.Text.Length;
txtFruitNo.MaxLength = 17;
}
}
private void txtFruitNo_Leave(object sender, EventArgs e)
{
if (txtFruitNo.TextLength != txtFruitNo.MaxLength)
{
MessageBox.Show("Your fruit number is too short. Please check.");
txtFruitNo.Focus();
}
else
{
// Do something here
}
}
At what point is it important for continuation of the program that the "Fruit Number" is within parameters. If it is not at the time of leaving focus try moving it to a different control for example the "OK" button could run the parameter check and if valid continue if not flag mesage box and return to the textbox
Since your requirement is to only to do the validation and prompt the message box once the user has selected a value from the combo, please do the following;
Introduce a form variable
private bool isComboClicked = false;
Add the below line to cmbFruitSelection_SelectedIndexChanged
isComboClicked = true;
Adding the above line at the beginning of the above event would prompt the length validation message on selection of value from the combo. If you want to prompt message for specific value on the combo move it within the if statements if (comboBox1.SelectedItem.ToString() == "Apple") etc.
Now in txtFruitNo_Leave event enclose the code within the below if condition.
if (isComboClicked)
{
// Your Code
if (txtFruitNo.TextLength != txtFruitNo.MaxLength)
{
MessageBox.Show("Your fruit number is too short. Please check.");
txtFruitNo.Focus();
}
else
{
// Do something here
}
}
As I understand:
You have "validation" on TextBox in Leave eventhandler, which show error message if validation fails.
But if TextBox.Leave event was raised by selecting ComboBox control, then validation must be suppressed.
Create Panel and put there only txtFruitNo and cmbFruitSelection controls.
// Validation function
private bool IsTextBoxValid()
{
return this.txtFruitNo.Length == this.txtFruitNo.maxlength;
}
Then create and hook up Validating eventhandler for Panel where you will validate txtFruitNo
private void Panel_Validating(Object sender, CancelEventArgs e)
{
if(this.IsTextBoxValid() == false)
{
e.Cancel = true;
MessageBox.Show("Your fruit number is too short. Please check.") ;
}
}
Validating will be raised only when focus move outside of the panel.
Using Validating event will prevent changing focus to outside controls automatically if e.Cancel = true
In that case combobox cmbFruitSelection can be focused and user can complete txtFruitNo text by selecting valid value from ComboBox.
I think using of ErrorProvider control will be more friendly for the user, then MessageBox.
Add ErrorProvider control in the Form through designer and add few lines in the code
private void Panel_Validating(Object sender, CancelEventArgs e)
{
if(this.IsTextBoxValid() == false)
{
e.Cancel = true;
this.ErrorProvider1.SetError(txtFruitNo,
"Your fruit number is too short. Please check.");
}
else
{
this.ErrorProvider1.Clear();
}
}
And clear error after valid value was used from ComboBox
private void cmbFruitSelection_SelectedIndexChanged(object sender, EventArgs e)
{
DateTime thetime = DateTime.Now;
String varApple = "App-Red";
String varBanana = "Ban-Yellow";
if (cmbFruitSelection.SelectedItem.ToString() == "Apple")
{
txtFruitNo.Text = varApple.ToString() + thetime.ToString("yyyy");
txtFruitNo.SelectionStart = txtFruitNo.Text.Length;
txtFruitNo.MaxLength = 18;
//Clear error
this.ErrorProvider1.Clear();
}
else if (cmbFruitSelection.SelectedItem.ToString() == "Banana")
{
txtFruitNo.Text = varBanana.ToString() + thetime.ToString("yyyy");
txtFruitNo.SelectionStart = txtFruitNo.Text.Length;
txtFruitNo.MaxLength = 17;
//Clear error
this.ErrorProvider1.Clear();
}
}
In my wpf app, My buttons are not working on single click. I've Edit button for changing dataTemplate of ListBox items. But, I need to click button two times to edit. also for right click event, I need to click twice. Double click event works fine. Why this happens? Where could be the problem?
C# code for Right click event and Edit button:
private void listBox1_MouseRightClick(object sender, MouseButtonEventArgs e)
{
Harvest_TimeSheetEntry entryToDelete = (Harvest_TimeSheetEntry)listBox1.SelectedItem;
if(entryToDelete!=null)
{
MessageBoxResult Result = System.Windows.MessageBox.Show("Are you sure?", "Delete Confirmation", System.Windows.MessageBoxButton.YesNo);
if (Result == MessageBoxResult.Yes)
{
Globals._globalController.harvestManager.deleteHarvestEntry(entryToDelete);
listBox1.Items.Remove(listBox1.SelectedItem);
}
else
{
System.Windows.MessageBox.Show("Delete operation Terminated");
}
}
}
private void EditButton_Click(object sender, RoutedEventArgs e)
{
if (listBox1.ItemTemplate == (DataTemplate)this.FindResource("DefaultDataTemplate"))
{
listBox1.ItemTemplate = (DataTemplate)this.FindResource("EditableDataTemplate");
EditButton.Content = "Done Editing";
}
else
{
foreach (Harvest_TimeSheetEntry item in listBox1.Items)
{
if (!item.isSynced)
{
ValidateEntry(item);
Globals._globalController.harvestManager.updateHarvestEntry(item);
System.Windows.MessageBox.Show("Entry Updated");
}
listBox1.ItemTemplate = (DataTemplate)this.FindResource("DefaultDataTemplate");
EditButton.Content = "Edit";
}
}
}
Try handling the PreviewMouseDown or PreviewMouseLeftButtonDown events instead. Sometimes the bubbling Routed Events get internally used by controls. For more information, please view the UIElement.PreviewKeyDown Event and UIElement.PreviewMouseDown Event pages at MSDN.
I understand that there are Listbox Select index change questions floating around. However, this question focuses on a different matter. I have a list box, with some strings on the form. What I am trying to accomplish is to be able to scroll through the items in the list box (i.e using the arrow keys to navigate to a particular item). Once I navigate to the item I want, I want to either be able to press enter on the item and continue my application. So, the question is How to determine the Event type of that was raised on the List box in order to compare the event with either a Mouse Click event or a Keydown event, thus allowing me to decide which conditional statement to execute based of the result of the boolean expression......The reason I need to determine the type is because if the user presses ENter on the selectedIndexed Item a Dialogbox Appears, currently the dialogbox appears everytime a user HIGHLIGHTS a new item (you can see how that is a problem).
Psuedo Code
if (Listbox_Selected_Event_EventType isEqualTo Mouse_Click)
{
// execute code
} else if (Listbox_Selected_Event_EventType isEqualTo KeydownEvent)
{
// execute code
}
Finished code thanks to Evan,
private void listBox1_KeyPress(object sender, KeyPressEventArgs e)
{
if (listBox1.SelectedIndex != -1)
{
if (e.KeyChar == (char)Keys.Return)
{
var file = Directory.GetFiles(urlHistoryFolder, listBox1.Text).FirstOrDefault();
String line;
try
{
using (StreamReader sr = new StreamReader(file))
{
line = sr.ReadToEnd();
}
DialogResult result1 = MessageBox.Show("Are You sure you want to Load this WebService", "Important Question", MessageBoxButtons.YesNo);
if (result1 == DialogResult.Yes)
{
//MessageBox.Show("Loading WebService");
textEndPointUri.Text = line;
listBox1.Visible = false;
GetBtn_Click(sender, e);
}
}
catch (Exception exp)
{
Console.WriteLine("File could not be read:");
Console.WriteLine(exp.Message);
}
}
}
}
The problem is you are looking at the wrong event. You should be handling the MouseClick event and the KeyUp or KeyDown event on the list box.
private void listBox1_KeyUp(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
{
//Get the selected item and do whatever you need to it
//Open your dialog box
}
}
private void listBox1_Click(object sender, MouseEventArgs e)
{
//Get the selected item and do whatever you need to it
//Open your dialog box
}
Then there is no need for a conditional as you have handled both the events individually. Make sure you remove your Dialog box code from the SelectedIndexChanged event.
EDIT:
SelectedIndexChanged fires every time you select and item in the ListBox Object. The box still stores an index even if you don't handle that event. So you can reference or manipulate the PROPERTY of SelectedIndex anywhere. If you handle the two above events, any time a user clicks an item or presses enter you check if there is a selected item:
if (listBox1.SelectedIndex != -1)
{
//Now we know you have an item selected
//Do some stuff
}
Add a Button to the Form and set the AcceptButton() Property of the FORM to that Button. Now when Enter is pressed the Button will fire. Display your dialog in the Button Click() handler. This has the added benefit that people can also click the Button instead of pressing Enter:
private void button1_Click(object sender, EventArgs e)
{
if (ListBox.SelectedIndex != -1)
{
// ... display the dialog ...
Console.WriteLine(ListBox.SelectedItem.ToString());
}
}
To identify if ENTER has been pressed:
private void listBox1_KeyPress(object sender, KeyPressEventArgs e)
{
if (e.KeyChar == (char)Keys.Return)
// do something
}
I have a Tooltip with the ShowAlways property set to true.
On the controls where I want the tooltip to display (LinkLabels in this instance), I see there is a "ToolTip on <name of my Tooltip>" property which expects a string.
However, my tooltip is shared between 5 LinkLabels, and should differ depending on which one is hovered over.
I do have a shared click event that works:
private void linkLabelPlatypus1_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
{
int Platypus = 1;
LinkLabel ll = null;
if (sender is LinkLabel)
{
ll = sender as LinkLabel;
}
if (null != ll)
{
if (ll.Name == linkLabelPlatypus2.Name)
{
Platypus = 2;
} else if (ll.Name == linkLabelPlatypus3.Name)
{
Platypus = 3;
} else if (ll.Name == linkLabelPlatypus4.Name)
{
Platypus = 4;
} else if (ll.Name == linkLabelPlatypus5.Name)
{
Platypus = 5;
}
toolTipPlatypi.SetToolTip(ll, DuckbillData.GetPlatypusDataForToolTip(Platypus));
}
}
...but I want the tooltips to also show on hover, and not require the user to click the label.
You only need to set the tooltip once :
public Form1()
{
InitializeComponent();
toolTip1.SetToolTip(linkLabel1, "foo");
toolTip1.SetToolTip(linkLabel2, "bar");
}
Done.
Doing this in a MouseHover or MouseEnter handler will call this function over and over each time the event fires. It will work, but it is unnecessarily complicated.
You only need one ToolTip on a form to provide tips for any number of components and it can provide them all simultaneously and continuously (ie: you don't have to change it or set it each time). Each component can have only one tip, but you can change it throughout the program any time you like. ShowAlways does not have to be true - it is used to make tooltips show on forms which are not active (ie: hover over an inactive window behind one with focus, etc).
You should write a event handler for Mouse Hover and have your tool tip display logic inside it.
private void Label1_MouseHover(object sender, System.EventArgs e)
{
//display logic
}
http://msdn.microsoft.com/en-us/library/system.windows.forms.control.mousehover.aspx
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.