I am developing a UWP application in which I have several XAML controls(buttons, textblocks, checkboxes, etc). Ideally, The final user of this app should be able to navigate between these controls ONLY USING MOUSE WHEEL(this is a medical device UI in which only a mouse wheel will be available on top of the monitor). Now my question is that how to force this application use mouse wheel as the primary source of navigation between controls?
Some more feedbacks:
1.Right now, when I run my application in visual studio, I just see mouse pointer and of course buttons are sensitive to mouse clicks but in order to initiate an event, I have to hover to that element and click. MOUSE WHEEL IS NOT WORKING by default to navigate and select controls.
2.when I sideload this UWP application on a raspberry pi device and run the application there, the only way to navigate between controls is using an attached keyboard(possible to navigate and select controls using it). AGAIN ATTACHED MOUSE WHEEL IS NOT WORKING HERE.
an example of controls I use in my code is this:
xaml code:
<Button x:Name="button1" Grid.Column="0" Grid.Row="0" Content="Button1" Click="button1_click" />
<Button x:Name="button2" Grid.Column="1" Grid.Row="0" Content="Button2" Click="button2_click" />
<Button x:Name="button3" Grid.Column="2" Grid.Row="0" Content="Button3" Click="button3_click" />
c# code:
private void button1_click(object sender, Windows.UI.Xaml.RoutedEventArgs e)
{
//do sth
}
private void button2_click(object sender, Windows.UI.Xaml.RoutedEventArgs e)
{
//do sth
}
private void button3_click(object sender, Windows.UI.Xaml.RoutedEventArgs e)
{
//do sth
}
in above code, it is not possible to navigate between three buttons using mouse wheel(both in visual studio and raspberry pi).
AGAIN ATTACHED MOUSE WHEEL IS NOT WORKING HERE.
How did you register the 'MOUSE WHEEL' event in your code? It worked well on my side.
Please see the following code sample:
<StackPanel x:Name="root" >
<Button x:Name="button1" Grid.Column="0" Grid.Row="0" Content="Button1" Click="button1_click" />
<Button x:Name="button2" Grid.Column="1" Grid.Row="0" Content="Button2" Click="button2_click" />
<Button x:Name="button3" Grid.Column="2" Grid.Row="0" Content="Button3" Click="button3_click" />
</StackPanel>
public MainPage()
{
this.InitializeComponent();
Window.Current.CoreWindow.PointerWheelChanged += CoreWindow_PointerWheelChanged;
}
private async void CoreWindow_PointerWheelChanged(Windows.UI.Core.CoreWindow sender, Windows.UI.Core.PointerEventArgs args)
{
Debug.WriteLine(args.CurrentPoint.Properties.MouseWheelDelta);
UIElement element;
if (args.CurrentPoint.Properties.MouseWheelDelta > 0)
{
element = FocusManager.FindNextFocusableElement(FocusNavigationDirection.Up);
if (element == null)
{
element = FocusManager.FindLastFocusableElement(root) as UIElement;
}
var result = await FocusManager.TryFocusAsync(element, FocusState.Keyboard);
Debug.WriteLine((element as Button).Content.ToString() + " focused: " + result.Succeeded);
}
else
{
element = FocusManager.FindNextFocusableElement(FocusNavigationDirection.Down);
if (element == null)
{
element = FocusManager.FindFirstFocusableElement(root) as UIElement;
}
var result = await FocusManager.TryFocusAsync(element, FocusState.Keyboard);
Debug.WriteLine((element as Button).Content.ToString() + " focused: " + result.Succeeded);
}
}
just to give you an idea.
First you should handle tabIndex properties of all of those Items on form and set their order. also whats being triggered with you will move with the tab in your case with mouse wheel gonna be "Focused" or "GotFocus" method. so an event like "GotFocus" will be needed. also you need to handle mouse wheel movements(up or down). you may google about how to override TabIndex property from tab Key to Mouse wheel as you want.
Related
I am working on a Kinect application for WPF (Kinect 2). I am using the KinectRegion to trigger some buttons, but i want to trigger the buttons on hover and not on click. what is the best way to achieve this? I have tried with MouseEnter and MouseLeave with no luck. My goal is that when the user hovers on a button an animation is played and then after 2 seconds the buttons is clicked. I would appreciate any help!
<k:KinectRegion x:Name="kinectRegion" >
<Grid Background="White" Name="gridTest">
<k:KinectUserViewer Height="400" Width="300" HorizontalAlignment="Center" VerticalAlignment="Top" DefaultUserColor="#FFF93636" EngagedUserColor="#FF395913" />
<Button Name="buttonStartSpel" Width="400" Height="200" Margin="0,800,0,0" VerticalAlignment="Top" HorizontalAlignment="Center" Content="Start het spel" Style="{StaticResource KinectCustomButton}" MouseEnter="buttonStartSpel_MouseEnter" MouseLeave="buttonStartSpel_MouseLeave"></Button>
</Grid>
</k:KinectRegion>
UPDATE -
Looking for multiple ways to solve this i came up with this solution:
We executed the code on window load.
void KinectPointerPointSample_Loaded(object sender, RoutedEventArgs e)
{
// Listen to Kinect pointer events
KinectCoreWindow kinectCoreWindow = KinectCoreWindow.GetForCurrentThread();
kinectCoreWindow.PointerMoved += kinectCoreWindow_PointerMoved;
}
private void kinectCoreWindow_PointerMoved(object sender, KinectPointerEventArgs args)
{
KinectPointerPoint kinectPointerPoint = args.CurrentPoint;
bool isEngaged = kinectPointerPoint.Properties.IsEngaged;
if (isEngaged)
{
System.Drawing.Point mousePt = new System.Drawing.Point((int)(kinectPointerPoint.Position.X * kinectRegion.ActualWidth - 80), (int)(kinectPointerPoint.Position.Y * kinectRegion.ActualHeight));
System.Windows.Forms.Cursor.Position = mousePt;
}
}
Noticed that the mouse pointer does not have the exact same position of the handpointer, i have tested that with negative results. Thats why i placed the mouse pointer slightly left to the handpointer (80 pixs to be exact). You can play around depending on your project. Finally we hide the mouse pointer with the following code:
this.Cursor = Cursors.None;
Now we can use the OnMouseEnter and OnMouseLeave events...I hope this helps anyone having this problem.
I'm doing integration tests with help of UI Automation. I need to check if a user control has focus (IsFocused = true). Is it possible ? I tried using AutomationElement.FocusedElement, but as far as I checked it returns different control (probably outside of my app).
My control:
<UserControl GotFocus="UserControl_GotFocus" Focusable="True">
<DockPanel>
<Button DockPanel.Dock="Right" Content=">" IsTabStop="False" Focusable="False" Click="TextButton_Click" />
<TextBox Text="{Binding Text}" x:Name="textBox" />
</DockPanel>
code behind:
private void UserControl_GotFocus(object sender, RoutedEventArgs e)
{
textBox.Focus();
Keyboard.Focus(textBox);
}
You can get the AutomationElement associated with the control you care about, then get the AutomationElement.FocusedElement and compare them. If they are the same, then it is focused.
Also, AutomationElement.Current should have a HasKeyboardFocus property. You can see if that gives you the information you need.
I have the following button on my page:
<AppBarButton Grid.Column="0" x:Name="backButton" Icon="Back" Margin="10,26,0,-1"
Command="{Binding NavigationHelper.GoBackCommand, ElementName=pageRoot}"
IsEnabled="True"
Visibility="Visible"
Foreground="Green"
AutomationProperties.Name="Back"
AutomationProperties.AutomationId="BackButton"
AutomationProperties.ItemType="Navigation Button" Grid.Row="1" Grid.RowSpan="2" VerticalAlignment="Stretch"
/>
The button appears but clicking it does nothing. This was placed on the second of two pages in the application. I followed the instructions in NavigatonHelper.cs to get it wired up to my second page, but haven't done anything special in the first. What am I missing?
I even tried tying the Click property to a custom function:
public void ClickGoBack(object sender, RoutedEventArgs routedEventArgs) {
this.Frame.Navigate(typeof(HubPage));
}
But this never even got hit when I clicked the button.
Have you checked the Click existed in AppBarButton defined?
like: <AppBarButton ... Click="ClickGoBack"></AppBarButton>
and you should use
if (this.Frame.CanGoBack)
{
this.Frame.GoBack();
}
instead of
this.Frame.Navigate(typeof(HubPage));
You could do this instead much more easier for me.
<AppBar><Button Style="{StaticResource BackButtonStyle}" Click="Click1"></Button>
</AppBar>
and for your code behind...
private void ButtonBase_OnClick(object sender, RoutedEventArgs e)
{
Frame.GoBack();
}
Something was put after the top grid in the XAML that overlapped the button - I didn't understand the concept of "natural order" until now. Thanks for the help everyone!
As hard as I try I can not find how to reference my tag in my CS file.
In my XAML file I have the following
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
<TextBlock Text="User Id" Margin="30" Foreground="White" FontSize="25" />
<TextBox x:Name="logInUserIdText" IsSpellCheckEnabled="True" Height="40" Margin="13,1" Width="408" InputScope="EmailSmtpAddress" FontFamily="Global User Interface" KeyDown="logInUserIdKeyDown" Tag="1" />
</StackPanel>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
<TextBlock Text="Password" Margin="20" Foreground="White" FontSize="25" />
<PasswordBox x:Name="logInPasswordText" IsPasswordRevealButtonEnabled="True" Height="40" Margin="5,1" Width="408" KeyDown="logInPasswordKeyDown" Tag="2"/>
</StackPanel>
Now in my CS file I have the following
private void logInUserIdKeyDown(object sender, KeyRoutedEventArgs e)
{
if (e.Key == VirtualKey.Enter)
{
logInUserIdString = logInUserIdText.Text;
Debug.WriteLine("aa");
logInPasswordText.Focus(FocusState.Programmatic);
}
}
private void logInPasswordKeyDown(object sender, KeyRoutedEventArgs e)
{
if (e.Key == VirtualKey.Enter)
{
logInPasswordString = logInPasswordText.Password;
Debug.WriteLine("bb");
}
}
And the issue is that regardless of which box is in focus, if I hit ENTER on the keyboard both methods get fired and the output is aa bb which are the debug statements in each method.
So I assume that since I set the tag value in XAML I should be able to do something like
if (e.Key == Virtual.Enter)&&(e.Tag == 1)
Debug.WriteLine("loginuserid method only called");
But I can not, it wont let me reference the tag in the CS file. Why not?
Any help would be much appreciated.
What happen to you seems impossible. To inspect more closely, try to run your application in debug mode, put breakpoint at the beginning of both method. Then, when execution hit breakpoint, you can see which control trigger that event from sender parameter (I prefer to use visual studio watch window to see content of variable).
The same concept can be used to get Tag value :
var s = (FrameworkElement)sender;
var tagValue = (string)s.Tag;
But I suggest to fix the original problem rather than workaround it with using Tag value.
In my app there is a canvas with a small image (not taking up entire space of canvas).
when user clicks on image and drags inside the canvas, it traces the path with a black line. Till here everything works. Now, I want the path to be deleted as soon as the user releases the hold on the mouse. I am using MouseLeftButtonUp on the canvas to detect the mouse release. Now problem is this is working randomly. sometimes it fires and sometimes it does not. Kindly help.
XAML:
<Canvas Height="400" HorizontalAlignment="Center" Margin="10,10,0,0" Name="canvas1" VerticalAlignment="Center" Background="Aqua" Width="400">
<Image Canvas.ZIndex="30" Canvas.Left="10" Canvas.Top="10" Height="20" Name="dot1" Stretch="Uniform" Width="20" Source="/BoxIt;component/Images/dot.png" MouseLeftButtonDown="dot_MouseLeftButtonDown" />
</Canvas>
C#:
this.canvas1.MouseMove += new MouseEventHandler(canvas1_MouseMove);
this.canvas1.MouseLeftButtonUp += new MouseButtonEventHandler(canvas1_MouseLeftButtonUp);
Eventhandler in C# :
void canvas1_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
// code to delete the path
}
In Windows Phone we are advised to use the Tap, Hold and Manipulation* methods instead of the Mouse related events.
Please read this for more information.