I have a list box with some items. Is there anyway I can attach a double click event to each item?
Item 1
Item 2
Item 3
If i was to double click Item 2, a Messagebox saying "Item 2" would pop up
How would i do this?
void listBox1_MouseDoubleClick(object sender, MouseEventArgs e)
{
int index = this.listBox1.IndexFromPoint(e.Location);
if (index != System.Windows.Forms.ListBox.NoMatches)
{
MessageBox.Show(index.ToString());
}
}
This should work...check
WinForms
Add an event handler for the Control.DoubleClick event for your ListBox, and in that event handler open up a MessageBox displaying the selected item.
E.g.:
private void ListBox1_DoubleClick(object sender, EventArgs e)
{
if (ListBox1.SelectedItem != null)
{
MessageBox.Show(ListBox1.SelectedItem.ToString());
}
}
Where ListBox1 is the name of your ListBox.
Note that you would assign the event handler like this:
ListBox1.DoubleClick += new EventHandler(ListBox1_DoubleClick);
WPF
Pretty much the same as above, but you'd use the MouseDoubleClick event instead:
ListBox1.MouseDoubleClick += new RoutedEventHandler(ListBox1_MouseDoubleClick);
And the event handler:
private void ListBox1_MouseDoubleClick(object sender, RoutedEventArgs e)
{
if (ListBox1.SelectedItem != null)
{
MessageBox.Show(ListBox1.SelectedItem.ToString());
}
}
Edit: Sisya's answer checks to see if the double-click occurred over an item, which would need to be incorporated into this code to fix the issue mentioned in the comments (MessageBox shown if ListBox is double-clicked while an item is selected, but not clicked over an item).
Hope this helps!
I know this question is quite old, but I was looking for a solution to this problem too. The accepted solution is for WinForms not WPF which I think many who come here are looking for.
For anyone looking for a WPF solution, here is a great approach (via Oskar's answer here):
private void myListBox_MouseDoubleClick(object sender, MouseButtonEventArgs e)
{
DependencyObject obj = (DependencyObject)e.OriginalSource;
while (obj != null && obj != myListBox)
{
if (obj.GetType() == typeof(ListBoxItem))
{
// Do something
break;
}
obj = VisualTreeHelper.GetParent(obj);
}
}
Basically, you walk up the VisualTree until you've either found a parent item that is a ListBoxItem, or you ascend up to the actual ListBox (and therefore did not click a ListBoxItem).
For Winforms
private void listBox1_DoubleClick(object sender, MouseEventArgs e)
{
int index = this.listBox1.IndexFromPoint(e.Location);
if (index != System.Windows.Forms.ListBox.NoMatches)
{
MessageBox.Show(listBox1.SelectedItem.ToString());
}
}
and
public Form()
{
InitializeComponent();
listBox1.MouseDoubleClick += new MouseEventHandler(listBox1_DoubleClick);
}
that should also, prevent for the event firing if you select an item then click on a blank area.
It depends whether you ListBox object of the System.Windows.Forms.ListBox class, which does have the ListBox.IndexFromPoint() method. But if the ListBox object is from the System.Windows.Control.Listbox class, the answer from #dark-knight (marked as correct answer) does not work.
Im running Win 10 (1903) and current versions of the .NET framework (4.8). This issue should not be version dependant though, only whether your Application is using WPF or Windows Form for the UI.
See also: WPF vs Windows Form
This is very old post but if anyone ran into similar problem and need quick answer:
To capture if a ListBox item is clicked use MouseDown event.
To capture if an item is clicked rather than empty space in list box check if listBox1.IndexFromPoint(new Point(e.X,e.Y))>=0
To capture doubleclick event check if e.Clicks == 2
The post is old but there is a simple solution for those who need it
private void listBox1_DoubleClick(object sender, EventArgs e)
{
if (listBox1.SelectedIndex > -1)
{
MessageBox.Show(listBox1.Items[listBox1.SelectedIndex].ToString());
}
}
Related
I have a ListBox in winforms Application, now the business logic demands me to fire one function if an item in the List Box is Selected and fire another if an item in the List Box is Deselected.
But the way I see it none of the Events Listed in VS is giving that power of Execution. I do see Events like
SelectedIndexChanged(object sender, EventArgs e)
and
SelectedValueChanged(object sender, EventArgs e)
But both these event fires if there is a change in the selection of the ListBox. But it doesn't specify if an item was selected or deselected which raised the event.
Any suggestion on this would be very helpful.
I even found the following link on MSDN
https://msdn.microsoft.com/en-us/library/system.windows.controls.listboxitem.unselected%28v=vs.110%29.aspx
But I am not sure how to apply the same in this situation.
Posting the Tedious Solution. Might help some1 in the future to Copy Paste.
public static int ListCount;
private void listBoxPackService_SelectedIndexChanged(object sender, EventArgs e)
{
int CurrCount;
ListBox.SelectedObjectCollection col = listBoxPackService.SelectedItems;
CurrCount = col.Count;
if (CurrCount > ListCount)
{
//Item Selected
}
else
{
//Item DeSelected
if(CurrCount == 0)
{
//All Items Were Deselected
}
}
ListCount = CurrCount;
}
On load of the ListBox
ListCount = 0
rename the Controls as per your requirement.
I am still open for a better solution :)
In my .NET 4,5 Winforms application, the ListView control's MouseUp event is firing multiple times when I open a file from that event as follows:
private void ListView1_MouseUp(object sender, MouseEventArgs e)
{
ListViewHitTestInfo hit = ListView1.HitTest(e.Location);
if (hit.SubItem != null && hit.SubItem == hit.Item.SubItems[1])
{
System.Diagnostics.Process.Start(#"C:\Folder1\Test.pdf");
MessageBox.Show("A test");
}
}
Note: When clicking on the SubItem1 of the listview, the file opens but the message box appears at least twice. But, when I comment out the line that opens the file the message box appears only once (as it should). I do need to open the file whose name is clicked by the user in the listview. How can I achieve this without the MoueUp event firing multiple times?
Please also note that the MouseClick event for listview does not always work as also stated here. So, I have to use MouseUp event.
EDIT: I should mention the ListView is in Details mode.
Avoid HitTest() and use ListView's native function GetItemAt(). An example from MSDN looks like this:
private void ListView1_MouseDown(object sender, MouseEventArgs e)
{
ListViewItem selection = ListView1.GetItemAt(e.X, e.Y);
// If the user selects an item in the ListView, display
// the image in the PictureBox.
if (selection != null)
{
PictureBox1.Image = System.Drawing.Image.FromFile(
selection.SubItems[1].Text);
}
}
I'm writing a simple application with several controls on a Windows form. I need to monitor the state of buttons (enabled/disabled) according to the state of a textbox and a listbox.
For example, when the listbox is empty, buttons Delete, Delete All and Edit are to be disabled, or when either the textbox or the listbox is empty button Forward is disabled, and so on.
So, I put the change of these properties on Application.Idle event, so it goes something like this:
private void MainForm_Load(object sender, EventArgs e)
{
Application.Idle += new EventHandler(Application_Idle);
}
public void Application_Idle(object sender, EventArgs e)
{
CheckFillingFields(forwardBtn);
CheckFillingList(deleteBtn);
CheckFillingList(deleteAllBtn);
CheckFillingList(editBtn);
}
private void CheckFillingFields(object sender)
{
if (questionTxt.Text == "" || answersLst.Items.Count == 0)
(sender as Button).Enabled = false;
else
(sender as Button).Enabled = true;
}
private void CheckFillingList(object sender)
{
if (answersLst.Items.Count == 0)
(sender as Button).Enabled = false;
else
(sender as Button).Enabled = true;
}
So, the question is - is it acceptable to use Application.Idle in this case? Or should I make these properties dependable on user actions? (For example, when the user deletes an item from the listbox, I should check if it was the last one, and disable the corresponding buttons.)
Thanks a lot in advance, I really appreciate your help!
The simple answer is that, yes, the idle checking is bad and you should re-check the state of your controls on their change events, not "whenever possible".
I am having a treeview with some nodes. I am also having a panel. I have taken some usercontrol forms and i will load those usercontrols when corresponding node is selected from the child hood. Now what i need is have some validations like if i left the text box empty i will have some tooltips displayed to the user. Suppose if i click on first node i will have a user control loaded. With out giving any values if i hit ok i will have some tool tips as follows
Now if i select the second node from the tree still the tooltips getting displayed i would like to hide those
Any Help please
my code for rasing error tooltips is as shown below
public class TestClass
{
public void RequiredText(TextBox txtTemp, ToolTip newtoolTip)
{
if (txtTemp.Text != string.Empty)
{
txtTemp.BackColor = System.Drawing.Color.White;
newtoolTip.Hide(txtTemp);
}
else
{
txtTemp.BackColor = System.Drawing.Color.Tomato;
newtoolTip.Show("Required", txtTemp);
}
}
}
But this was done in the use control form.
I haven't yet mastered the art of reverse-engineering code from a screenshot. I'm guessing that you don't dispose the previous user control when you select a new one. Allowing the tool tip to stay visible. Use code like this:
private UserControl currentView;
public void SelectView(UserControl view) {
if (currentView == view) return;
if (currentView != null) currentView.Dispose();
if (view != null) this.Controls.Add(view);
currentView = view;
}
And call SelectView() from the TreeView's AfterSelect event handler.
Have you tried the Hide method?
http://dotnetperls.com/tooltip
Got the answer just written Usrcntrl_Leave event for every user control as
private void usrcntrlPPD_Leave(object sender, EventArgs e)
{
this.Dispose();
}
This solved my problem :)
private void timer1(object sender, EventArgs e)
{
count++;
if (count == 2)
{
toolTMensaje.SetToolTip(textBox1,"");
toolTMensaje.Hide(textBox1);
count = 0;
timer1.Stop();
}
}
I have a C# ComboBox using WPF. I have code that executes when the ComboBox's GotFocus is activated. The issue is that the GotFocus event is executed every time a selection is made from the ComboBox. For example, the GotFocus is executed when you first click on the ComboBox and then when you make a selection even though you have not click on any other control.
Is it possible to prevent this event from firing if a selection is being made in the list or is there a flag or something else in the event handler that can be used to determine if the GotFocus event handler was fired as a result of the user selecting an item in the list?
You can solve this problem with next verification:
private void myComboBox_GotFocus(object sender, RoutedEventArgs e)
{
if (e.OriginalSource.GetType() == typeof(ComboBoxItem))
return;
//Your code here
}
This code will filter all focus events from items (because they use bubble routing event). But there is another problem - specific behaviour of WPF ComboBox focus: when you open drop-down list with items your ComboBox losing focus and items get. When you select some item - item losing focus and ComboBox get back. Drop-down list is like another control. You can see this by simple code:
private void myComboBox_GotFocus(object sender, RoutedEventArgs e)
{
if (e.OriginalSource.GetType() != typeof(ComboBoxItem))
{
Trace.WriteLine("Got " + DateTime.Now);
}
}
private void myComboBox_LostFocus(object sender, RoutedEventArgs e)
{
if (e.OriginalSource.GetType() != typeof(ComboBoxItem))
{
Trace.WriteLine("Lost " + DateTime.Now);
}
}
So you will get anyway atleast two focus events: when you select ComboBox and when you selecting something in it (focus will return to ComboBox).
To filter returned focus after selecting item, you can try to use DropDownOpened/DropDownClosed events with some field-flag.
So the final code with only 1 event of getting focus:
private bool returnedFocus = false;
private void myComboBox_GotFocus(object sender, RoutedEventArgs e)
{
if (e.OriginalSource.GetType() != typeof(ComboBoxItem) && !returnedFocus)
{
//Your code.
}
}
private void myComboBox_LostFocus(object sender, RoutedEventArgs e)
{
if (e.OriginalSource.GetType() != typeof(ComboBoxItem))
{
ComboBox cb = (ComboBox)sender;
returnedFocus = cb.IsDropDownOpen;
}
}
Choose from this examples what you actually need more for your application.
I'm not too hot on WPF; but if you're trying to detect changes to the list (click on new value etc) you can use SelectedIndexChanged events..
On the other hand, if you really do want to know simply when the control is focussed, can you filter it by saying something like;
if (combo1.Focused && combo1.SelectedIndex == -1)
{
...
}
.. ? It really depends on what youre trying to detect, exactly.
Another solution is used is to determine whether the new focused element is an existing item in the combobox. If true then the LostFocus event should not be performed, because the combobox still has focus. Otherwise an element outside the combobox received focus.
In the code snipplet below I added the functionality in a custom combobox class
public class MyComboBox : System.Windows.Controls.Combobox
{
protected override void OnLostFocus(RoutedEventArgs e)
{
//Get the new focused element and in case this is not an existing item of the current combobox then perform a lost focus command.
//Otherwise the drop down items have been opened and is still focused on the current combobox
var focusedElement = FocusManager.GetFocusedElement(FocusManager.GetFocusScope(this));
if (!(focusedElement is ComboBoxItem && ItemsControl.ItemsControlFromItemContainer(focusedElement as ComboBoxItem) == this))
{
base.OnLostFocus(e);
/* Your code here... */
}
}
}