In WP8, how to hide the soft keyboard when the listbox is scrolled?
Is there an event to detect when the listbox is scrolled?
So I duplicated your problem in a Windows Phone 8 application.
I tested this solution and it does in fact work.
What you want to do is target the ListBox.ManipulationStarted event
Inside this event just simply do this.Focus();
This will cause the soft keyboard to retreat
Your final product might look like this
public page2()
{
InitializeComponent();
for (int x = 0; x < 100; x++)
{
lb.Items.Add(x);
}
lb.ManipulationStarted += lb_ManipulationStarted;
}
void lb_ManipulationStarted(object sender, System.Windows.Input.ManipulationStartedEventArgs e)
{
this.Focus();
}
So my round about way of answering your question is no, there is no scroll event for the listbox. Anything you do will be a hack similar to this but it DOES work.
Related
I'm currently developing an Universal Application, but here is a problem. I have a Frame with the TextBox for User Phone Number.
So, I want to change the height of my LayoutRoot (GRID) so it can fits in the free space.
I'm using InputPane.GetForCurrentView().Showing and InputPane.GetForCurrentView().Hiding for that purposes.
Here is my code.
public UserRegistrationAuthorization_PhoneNumber()
{
this.InitializeComponent();
LayoutRootInitialHeight = LayoutRoot.ActualHeight;
InputPane.GetForCurrentView().Showing += UserRegistrationAuthorization_PhoneNumber_Showing;
InputPane.GetForCurrentView().Hiding += UserRegistrationAuthorization_PhoneNumber_Hiding;
}
private void UserRegistrationAuthorization_PhoneNumber_Showing(InputPane sender, InputPaneVisibilityEventArgs args)
{
LayoutRoot.Height = LayoutRoot.ActualHeight - args.OccludedRect.Height;
LayoutRoot.VerticalAlignment = VerticalAlignment.Top;
args.EnsuredFocusedElementInView = true;
}
private void UserRegistrationAuthorization_PhoneNumber_Hiding(InputPane sender, InputPaneVisibilityEventArgs args)
{
// TODO: Get rid of that shit
LayoutRoot.Height = LayoutRootInitialHeight;
args.EnsuredFocusedElementInView = false;
}
When I click outside the TextBox keyboard hides and leaves after that a black hole on the screen. 2
But, the most interesting is that when I press that physical Back Button on my Lumia, keyboard hides normally and my LayoutRoot gets the Frame's initial height.
Is it a bug or I'm doing something wrong?
It happens because by the time you saving your LayoutRootInitialHeight in the constructor, LayoutRoot actually isn't loaded and it's ActualHeight == 0. Then you setting LayoutRoot.Height to 0, so it becomes not visible. So you should probably save your LayoutRootInitialHeight in LayoutRoot's Loaded event handler.
I would also suggest you not to change LayoutRoot's height at all. It causes your whole visual tree to be rendered from scratch and it's bad practise in general. Instead, modify RenderTransform of all necessary elements so they get moved to appropriate positions. RenderTransform is the right way to handle movements and animations on the screen, and you can achieve some nice visual effects with Next button moving up same as keyboard.
Roughly your code can look like this:
<Button Content="Next" VerticalAlignment="Bottom" HorizontalAlignment="Stretch" HorizontalContentAlignment="Center">
<Button.RenderTransform>
<CompositeTransform x:Name="NextButtonTransform" TranslateY="0"/>
</Button.RenderTransform>
</Button>
...
private void UserRegistrationAuthorization_PhoneNumber_Showing(InputPane sender, InputPaneVisibilityEventArgs args)
{
NextButtonTransform.TranslateY = -300;
EnsuredFocusedElementInView = true;
}
private void UserRegistrationAuthorization_PhoneNumber_Hiding(InputPane sender, InputPaneVisibilityEventArgs args)
{
NextButtonTransform.TranslateY = 0;
args.EnsuredFocusedElementInView = false;
}
And more complicated way is to run some storyboard which makes your Next button move up and down in same speed with keyboard, always appearing on top of it. Although, since InputPane.GetForCurrentView().Showing gets fired after keyboard already shown fully, you should hook up all animations to TextBox.GotFocus and TextBox.LostFocus events. On mobile, keyboard is always shown when text box has focus, so it will work nicely.
I have a CaptureElement in my WP8.1 App, My CaptureElement Stuck on one frame if I do below steps:
Open that page which have capture element, it shows my camera preview.
Press and hold hardware back button of phone. Recent apps will be shown on screen.
Don't tap on any app just again press hardware back button one time.
It will take me back to capture element screen but now the preview is showing last frame when I press and hold back button.
I have tried this on default camera app of phone and it works ok but flicks a little bit, seems that they have handled it.
How can I handle it in my application.
By surfing on internet I came to know that this suspends the application so I have to handle suspension states.
Just adding these simple lines, it worked perfectly :)
public MediaCapture()
{
this.InitializeComponent();
this.navigationHelper = new NavigationHelper(this);
Application.Current.Resuming += App_resuming;
Application.Current.Suspending += App_Suspending;
Windows.Phone.UI.Input.HardwareButtons.BackPressed += HardwareButtons_BackPressed;
}
async void App_Suspending(object sender, Windows.ApplicationModel.SuspendingEventArgs e)
{
if (captureManager != null)
{
await captureManager.StopPreviewAsync();
captureManager.Dispose();
captureManager = null;
}
}
private void App_resuming(object sender, object e)
{
if (Frame.Content == this)
{
InitializeCamera();
}
}
When you click or tap a button, it gives it focus, so that when you push the spacebar or Enter, it triggers the button again. I don't want that to happen.
I tried this: button1.Focus(Windows.UI.Xaml.FocusState.Unfocused);
But the unwanted behavior still happens (pushing the spacebar or Enter triggers the button again). I also tried setting focus to another button using the Programmatic and Keyboard FocusStates but that doesn't fix it either.
Any help, especially an explanation of why this is happening, would be greatly appreciated.
You can set the TabStop property to False, but be aware that doing this disallows user from using the button by keyboard.
<Button Content="Click Me By Pointer!" IsTabStop="False"/>
Update
As msdn states:
You can't remove focus from a control by calling this method with FocusState.Unfocused as the parameter. This value is not allowed and causes an exception. To remove focus from a control, set focus to a different control.
So another way to achieve this, is setting focus to previously focused element when the button is about to get focus by pointer. Unfortunatly the GettingFocus event is not working for the Button class (maybe because final version is not released yet?) so we should use GotFocus event, it's ugly it but works.
bool moveFocus = false;
public MainPage() {
this.InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e) {
if (moveFocus) {
UIElement focusedElement = FocusManager.FindNextFocusableElement(FocusNavigationDirection.Right);
if (focusedElement is Control) {
((Control)focusedElement).Focus(FocusState.Programmatic);
}
}
}
private void Button_GotFocus(object sender, RoutedEventArgs e) {
Button button = (Button)sender;
moveFocus = (button.FocusState == FocusState.Pointer);
}
Note that I passed FocusNavigationDirection.Right to FocusManager.FindNextFocusableElement to get an element in right, I should have used FocusNavigationDirection.Previous instead to get previous element but it returns null for unknown reason.
None of my screen-touch events (ManipulationStarted, MouseLeftButtonDown, MouseMove, Tap etc.) are fired when stopping or reversing a scroll fling on a ScrollViewer. How do I capture a screen-touch event even when this happens?
These events are fired OK after the ScrollViewer has completely stopped flinging, just not when stopping or reversing an existing fling.
EDIT: I need to get the actual element that was touched.
I think you can try to make use of FrameReported event, in which you can read gesture from TouchPanel. Simple example can look like this:
using Microsoft.Xna.Framework.Input.Touch;
using Microsoft.Xna.Framework;
public MainPage()
{
InitializeComponent();
TouchPanel.EnabledGestures = (GestureType)1023; // read all gestures
Touch.FrameReported += Touch_FrameReported;
}
private void Touch_FrameReported(object sender, TouchFrameEventArgs e)
{
if (TouchPanel.IsGestureAvailable)
{
GestureSample gesture = TouchPanel.ReadGesture();
float Xposition = gesture.Position.X;
float Yposition = gesture.Position.Y;
}
}
Depending on your purpose you can enable some gestures and read various properties from them.
I have got some Rectangles, what I'm trying to implement is:
user touch the screen, he could slide between Rectangles. then his finger Lift off, and the last touched rectangle is selected.
(Lift off outside rectangle will trigger nothing)
Just like my lumia 920's keyboard, once you recognized that your finger was in a wrong place, you could slide to the right place, lift off, and the right character show on the screen.
many thanks to you heroes!
That's trickier than it seems, as the MouseLeftButtonUp event will be triggered only if the MouseLeftButtonDown has first been triggered on the control.
I see two ways to achieve this result:
Assign the same MouseLeftButtonDown and MouseLeftButtonUp event handler to all your rectangles. In the MouseLeftButtonDown, call the CaptureMouse method (it tells the control to continue tracking the mouse events even if the cursor isn't on top of the control anymore):
private void MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
((UIElement)sender).CaptureMouse();
}
In the MouseLeftButtonDown, release the mouse, then use the VisualTreeHelper.FindElementsInHostCoordinates to find the rectangle on which the cursor was when the even was triggered:
private void MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
var element = (UIElement)sender;
element.ReleaseMouseCapture();
var mouseUpRectangle = VisualTreeHelper.FindElementsInHostCoordinates(e.GetPosition(this), this.ContentPanel)
.OfType<Rectangle>()
.FirstOrDefault();
if (mouseUpRectangle != null)
{
Debug.WriteLine("MouseUp in " + mouseUpRectangle.Name);
}
}
(replace ContentPanel by the name of the container in which you've put all your controls)
Not tested but it might work. Subscribe to the MouseLeftButtonUp event of the container in which you've put all your rectangles. Then use the same logic to retrieve the rectangle at the coordinates of the pointer:
private void MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
var mouseUpRectangle = VisualTreeHelper.FindElementsInHostCoordinates(e.GetPosition(this), this.ContentPanel)
.OfType<Rectangle>()
.FirstOrDefault();
if (mouseUpRectangle != null)
{
Debug.WriteLine("MouseUp in " + mouseUpRectangle.Name);
}
}
You can find more information in that article I wrote a few months ago.