The problem:
KeyUp is handled by the grid in main window (Grid_KeyUp)
Main window shows a child window (e.g. MessageBox.Show(...))
User presses [Return] (Keys.Return) to close the MessageBox
Main window actually GETS the KeyUp event from that keypress in MessageBox
I have a very simple isolated sample that shows the problem I am having. Just create an empty WPF project and use this XAML:
<Grid KeyUp="Grid_KeyUp">
<Button Click="Button_Click"></Button>
</Grid>
And the code-behind:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void Grid_KeyUp(object sender, KeyEventArgs e)
{
Console.WriteLine("KEYUP: " + e.Key);
}
private void Button_Click(object sender, RoutedEventArgs e)
{
MessageBox.Show(this, "TEST");
}
}
If you click the button and press [Return] to close the MessageBox the output window will print:
KEYUP: Return
Weird facts:
I get the same behaviour when pressing [Escape] (KEYUP: Escape gets printed), but when I press [Space] the console does not print out anything!
e.Source and e.OriginalSource point to the button in the main window (which is, obviously, wrong).
If you put a breakpoint right after MessageBox.Show(...) the event does not get handled by out KeyUp handler (i.e. the output is empty).
Could anyone explain to me what is happening?
PS Target framework is: .NET 4 Client
Clearly what is happening is that when you press the enter or escape, the message box closes and before you lift up the button the MainWindow gets focus and catches the KeyPress aswell .
The reason why this is not happening with the space bar is that pressing spacebar pushes the button down, but does not release it until you release the spacebar yourself. This means that the spacebar is released before the button is "unpressed" and therefore the MessageBox only closes once the spacebar is released, so the MainWindow does not catch the button press.
You can test this by holding the spacebar in.
You will see that the button is held down but is not pressed until you release it.
You could prolly create a flag that goes off after the MessageBox close. Check if it's the first KeyPress (and maybe check that it happened less than 10 miliseconds after the close) and then just ignore it.
I know, its ugly, but I don't think there's much else you can do (if I'm right)
Related
In my C# project I have a text box and a button. What I want is:
1) the user writes something in the text box
2) clicks the "Enter" button
3) this automatically triggers the button1_Click event
Step 1 is straightforward.
For step 2 the problem is that after I write sth in the text box, it is still selected and I am forced to write "Enter" (new line) in the text box which doesn't happen and I hear an error sound.
For step 3 I used
public Form1()
{
InitializeComponent();
KeyDown += new KeyEventHandler(Form1_KeyDown);
}
void Form1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode==Keys.Enter)
{
button1.PerformClick();
}
}
But the code doesn't detect that the Enter key is presses and the code isn't ran at all. Any ideas how to fix this? I suppose I have to unselect the text box and then press Enter but I don't know how it works.
I have a RadDropDownList in suggestappend mode and a usercontrol as keyboard, this have buttons with ControlStyles.Selectable = false. the MouseUp event fires a SendKeys.Send(key).
The thing is when I focus in the RadDropDownList and write with my keyboard (UserControl) the suggest list appears for a milisecond and desappear.
I tried to control the popup event but it seems to have nothing to do with the suggest list.
how can i keep it opened showing suggestions until user leaves the RadDropDownList?
Here is how to access the auto complete suggest popup and cancel the closure of the popup:
radDropDownList1.DropDownListElement.AutoCompleteSuggest.DropDownList.PopupClosing += DropDownList_PopupClosing;
. . .
void DropDownList_PopupClosing(object sender, Telerik.WinControls.UI.RadPopupClosingEventArgs args)
{
args.Cancel = true;
}
I am currently working on a WPF application with Caliburn framework. At the top right of the application windows, there is a windows CLOSE(X) button. I would like to catch the event for the windows CLOSE button. However, when the application window is closing, the fade out will begin regardless of any buttons which will close the application windows. Also, when the application closes, the application will ask the user whether they want to save the changes or not if there is any changes. However, I can only manage to get the EXIT button in my application to pop up the SAVE CHANGES message and then start the fade out, but this does not occur for the windows CLOSE(X) button. When I pressed the windows CLOSE(X) button, the fadeout will begin first*(Therotically, this shouldn't happen, it should show the SAVE CHANGES message first and then fadeout afterwards)*. During the fade out, the SAVE CHANGES message appears. At the end, the application crashes because the application cannot close as the message still shows in the application. Does any one know any way to work around this? Below is the code I used for the issue.
The code-behind of the wpf view - I used this to catch the event for WINDOWS CLOSE button:
protected override void OnClosing(System.ComponentModel.CancelEventArgs e)
{
if (!closed)
{
e.Cancel = true;
FormFadeOut.Begin();
closed = true;
}
base.OnClosing(e);
}
This code is used to close the application when the fadeout ends:
private void FormFadeOutAnimation_Completed(object sender, EventArgs e)
{
this.Close();
}
In my xaml,I used this code in order to call the function to pop up the SAVE CHANGES message when it is closing:
cal:Message.Attach="[Event Closing] = [Action CloseApp2()]"
In my view model, the following function is called by the above xaml code:
public void CloseApp2()
{
// isClosing = true;
events.Publish(new IsClosingEvent());
// events.Publish(new ClearItemsEvent());
// events.Publish(new SwitchTimerOffEvent());
// Thread.Sleep(2000);
}
When the "IsClosingEvent" event is sent, the SAVE CHANGES message will appear if there are any changes made by the user.
Does anyone have any good idea of how to solve this issue?
Thanks for any helps in advance.
Charles
Use Window.Closing event instead of
protected override void OnClosing(System.ComponentModel.CancelEventArgs e)
when I jump into the PreviewKeyDown the char righthand to the Caret in my RichTextBox is not moved YET. I would like to say to this event do your stuff move the char to the rightside and THEN let me do MY stuff. How can I do that?
private void RTB_PreviewKeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.Space)
{
// event do your stuff
// Char righthanded from the Caret position is moved to the right side
// do MY stuff
}
}
UPDATE: that you know what I talk about... =>
The Caret was directly before the Word "Harold..." then I pressed the spacebar key several times to move the "Harold..." to the right. But the formatting a black Underline seem to be stuck... how can I make the Underline stay attached to the Run object containing the name "Harold..." ?
The reason why I wanted to catch the spacebar key in the KeyDown event is to get the new implicit created Run-object and remove the black Underline.
"Preview" events are fired before the event happens. There will be an equivalent KeyDown event that is fired after the event is processed. Wire up to that event instead and your code will run after WPF has completed handling the keypress.
That is why its called PreviewKeyDown... the event you want is probably KeyDown or TextChanged
I have a simple two forms, one that contains a grid and a button. When I click the button, my application starts doing a long operation. While it is working, I show another form that contains a progress bar
I open it like this:
_busyWindow.ShowDialog();
And defined
public partial class BusyWindow : DevExpress.XtraEditors.XtraForm
{
public BusyWindow()
{
InitializeComponent();
}
private void BusyWindow_FormClosing(object sender, FormClosingEventArgs e)
{
this.Hide();
e.Cancel = true; // this cancels the close event.
}
}
When the operation is finished, I hide the form like this
if (ended)
_busyWindow.Hide();
It works fine. The problem is that when I close the second form (same closing code), it also closes fine but my main GUI loses the focus. For example, if I have the Firefox opened behind the application, then the Firefox gets the focus.
This only happens when I close the second form when the busyWindow has been opened, and no when it hasn't (ie, if I open the form, I close it without clicking on the button, then the main GUI doesn't lose the focus).
Do you know what is happening or where could I try to search?
There could be two possible solutions to enable you to keep focus on your main window:
//Edited: Main Window in the below example would be the window with Grid and Button.
Since you are showing the busy window via ShowDialog() try setting the owner of the window by this: _busyWindow.ShowDialog(this);. I had earlier faced a similar problem and this worked for me. Since you specify the owner of the busyWindow, when it closes it would put the focus back on its owner,i.e. your main window
In case the above technique doesnt work (it should, as it worked for me), you could try to pass the reference of the main window to the busyWindow and then on its close set the focus of the main window. Sample:
_busyWindow.MyMainWindow = this; //MyMainWindow references mainWindow of your app
_busyWindow.ShowDialog();
And the following at the FormClosing of busyWindow:
private void BusyWindow_FormClosing(object sender, FormClosingEventArgs e)
{
this.Hide();
e.Cancel = true; // this cancels the close event.
MainWindow.Focus();
}
See if it works. The first solution should work.
Hope it helps.
Thanks & Happy Windowing!
Just set child's window Owner = null before closing it