(UWP) Using ESC Key to Close ModalDialog - c#

I'm displaying ModalDialog using sample code Busy.xaml in Template10 :
public static void SetBusy(bool busy, string text = null)
{
WindowWrapper.Current().Dispatcher.Dispatch(() =>
{
var modal = Window.Current.Content as ModalDialog;
var view = modal.ModalContent as Busy;
if (view == null)
modal.ModalContent = view = new Busy();
modal.IsModal = view.IsBusy = busy;
view.BusyText = text;
modal.CanBackButtonDismiss = true;
});
}
I can close this dialog by using ALT+Left Arrow, but on most Desktop application pressing ESC key usually will also close popup or dialog.
I try to add code to handle KeyDown on Busy.xaml but this method never executed when I press ESC or any key.
private void UserControl_KeyDown(object sender, KeyRoutedEventArgs e)
{
if (e.Key == VirtualKey.Escape)
{
e.Handled = true;
SetBusy(false);
}
}
So, how to make this ModalDialog close when user press ESC key ?

You have to attach an event handler to the CharacterReceived event of the CoreWindow.
Modify the SetBusy method:
public static void SetBusy(bool busy, string text = null)
{
WindowWrapper.Current().Dispatcher.Dispatch(() =>
{
var modal = Window.Current.Content as ModalDialog;
var view = modal.ModalContent as Busy;
if (view == null)
modal.ModalContent = view = new Busy();
modal.IsModal = view.IsBusy = busy;
view.BusyText = text;
modal.CanBackButtonDismiss = true;
// Attach to key inputs event
var coreWindow = Window.Current.CoreWindow;
coreWindow.CharacterReceived += CoreWindow_CharacterReceived;
});
}
Where as the CoreWindow_CharacterReceived would look like this:
private static void CoreWindow_CharacterReceived(CoreWindow sender,
CharacterReceivedEventArgs args)
{
// KeyCode 27 = Escape key
if (args.KeyCode != 27) return;
// Detatch from key inputs event
var coreWindow = Window.Current.CoreWindow;
coreWindow.CharacterReceived -= CoreWindow_CharacterReceived;
// TODO: Go back, close window, confirm, etc.
}

While the modal is open just use something along this route:
private void Modal_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Escape)
{
this.Close();
}
}
Another way to address (e.KeyCode==Keys.Escape) is:
(e.KeyChar == (char)27)
or
e.KeyCode==(char)Keys.Escape
For this code to work, you need Form.KeyPreview = true;
For more information on what's above: https://msdn.microsoft.com/en-us/library/system.windows.forms.control.keydown.aspx
I believe that you need to append the CancelButton Property for this to work properly.
(Almost the same approach) I believe this should work nicely as well:
private void HandleEsc(object sender, KeyEventArgs e)
{
if (e.Key == Key.Escape)
Close();
}
This is for a console application:
if (Console.ReadKey().Key == ConsoleKey.Escape)
{
return;
}

Related

Old form still display winforms c#

I implement a form for handle excel file when click button "Start".
Event click Start button:
private void btnImport_Click(object sender, EventArgs e)
{
showFormSelectLanguage();
if (CheckSheetFile() == true) {
using (WaitingForm frm = new WaitingForm(handleExcel))
{
frm.ShowDialog(this);
}
var dialogMessage = new DialogMessage();
dialogMessage.ShowDialog(this);
} else
{
ShowDialogNotFoundSheet();
}
}
showFormSelectLanguage method display dialog for select language:
private void showFormSelectLanguage()
{
var formSelectLanguage = new FormSelectLanguage();
formSelectLanguage.ShowDialog(this);
}
ShowDialogNotFoundSheet function for check sheet excel exist:
private void ShowDialogNotFoundSheet()
{
var dialogNotFoundSheet = new DialogNotFoundSheet();
dialogNotFoundSheet.setTextContent("Not found sheet");
dialogNotFoundSheet.ShowDialog(this);
}
Event click confirm select language button at Select language form:
private void btnConfirmLanguage_Click(object sender, EventArgs e)
{
//close dialog
this.Close();
}
Event click Close button for close DialogNotFoundSheet form:
private void btnCloseDialogNotFoundSheet_Click(object sender, EventArgs e)
{
this.Close();
}
CheckSheetFile method:
private bool CheckSheetFile()
{
var isCorrectFile = false;
try
{
xlWorkBook = xlApp.Workbooks.Open(txtFilePath.Text, System.IO.FileMode.Open, System.IO.FileAccess.Read);
var xlWorkBook1 = xlWorkBook.Sheets["SheetName"];
isCorrectFile = true;
}
catch (Exception e)
{
return false;
}
return isCorrectFile;
}
Issue:
When I click Close button at DialogNotFoundSheet form. Then FormSelectLanguage from still display. It repeats. How can resolve it?
Expected 2 forms can close
Thanks!
Update:
All References btnImport_Click:
UI:
I don't exactly know what you did with btnImport_Click, but if your purpose is to disable the function of a button at a time and to enable it at another time, actually you don't have to register or unregister the click event, you can simply set button's Enabled propety.
//btnImport.Click += btnImport_Click;
btnImport.Enabled = true;
//btnImport.Click -= btnImport_Click;
btnImport.Enabled = false;
My guess of the reason of this loop is that you have called += btnImport_Click many times, but -= btnImport_Click is never (or less) run.
For instance if you do:
btnImport.Click += btnImport_Click;
btnImport.Click += btnImport_Click;
Each time btnImport is clicked, btnImport_Click will get invoked twice.

UWP KeyDown Event

I have coded an app in WPF where i have Keydown event functioning with the code below:
private void Form1_Load(object sender, EventArgs e)
{
this.KeyDown += new System.Windows.Forms.KeyEventHandler(Form1_KeyDown);
this.KeyUp += new System.Windows.Forms.KeyEventHandler(Form1_KeyUp);
}
//Declare the comands for Rover control//
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.W) // Holding Keyboard Character "W" //
{
serialPort1.Write("F"); // Passing command "Forward" thorugh letter "F" in arduino code //
}
I am trying to replicate this in UWP and am not sure what I am doing wrong.
Based on research so far, I understand that i have to place KeyDown="Grid_KeyDown" within Grid in XAML part, and i have to write something like:
private async void Grid_KeyDown(object sender, KeyRoutedEventArgs e)
{
//handling code here
if (e.Key == Key.F)
{
string sendData = "F";
if (string.IsNullOrEmpty(sendData))
{
errorStatus.Visibility = Visibility.Visible;
errorStatus.Text = "Please specify the string you are going to send";
}
else
{
DataWriter dwriter = new DataWriter(streamSocket.OutputStream);
UInt32 len = dwriter.MeasureString(sendData);
dwriter.WriteUInt32(len);
dwriter.WriteString(sendData);
await dwriter.StoreAsync();
await dwriter.FlushAsync();
}
}
However this is not working. Does anyone have any suggestion how do I make this Keydown even work so when i press F key i want to pass that to serial port and send it as string "F" to Bluetooth device?
Ok so when i involve the if (e.Key == Windows.System.VirtualKey.F) the code works as below:
private async void Grid_KeyDown(object sender, KeyRoutedEventArgs e)
{
//handling code here
if (e.Key == Windows.System.VirtualKey.F)
{
string sendData = "F";
if (string.IsNullOrEmpty(sendData))
{
errorStatus.Visibility = Visibility.Visible;
errorStatus.Text = "Please specify the string you are going to send";
}
else
{
DataWriter dwriter = new DataWriter(streamSocket.OutputStream);
UInt32 len = dwriter.MeasureString(sendData);
dwriter.WriteUInt32(len);
dwriter.WriteString(sendData);
await dwriter.StoreAsync();
await dwriter.FlushAsync();
}
}
}
However, i am having like the delay. As i mentioned in the first part of the code where I was using serialPort1.Write, the Bluetooth will send the command to the robot instantaneously when i press button and will stop right away when i release the button. So i have to incorporate something similar to UWP as i did in the WPF code below:
private void Form1_Load(object sender, EventArgs e)
{
this.KeyDown += new System.Windows.Forms.KeyEventHandler(Form1_KeyDown);
this.KeyUp += new System.Windows.Forms.KeyEventHandler(Form1_KeyUp);
}
//Declare the comands for Rover control//
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.W) // Holding Keyboard Character "W" //
{
serialPort1.Write("F"); // Passing command "Forward" thorugh letter "F" in arduino code //
}
Thank you
Have you tried using key up event as below:
<Grid KeyUp="Grid_KeyUp">
...
</Grid>
void Grid_KeyUp(object sender, KeyRoutedEventArgs e)
{
//handling code here
}
For more details read the documentation here.
Maybe this will help! This is how I used KeyUP ...
`private void Value1_KeyUp(object sender, KeyRoutedEventArgs e)
{
if (e.Key == VirtualKey.Enter)
{
string value = Value1.Text;
PivotItem pi = MainPivot.SelectedItem;
((WebView)pi.Content).Navigate(new Uri(value,
UriKind.Absolute));
MainPivot.SelectedItem = pi;
TagTextBlock.Text = Value1.Text;
pi.Header = ((WebView)pi.Content).DocumentTitle;
}
}
`
Maybe you need to flush the DataWriter:
await dwriter.FlushAsync();

How to check if Window is already open? Duplicate Windows

I have a button that opens a Window.
If the button is pressed again, it opens a duplicate of the same window.
info = new Info();
info.Owner = Window.GetWindow(this);
info.Show();
How do you check if the Window is already open, and deny a duplicate from being opened again?
I can't use info.ShowDialog() because it disables the Main Window.
Solutions that have not worked:
Info info = new Info();
if (!info.IsActive)
{
info = new Info();
info.Owner = Window.GetWindow(this);
info.Show();
}
Info info = new Info();
if (info.Visibility != Visibility.Visible)
{
info.Owner = Window.GetWindow(this);
info.Show();
}
public static bool IsWindowOpen<T>(string name = "") where T : Window
{
return string.IsNullOrEmpty(name)
? Application.Current.Windows.OfType<T>().Any()
: Application.Current.Windows.OfType<T>().Any(w => w.Name.Equals(name));
}
private void buttonInfo_Click(object sender, RoutedEventArgs e)
{
if (!IsWindowOpen<Window>("Info"))
{
Info info = new Info();
info.Owner = Window.GetWindow(this);
info.Show();
}
}
Create a form only when value is not null.
If the form was closed put the value back to null with the FormClosed event.
public static Info info;
if(info == null){
info = new Info();
info.Show();
}
put an event form close on the info form
private void info_FormClosed(object sender, FormClosedEventArgs e)
{
MainForm1.info = null;
}
It works for me
The sensible approach is to just keep track of the Window instance so you don't have to find it back later. Add a field:
private Info infoWindow;
If it is null then you know that the window doesn't exist yet, so you'll want to create it. Use the Closed event to set the variable back to null. If it is not null then you want to make sure that the window gets restored. So:
private void button_Click(object sender, RoutedEventArgs e) {
if (infoWindow == null) {
infoWindow = new Info();
infoWindow.Closed += (s, ea) => infoWindow = null;
infoWindow.Owner = this; // optional
infoWindow.Show();
}
else {
if (infoWindow.WindowState == WindowState.Minimized) {
infoWindow.WindowState = WindowState.Normal;
}
infoWindow.Activate();
}
}
And you probably also want to close the window automatically when the window that contains the button is closed:
private void Window_Closed(object sender, EventArgs e) {
if (infoWindow != null) infoWindow.Close();
}
You could use .IsLoaded field or bind the .ContentRendered event
Edit 1 -
Window1:
public class Window1 : Window
{
private Info info = null;
private Boolean IsInfoOpened = false;
protected void OpenInfo()
{
if (this.IsInfoOpened) return;
this.info = new Info();
this.info.ContentRendered += delegate { this.IsInfoOpened = true; };
this.info.Closed += delegate { this.IsInfoOpened = false; }
this.info.Show();
}
}

handling backpress event in windows phone 8.1

I want to handled the backpress button in windows phone 8.1 app.I want whenever backpress is pressed navigate to previous page but when backpress is pressed at the second page(after the mainpage) i want the app to exit or asked to exit.
i am using this code to navigate
Windows.Phone.UI.Input.HardwareButtons.BackPressed += HardwareButtons_BackPressed;
}
public bool Handled { get; set; }
private void HardwareButtons_BackPressed(object sender, Windows.Phone.UI.Input.BackPressedEventArgs e)
{
Frame frame = Window.Current.Content as Frame;
if (frame == null)
{
return;
}
if (frame.CanGoBack)
{
frame.GoBack();
e.Handled = true;
}
}
Try the following code. It works for me.
private async void HardwareButtons_BackPressed(object sender, BackPressedEventArgs e)
{
Frame rootFrame = Window.Current.Content as Frame;
e.Handled = true;
var curpage = rootFrame.CurrentSourcePageType.FullName;
if(curpage=="your page name where you want to show dialog")
{
var msg = new MessageDialog("Sure to Exit?");
var okBtn = new UICommand("OK");
var cancelBtn = new UICommand("Cancel");
msg.Commands.Add(okBtn);
msg.Commands.Add(cancelBtn);
IUICommand result = await msg.ShowAsync();
if (result != null && result.Label == "OK")
{
Application.Current.Exit();
}
}
else
{
if (rootFrame.CanGoBack)
{
rootFrame.GoBack();
}
}
}
My understanding to your quesiton is everytime when user what to navigate back to the first page by pressing back button, you want to exit the app. If so, what we need to do is in the first page's OnNavigatedFrom event to check if the NavigationMode is Back. Try the following code:
protected override void OnNavigatedFrom(NavigationEventArgs e)
{
base.OnNavigatedFrom(e);
if(e.NavigationMode == NavigationMode.Back)
{
App.Current.Exit();
}
}
If you want to delete the history of the first navigated page, you can remove it from BackStack, and the second page is considered as first one. Just put this on your mainpage:
protected override void OnNavigatedFrom(NavigationEventArgs e)
{
Frame.BackStack.Remove(Frame.BackStack.First());
base.OnNavigatedFrom(e);
}

Cancel opening link in browser

In my Windows phone application I use RichTextBox element
I have a hyperlink on it, and when user click on it there is a dialog: Do you want to open this link in exteranl browser. If user say no, external browser shouldn't be opened. I cancel navigation but in any case - external browser opens. How can I cancel opening link in browser?
//Constructor
static Helper()
{
var phoneApplicationFrame = Application.Current.RootVisual as PhoneApplicationFrame;
if (Application.Current.RootVisual as PhoneApplicationFrame != null)
{
phoneApplicationFrame.Navigating += new NavigatingCancelEventHandler(NavigationService_Navigating);
}
}
link.Foreground = new SolidColorBrush(Colors.Blue);
link.MouseOverForeground = new SolidColorBrush(Colors.Blue);
link.TargetName = "_blank";
var linkText = new Run() { Text = linkDesc };
link.Inlines.Add(linkText);
link.Click += new RoutedEventHandler(NavidateTo);
private static void NavidateTo(object sender, RoutedEventArgs routedEventArgs)
{
if (MessageBox.Show(
Constants.BrowserNavigating,
"",
MessageBoxButton.OKCancel) == MessageBoxResult.Cancel)
{
StateManager.Set("ExternalBrowser", "true");
}
else
{
StateManager.Set("Browser", "true");
}
}
public static void NavigationService_Navigating(object sender, NavigatingCancelEventArgs e)
{
var res = StateManager.Get("ExternalBrowser");
if (res != null)
{
StateManager.Remove("ExternalBrowser");
e.Cancel = true;
}
}
Rather than have the HyperlinkButton open the link itself, don't specify the NavigationUri but handle the Tap event yourself.
In the eventhandler ask the question and only open the browser if they say yes.
This will be much simpler than trying to cancel something that is already in progress.

Categories

Resources