While developing a simple Windows Form UI applications, I am trying to create an effect to show and close dropdown on mouse events.
Like I can open the dropdown on MouseMove event by setting comboBox.DroppedDown = true;
However, this same is not working when I set comboBox.DroppedDown = false; on MouseLeave event to close it.
No idea what exactly is needs to be done here.
The problem is on MouseLeave the dropdown does not lose focus and hence unless you select one item from list, it does not close. It waits for user to select an item from list.
If it can lose focus on MouseLeave, would work.
Any suggestions please.
First of all I must say that I am not an experienced programmer and I just started with WPF.
I know this question is two years old but I had the same issue and I found I can close the drop down list of the ComboBox using the event IsMouseDirectlyOverChanged. What was really annoying for me was that I had a ComboBox and a button, and If the drop down menu was opened without making a selection and I wanted to click the button, nothing happens at the first click because at the first click the drop down menu was closing. After this I could click on the button.
For me it's working fine: the drop down list close if I move the mouse in any direction (up, left, down, right) and a message is append to a textbox control. I don't know if this event is something new or it could be used 2 years ago too.
private void comPortList_IsMouseDirectlyOverChanged(object sender, DependencyPropertyChangedEventArgs e)
{
if (comPortList.IsDropDownOpen==true)
{
txtMsgBox.AppendText("MouseDirectlyOverChanged\n");
txtMsgBox.ScrollToEnd();
comPortList.IsDropDownOpen = false;
}
}
This event triggers when your mouse pointer is over the opened ComboBox. If you don't open the drop down list, it will not trigger.
Another thing that I've seen is that this event triggers when you enter over the opened ComboBox and also when you leave it. If I append the text before checking if the IsDropDownOpen property is true, the text "MouseDirectlyOverChanged" will appear twice in my textbox when I the mouse pointer leaves the oppened ComboBox.
If i comment the line:
comPortList.IsDropDownOpen = false;
and leave the AppendText and ScrollToEnd before if, the text will append only once.
I hope this helps :)
It sounds to me like you need to be using the MouseEnter event and not MouseMove. The reason it wouldn't work on MouseLeave is because your mouse is moving, and that will just set it to true again.
Related
I am trying to create a form where the user selects one of 2 radio buttons, "fast" and "slow", then presses a "go" button on the form. It should work as follows:
When "fast" is selected and "go" is pressed, the user needs to continue holding down the button in order to make the player move and the player stops when the user releases their finger from the button. For this, I am using the MouseDown and MouseUp events.
If "slow" is selected, the user can only move one step at a time, regardless of how long the button is held down. for this, I am using the Click event.
To test this concept, I put a MessageBox in the Click and MouseDown events to see how they work together. When I click on the button, however, I am only seeing the Mousedown event get triggered, regardless of which radio button is selected and the Click event is only triggered when the go button is in focus and I press enter.
How can I make it so that both events get called simultaneously (and then I can put the respective if statement in to differentiate between "fast" and "slow" radio buttons)? (The button is wired up to these events by double-clicking on their respective handler in the design window, not hardcoded).
private void go_button_MouseDown(object sender, MouseEventArgs e)
{
Console.WriteLine("Mousedown"); // Doesn't show in console window in Release mode, still trying to solve this
MessageBox.Show("Mosuedown");
}
private void go_button_Click(object sender, EventArgs e)
{
Console.Out.WriteLine("go_buttonclick"); // Doesn't show in console window in Release mode, still trying to solve this
Console.WriteLine("go_buttonclick"); // Doesn't show in console window in Release mode, still trying to solve this
MessageBox.Show("go_buttonclick");
}
I found what I was doing wrong, both events are being triggered at the same time, but the MessageBox in the MouseDown event wasn't allowing me to see the Click and MouseUp events also being triggered. When I turned off the MouseDown MessageBox, the other 2 MessageBoxes appeared, thanks!
I have a user control that I'm trying to make draggable. The whole control should be draggable except when you click on buttons or text boxes. I'm handling the mousedown, mouseup and mousemove events on the usercontrol itself and I can drag by clicking anywhere. The only issue is now I can't click any buttons on the user control. Any clue what's going on?
Code is something like this:
<UserControl PreviewMouseLeftButtonDown="Popup_PreviewMouseLeftButtonDown" ....STUFF...>
<!-- CAN'T CLICK THIS -->
<Button />
<UserControl>
Code Behind:
public void Popup_PreviewMouseLeftButtonDown(object sender, MouseEventArgs e)
{
mouseDown = true;
oldMousePosition = this.PointToScreen(e.GetPosition(this));
this.Popup.Child.CaptureMouse();
}
The issue arises when you use CaptureMouse() - this permanently captures all your mouse input on the window, and makes it so that you're unable to click on anything within the Window. I don't know if it's different for you, or if you checked, but it's not (just) that the Button is unclickable - it's that literally everything on the Window is unclickable.
You have to actually do something with the mouse after you've captured it, and then once you finish that, you have to return normal control by calling Mouse.Capture(null). For you, this would probably be best to do in your MouseUp() method.
However, this still leaves the child problem. I can't really think of any way you're going to be able to both capture all mouse click events on a parent control and allow them to get to the child control. I suppose you could check the mouse position against the button position, both relative to the UserControl, then route the click event to the Button every time, but this seems a little overelaborate. Is there a reason you can't just add a full-sized Grid to the UserControl with a lower ZIndex than the Button, and just use that to detect if a click was made inside the UserControl but not on the Button?
I Have grid in my XAML and couple of buttons on it.
And i want to get notified every time the user press the grid so i add MouseEnter Event:
<Grid x:Name="LayoutRoot" Background="#FF1F1F1F" MouseEnter="TapMouse">
But my problem is that every time one of the buttons is pressed so this method called too.
Any way to disable it? or any other way to implement it?
Thanks
First set break points in each event block.
Find out which one is firing first the button or the grid
Declare a bool at the top and call it buttonClicked = false;
if it is the button then put a buttonClicked = true in the but event
if its the grid then I would try and see if you could use a buttonOver event
In the grid event wrap it all in an if statement if(!buttonClicked)
That should work
NOTE you will have to also add a buttonClicked = false into maybe focus lost event for the button
Update:
Coming back to this answer years later I acknowledge it's ghettoness. Though i'd like to update it, I think leaving it as a time capsule of my own ignorance is much more beneficial.
I want to disable selecting text and clicking in the middle of text in a TextBox, but the user must be able to enter this TextBox and write at the end of earlier text, so I cannot make it ReadOnly or Enable = false.
I try to handle MouseDown and do the following:
input.Select(input.Text.Length, 0);
It helps with placing a cursor in the middle of text, but the user still can make a selection from the end.
I also make a MessageBox() on MouseDown event, but in this case the user cannot click on textBox and write anything.
The last try was to set a focus() in another Control and focus back, after a period of time, but it didn't work at all. User still can make a selection.
How can I do it?
How about this for Click event
Edit: Also do the same for DoubleClick and MouseLeave to cover all cases. You can have a common event handler.
private void textBox1_Click(object sender, EventArgs e)
{
((TextBox) sender).SelectionLength = 0;
}
If it fits the UI/user model, another approach is to use two text boxes: a read-only one with the previous text that the user can see and act on (if that is something he needs to do) and an editable one for the new text along with a button to commit the new text to the read-only text box (and persistence layer).
That approach is not only arguably more user-friendly—the editable box is completely editable rather than just "appendable", which gets confusing when the user hits Backspace—but also requires less fighting with the framework to make the boxes do what you need.
You're not far off with your MouseDown event handler, but probably better to catch MouseUp, as this is the event that will fire when they have finished selecting.
Alternatively, you could catch the SelectionChanged event.
Just put your:
input.Select(input.Text.Length, 0);
code in any of those event handlers.
I have a WinForm with 3 group boxes, one with combo boxes, and two with radio buttons. I set all of them and their children controls to "TabStop = false", but when I cycle with TAB, the currently selected radio button in each of the last two group boxes gets focused.
If there's no way to change this behavior, what would be a good event to catch and move the focus away? I can't find an "OnFocus" event.
The solution is to set one method (code below) to handle the "Enter" event of every radio button in the form (if that's what you wish).
Actually, I only did it for the radio buttons of the first group box and it worked, the second group box's radio buttons don't get focus, even though their "Enter" events are not handled. This is not the behavior you would have expected.
private void radiobuttonXGroup1_Enter(object sender, EventArgs e)
{
SomeOtherControl.Focus();
}
In the *.Designer.cs file you edit every Enter event (for each radio button) to point to one event handler (the above method).
this.radiobutton1Group1.Enter += new System.EventHandler(this.radiobuttonXGroup1_Enter);
this.radiobutton2Group1.Enter += new System.EventHandler(this.radiobuttonXGroup1_Enter);
this.radiobutton3Group1.Enter += new System.EventHandler(this.radiobuttonXGroup1_Enter);
Setting the TabStop to False on a RadioButton to prevent tabbing to the control works until you actully select the radio button without any additional overrides like suggested by #msergeant.
EDIT
The following code prevents the code from getting a tab key event:
private void radioButton1_CheckedChanged(object sender, EventArgs e)
{
radioButton1.TabStop = false;
}
Radio buttons behave differently with respect to Tab from other controls in that they work in sets or groups based on setting the tab index or placing then radio buttons in a group box.
The MSDN documentation for RadioButton.TabStop states "This API supports the .NET Framework infrastructure and is not intended to be used directly from your code". Which basically means, "This isn't going to work how you expect it to".
With that said, the Enter event will fire when the button receives the focus. You can try to use that to move focus to another control.