Got a simple 3 page program, but would like to make a welcome screen that users have to press a button to move to the next page (and start the workflow).
Users will mostly be using a barcode scanner (captures string & hits enter), so I'm trying to avoid buttons that need to be clicked with a mouse.
The setup is basically one MainWindow with a DockPanel in it with a Frame in it.
Pages get loaded to the frame on events(the enter being hit on a textbox). Pages have Grids in them with the standard controls.
I've got the frame in the window navigating to the welcome page, but can't seem to capture a keypress.
What would set I the event on? The Window, the frame, the dockpanel, the page, the grid?
Also, is there a way to specify "any key or click" event, maybe listen for any input action?
I've tried experimenting and looking at documentation but I can't seem to get it.
I created an empty WPF app with a frame and was able to catch a keypress event. Once the app starts I focus the frame. You can do the same once your page loads or when your workflow starts over.
<Frame Loaded="FrameworkElement_OnLoaded" KeyUp="UIElement_OnKeyUp">
<Frame.Content>
<Page>
<Label Content="Hello"></Label>
</Page>
</Frame.Content>
</Frame>
private void FrameworkElement_OnLoaded(object sender, RoutedEventArgs e)
{
((Frame)sender).Focus();
}
private void UIElement_OnKeyUp(object sender, KeyEventArgs e)
{
MessageBox.Show("Key pressed");
}
Add this to your designer:
this.myForm.KeyDown += new System.Windows.Forms.KeyEventHandler(this.myForm_KeyDown);
And add this to your Form's code
private void myForm_KeyDown(object sender, KeyPressEventArgs e)
{
if(KeysDown().Any())
{
currentForm.Hide();
nextForm,Show();
}
}
Related
I have an issue that I am trying to resolve. I have two WPF windows. Those windows house the pages with content. My problem is not navigating page to page but rather window to window. here is an example of the code:
LoginPortal Design
<Grid>
<Frame x:Name="MainFrame" NavigationUIVisibility="Hidden"/>
</Grid>
LoginPortal Code
public LoginPortalMain()
{
InitializeComponent();
MainFrame.Navigate(new Uri("/Pages/LoginPortal.xaml", UriKind.RelativeOrAbsolute));
}
This is my Login portal that houses 4 buttons. Each button opens the second window which is houses several pages.
private void BtnSales_Click(object sender, RoutedEventArgs e)
{
var w = Application.Current.Windows[0];
w.Hide();
MainWindow mn = new MainWindow();
mn.Content = new SalesPage();
mn.Show();
}
When this button is clicked it opens the second WPF Window which is where several pages are housed. There is no problem with navigation. The problem starts when I wire the Closing event from the MainWindow to go back to the LoginPortalMain
private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
LoginPortalMain lgm = Application.Current.MainWindow as LoginPortalMain;
lgm.Show();
}
It then goes back to the start again. Now my problem is if I click on the same button again. It just duplicates everything. Then on closing anything it just adds new windows. If I then exit out of any window, it throws an error in picture below. My question is, is there a way to either dispose of the navigation once the MainWindow is closed. So there is no duplicate windows once you close the mainWindow a second time. I have used navigation before on a single window but not on multiple windows.
I may have to rethink this whole structure and use custom UserControls and figure out the animation sequence from Pages to UserControls. However, any help would be greatly appreciated.
enter image description here
enter image description here
enter image description here
enter image description here
enter image description here
If you only want to be able to open one instance of the new window try showing and hiding a single window instance.
When the open window button is pressed create the window if need and show it.
private OtherWindow mOtherWindow;
private void OpenWindowButtonClick(object sender, RoutedEventArgs e)
{
mOtherWindow ??= new OtherWindow(); //initialize child window on first call
mOtherWindow.Show();
}
When the other window is closed hide it and cancel the close request. You could also reset the other window state here for the next time it is shown.
private void OtherWindowClosingEvent(object sender, System.ComponentModel.CancelEventArgs e)
{
((Window)sender).Hide();
Application.Current.MainWindow.Activate();
e.Cancel = true;
}
I have a page which is a child of a CarouselPage. The page has ImageButtons on it which have pressed and released events.
Something happens when the pressed event fires and it stops when the released event fires.
The problem I have is when you push a button down and then slide left or right causing the carousel animation to take effect the released event from the currently held button no longer fires.
This is not an issue if the user switches to another page as I can use the page changed event to tidy up.
The problem is if you start sliding to the next page and then stop it pings back to the current one and no event fires at all.
I have looked for events that may fire in this scenario but have not found anything yet.
I need a way to either get the released events to still fire or a means of detecting a partial carousel scroll so that I can do the same from another event.
I am using the latest version of everything, testing in the emulator and developing solely for Android.
ImageButton definition
<ImageButton Grid.Row="0" Grid.Column="1" Source="up.png" Pressed="ImageButton_OnPressed" Released="ImageButton_OnReleased" BackgroundColor="Transparent" CommandParameter="U"></ImageButton>
Code behind
private void ImageButton_OnPressed(object sender, EventArgs e)
{
// Action start action
}
private void ImageButton_OnReleased(object sender, EventArgs e)
{
// Action stop action
}
Page Change event on CarouselPage
private void MainPage_OnCurrentPageChanged(object sender, EventArgs e)
{
// Action stop all actions on page
}
While I was adding code to scroll event of a panel in c#, I found a strange behavior.
I have added a panel and inside the panel (auto-Scroll = true) there is a groupbox.
As shown below clicking the scroll moves scroll bar to a small distance.
At the same time, when I add a message box in the event to display a notification that a scroll has taken place, multiple message box are popping out.
Why is that?
I have already planned to add some logic when scrolling, but if it occurs multiple times then how it could be possible?
Here is the event handler:
private void panel1_Scroll_1(object sender, ScrollEventArgs e)
{
MessageBox.Show("ScrollBar is clicked");
}
This is just how scroll event works, it fires many times while the panel is scrolling.
Try ScrollEventArgs.Type EndScroll which should be the last scroll event.
private void panel1_Scroll_1(object sender, ScrollEventArgs e)
{
if (e.Type == ScrollEventType.EndScroll)
MessageBox.Show("ScrollBar is clicked");
}
If above doesn't help for your case you will need to handle those multiple events by using one of approaches explains in this thread.
My Windows 8 XAML page contains two controls: Image and TextBox. When the user doubletaps Image, I want to move the focus to TextBox so that the virtual keyboard is automatically displayed.
The problem: The TextBox control correctly receives the focus, but only for 0.1 seconds. The focus then moves to somewhere else and no keyboard is displayed.
Through the events I can see that GotFocus and and LostFocus events are raised for the TextBox. The Image control doesn't have other event handlers as it only handles the DoubleTapped event:
private void CurrentPage_OnDoubleTapped(object sender, DoubleTappedRoutedEventArgs e)
{
e.Handled = true;
this.PageNumberTextBox.Focus(FocusState.Keyboard);
}
Why doesn't the focus "stick"? Where and why the focus goes?
Update:
With this very helpful helper I can see that the focus moves to ScrollViewer [Windows.UI.Xaml.Controls.Border]. I presume this is something which is built-in (maybe used by the RootFrame?) as I don't have any ScrollViewers added to the page and because this control seems to fill the whole screen.
So, the problem seems to be caused by event bubbling: Image-control is first to receive the event and then the control behind it. But why? Shouldn't e.Handled = true prevent this behavior?
Modifying the code to look like this doesn't help:
private void CurrentPage_OnDoubleTapped(object sender, DoubleTappedRoutedEventArgs e)
{
e.Handled = true;
//this.PageNumberTextBox.Focus(FocusState.Keyboard);
}
After the doubletap, the mystery ScrollViewer has the focus.
Update 2:
The problem might be related to Image-control. I created the following spike:
<Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Image Grid.Row="0" DoubleTapped="UIElement_OnDoubleTapped" Tapped="UIElement_OnTapped"
Source="http://upload.wikimedia.org/wikipedia/commons/1/1c/Squirrel_posing.jpg" Stretch="Fill"/>
<TextBox x:Name="MyBox" Grid.Row="1"/>
</Grid>
The spike app is created using the Blank template. In code behind I set the e.Handled = true for both Tapped and DoubleTapped:
private void UIElement_OnDoubleTapped(object sender, DoubleTappedRoutedEventArgs e)
{
e.Handled = true;
}
private void UIElement_OnTapped(object sender, TappedRoutedEventArgs e)
{
e.Handled = true;
}
The problem: When I tap the Image, the focus is always given to this mystery ScrollViewer. Here's some screenshots:
When I click the TextBox which takes the bottom half of the view, the focus correctly moves to the TextBox (the control with focus is highlighted and the control's name is displayed in top left):
When I click the Image at the top, the Image doesn't receive the focus. Instead, it's given to the mystery ScrollViewer, which seems to fill the whole screen:
So even though I've set the Image to handle both Tapped and DoubleTapped, the Image control doesn't receive the focus.
I think your problem is the double-tap is within a series of events that end up changing the focus. What you could try is to "queue" a focus change by asynchronously calling the Focus method. For example:
Task.Factory.StartNew(
() => Dispatcher.RunAsync(CoreDispatcherPriority.Low,
() => PageNumberTextBox.Focus(FocusState.Keyboard)));
I know it looks a little stupid but what this does is to try to put the code that changes the focus after all the other events in the queue.
I have a small (but annoying) problem.
You can quickly replicate it by doing the following:
New Project > Windows Store > Blank App (XAML)
Add a button to the grid. This also works with the default style. (note: TextButtonStyle is defined in SimpleStyles.xaml)
<Button Click="Click" Style="{StaticResource TextButtonStyle}" Content="Page 2"/>
Add the function to the code behind file:
private void ButtonBase_OnClick(object sender, RoutedEventArgs e)
{
Frame.Navigate(typeof (Page2));
}
Next create another page, add the button, and navigate back to the MainPage in the Click event.
Next set on both pages add NavigationCacheMode="Enabled". For convenience set one of the buttons to be Left aligned and the other one Right.
Run the app. Move the mouse over the button. The state changes to reflect this. Click the button. Again the color changes. On the second page, do the same. On returning to the first page, the button is still in it's "PointerOver" visual state, since there was no PointerExited event called on the button.
How can I fix this? VisualStateMananger.GoToState() doesn't work.
We encountered a similar issue. We noticed that the state 'resets' when you hide the control.
We solved it, the dirty way:
void GridView_ItemClick(object sender, ItemClickEventArgs e)
{
var ctrl = this.ItemContainerGenerator.ContainerFromItem(e.ClickedItem);
((Control)ctrl).Visibility = Visibility.Collapsed;
((Control)ctrl).Visibility = Visibility.Visible;
}
Maybe you could try to do the following (didn't test this):
private void ButtonBase_OnClick(object sender, RoutedEventArgs e)
{
((Control)sender).Visibility = Visibility.Collapsed;
((Control)sender).Visibility = Visibility.Visible;
Frame.Navigate(typeof (Page2));
}