I am looking to understand gesture or horizontal swipe event in windows phone 8.1. I have below code which works fine but don't how to understand the status of swipe. Whether it is right swipe or left swipe. So my question is How to identify swipe right and left?
void MainPage_PointerReleased(object sender, PointerRoutedEventArgs e)
{
var ps = e.GetIntermediatePoints(null);
if (ps != null && ps.Count > 0)
{
gr.ProcessUpEvent(ps[0]);
e.Handled = true;
gr.CompleteGesture();
}
}
void gr_CrossSliding(Windows.UI.Input.GestureRecognizer sender, Windows.UI.Input.CrossSlidingEventArgs args)
{
//How to know you swipe left and right
}
void MainPage_PointerMoved(object sender, PointerRoutedEventArgs e)
{
gr.ProcessMoveEvents(e.GetIntermediatePoints(null));
e.Handled = true;
}
void MainPage_PointerPressed(object sender, PointerRoutedEventArgs e)
{
var ps = e.GetIntermediatePoints(null);
if (ps != null && ps.Count > 0)
{
gr.ProcessDownEvent(ps[0]);
e.Handled = true;
}
}
And my constructor
Windows.UI.Input.CrossSlideThresholds cst = new Windows.UI.Input.CrossSlideThresholds();
cst.SelectionStart = 2;
cst.SpeedBumpStart = 3;
cst.SpeedBumpEnd = 4;
cst.RearrangeStart = 5;
gr.CrossSlideHorizontally = true;
gr.CrossSlideThresholds = cst;
gr.CrossSliding += gr_CrossSliding;
gr.GestureSettings = GestureSettings.CrossSlide;
One idea is to remember where was the first point pressed and then, upon release, check relesed position and compare with the rememered one. This should allow to idetify in which direction user has moved his finger.
Also if it would be possible, you can also think of using Velocities when using manipulation events - example at this post.
Related
I'm building a runtime designer for Winforms. The goal of this designer is to move controls in their container (e.g. a Form or a Panel).
When I move one control at a time everything work perfect. When I select multiple controls, things go wrong, but not always:
When I select two Buttons, the move works OK, but when I select a Label and a TextBox, the label moves in the wrong direction.
Here is an example what happens: https://www.screencast.com/t/sPaH4VNr
Here's my code:
protected virtual void ControlMouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
IsMouseDown = true;
Point startPosition = Control.PointToScreen(new Point(e.X, e.Y));
OffsetMove = new Point();
OffsetMove.X = Control.Location.X - startPosition.X;
OffsetMove.Y = Control.Location.Y - startPosition.Y;
}
else
{
IsMouseDown = false;
}
}
protected virtual void ControlMouseMove(object sender, MouseEventArgs e)
{
this.Control.Cursor = IsMovable && IsMoveAllowed(e) ? Cursors.SizeAll : Cursors.Default;
if (IsMouseDown && this.Control.Cursor == Cursors.SizeAll)
{
foreach (var control in Parent.SelectedControls.Select(sc => sc.Control))
{
Point newPoint = control.PointToScreen(e.Location);
newPoint.Offset(OffsetMove);
if (control.Location != newPoint)
{
control.Location = newPoint;
control.Parent.Invalidate();
}
}
}
}
I hope someone sees what I am doing wrong.
Thanks in advance.
is there any way to get swipe gesture same as windows phone 8 with wptoolkit.
Because wptoolkit nuget package is not available for uwp, so i am unable to get similar swipe gesture on UWP
In windows Phone 8 with the help of WPtoolkit nugetget package
i placed this
<toolkit:GestureService.GestureListener>
<toolkit:GestureListener Flick="OnSwipe"/>
</toolkit:GestureService.GestureListener>
over text block, so i can swipe left to right or right to left over textbox1.
and swipe gesture help me to implement this
private static int i;
private void OnSwipe(object sender, FlickGestureEventArgs e)
{
if (e.HorizontalVelocity < 0)
{
i++;
txtBox1.Text = i.ToString();
}
if (e.HorizontalVelocity > 0)
{
i--;
txtBox1.Text = i.ToString();
}
}
i tried Manupulation method with scrollViewer on uwp but it continuously increase the value untill it scroll viewer stopped
and this is codes
private static int i;
private Point initialpoint;
private void scrollview_ManipulationStarted(object sender, ManipulationStartedRoutedEventArgs e)
{
initialpoint = e.Position;
}
private void scrollview_ManipulationDelta(object sender, ManipulationDeltaRoutedEventArgs e)
{
if (e.IsInertial)
{
Point currentpoint = e.Position;
if (currentpoint.X - initialpoint.X >= 2)
{
i++;
txtBox1.Text = i.ToString();
}
if (currentpoint.Y - initialpoint.Y >= 2)
{
i--;
txtBox1.Text = i.ToString();
}
}
}
Any other way to implement same functionality.
Actually you don't need to handle ManipulationStarted in this case and you don't need the initialPoint property. Assuming you have already defined your ScrollViewer's ManipulationMode to the following
ManipulationMode="TranslateX,TranslateInertia,System"
Then you simply use e.Cumulative.Translation.X to tell how long you have swiped in total
private void scrollview_ManipulationCompleted(object sender, ManipulationCompletedRoutedEventArgs e)
{
if (e.IsInertial)
{
var swipedDistance = e.Cumulative.Translation.X;
if (Math.Abs(swipedDistance) <= 2) return;
if (swipedDistance > 0)
{
i++;
}
else
{
i--;
}
txtBox1.Text = i.ToString();
}
}
Update
Now that I understand your question better, I think you should handle gesture manipulation on the TextBox itself. If you want instant feedback, simply subscribe to the ManipulationDelta event and create a flag to only run the swipe logic once per touch.
private bool _isSwiped;
private void txtBox1_ManipulationDelta(object sender, ManipulationDeltaRoutedEventArgs e)
{
if (e.IsInertial && !_isSwiped)
{
var swipedDistance = e.Cumulative.Translation.X;
if (Math.Abs(swipedDistance) <= 2) return;
if (swipedDistance > 0)
{
i++;
}
else
{
i--;
}
txtBox1.Text = i.ToString();
_isSwiped = true;
}
}
private void txtBox1_ManipulationCompleted(object sender, ManipulationCompletedRoutedEventArgs e)
{
_isSwiped = false;
}
Make sure you move all the handlers and set the ManipulationMode onto the TextBox.
<TextBox x:Name="txtBox1"
ManipulationMode="TranslateX,TranslateInertia,System"
ManipulationDelta="txtBox1_ManipulationDelta"
ManipulationCompleted="txtBox1_ManipulationCompleted" />
I am currently using a Microsoft.Phone.Map in my Windows 8 Phone App and want to be able stop interactions for changing the zoom level and moving (scrolling) around the map.
I've tried disabling interaction but the problem is I have a layer with Points of Interests that need to be tapped to expand information which doesn't work when I disable the map with IsEnabled = True;
The zoom level is set to this.BigMap.ZoomLevel = 16; to start with and then to try and stop this from changing with interaction I did this:
void BigMap_ZoomLevelChanged(object sender, MapZoomLevelChangedEventArgs e)
{
this.BigMap.ZoomLevel = 16;
}
But it means that I get a rather jumpy effect - is there a better way to disable zoom?
And does anyone know how to stop the map moving - I want just the section that fits on the screen to stay put and not let the user move it around.
You can find the map-element's grid, and stop it's zoom and moving manipulations like this:
xaml:
<Grid x:Name="LayoutRoot">
<maps:Map ZoomLevel="10"
x:Name="MyMap"
Loaded="Map_Loaded"
Tap="MyMap_Tap"/>
</Grid>
cs:
private void Map_Loaded(object sender, RoutedEventArgs e)
{
Grid grid = FindChildOfType<Grid>(MyMap);
grid.ManipulationCompleted += Map_ManipulationCompleted;
grid.ManipulationDelta += Map_ManipulationDelta;
}
private void Map_ManipulationDelta(object sender, ManipulationDeltaEventArgs e)
{
// disable zoom
if (e.DeltaManipulation.Scale.X != 0.0 ||
e.DeltaManipulation.Scale.Y != 0.0)
e.Handled = true;
//disable moving
if (e.DeltaManipulation.Translation.X != 0.0 ||
e.DeltaManipulation.Translation.Y != 0.0)
e.Handled = true;
}
private void Map_ManipulationCompleted(object sender, ManipulationCompletedEventArgs e)
{
// disable zoom
if (e.FinalVelocities.ExpansionVelocity.X != 0.0 ||
e.FinalVelocities.ExpansionVelocity.Y != 0.0)
e.Handled = true;
//disable moving
if (e.FinalVelocities.LinearVelocity.X != 0.0 ||
e.FinalVelocities.LinearVelocity.Y != 0.0)
{
e.Handled = true;
}
}
public static T FindChildOfType<T>(DependencyObject root) where T : class
{
var queue = new Queue<DependencyObject>();
queue.Enqueue(root);
while (queue.Count > 0)
{
DependencyObject current = queue.Dequeue();
for (int i = VisualTreeHelper.GetChildrenCount(current) - 1; 0 <= i; i--)
{
var child = VisualTreeHelper.GetChild(current, i);
var typedChild = child as T;
if (typedChild != null)
{
return typedChild;
}
queue.Enqueue(child);
}
}
return null;
}
private void MyMap_Tap(object sender, GestureEventArgs e)
{
//This is still working
}
Because you disable only zoom and moving manipulations, taps and holds are working normally.
Hopefully this helps!
edit: Note that when you call FindChildOfType(MyMap), the map element should be visible.
Situation: WinRT application, canvas on a main page. The canvas has a number of children. When user taps on canvas and moves pointer, I’m trying to scroll them. All works fine, but I don’t know how to emulate inertial scrolling.
The code:
private GestureRecognizer gr = new GestureRecognizer();
public MainPage()
{
this.InitializeComponent();
gr.GestureSettings = GestureSettings.ManipulationTranslateInertia;
gr.AutoProcessInertia = true;
}
I’ve subscribed to some canvas events:
//Pressed
private void Canvas_PointerPressed(object sender, PointerRoutedEventArgs e)
{
if (e.Pointer.PointerDeviceType == Windows.Devices.Input.PointerDeviceType.Touch)
{
var _ps = e.GetIntermediatePoints(cnvMain);
if (_ps != null && _ps.Count > 0)
{
gr.ProcessDownEvent(_ps[0]);
e.Handled = true;
Debug.WriteLine("Pressed");
}
initialPoint = e.GetCurrentPoint(cnvMain).Position.X;
}
}
//Released
private void Canvas_PointerReleased(object sender, PointerRoutedEventArgs e)
{
if (e.Pointer.PointerDeviceType == Windows.Devices.Input.PointerDeviceType.Touch)
{
var _ps = e.GetIntermediatePoints(cnvMain);
if (_ps != null && _ps.Count > 0)
{
gr.ProcessUpEvent(_ps[0]);
e.Handled = true;
Debug.WriteLine("Released");
}
}
// Moved
private void Canvas_PointerMoved(object sender, PointerRoutedEventArgs e)
{
if (gr.IsActive || gr.IsInertial)
{
gr.ProcessMoveEvents(e.GetIntermediatePoints(null));
// Here is my code for translation of children
e.Handled = true;
}
}
So, I can translate canvas children, but there is no inertia. How can I enable it?
Unfortunately, I can't use something like GridView or ListView in this app because of specific data.
You should use the GestureRecognizer with ManipulationInertiaStarting. This should give you enough information to implement inertial scrolling.
with a form like this:
I wrote this piece of code to take care of enable/disable logic for moveup/down buttons when they click on at item ( we don't care about Avaiable list on the left, we just care about Selected list on the right)
private void SelectedLV_SelectedIndexChanged(object sender, EventArgs e)
{
// what to do wth move up button
if (SelectedLV.SelectedIndices.Count == 1 && SelectedLV.SelectedItems[0].Index > 0)
{
MoveUpBtn.Enabled = true;
}
else
{
MoveUpBtn.Enabled = false;
}
//what to do with move down button
if (SelectedLV.SelectedIndices.Count == 1 && SelectedLV.SelectedItems[0].Index < SelectedLV.Items.Count - 1)
{
MoveDownBtn.Enabled = true;
}
else
{
MoveDownBtn.Enabled = false;
}
}
I think it works fine for that scenario but my question is what about when we click off of Selected Listview, What is good logic to handle that and Disable Both Moveup/Down buttons?
I don't want them be enabled when we are not inside SelectedListView...
Also if you notice any issue with the code I pasted please let me know.
Thanks
You are about to shoot your foot with the focus requirement. These kind of UI updates are best done with the Application.Idle event, it only runs when nothing important is happening. And can help to eliminate a lot of event handlers. Like this:
public partial class Form1 : Form {
public Form1() {
InitializeComponent();
Application.Idle += Application_Idle;
this.FormClosed += delegate { Application.Idle -= Application_Idle; };
}
void Application_Idle(object sender, EventArgs e) {
bool focusOk = this.ActiveControl == SelectedLV;
bool selectOk = SelectedLV.SelectedIndices.Count == 1;
int index = selectOk ? SelectedLV.SelectedIndices[0] : -1;
MoveUpBtn.Enabled = focusOk && selectOk && index > 0;
MoveDownBtn.Enabled = focusOk && selectOk && index < SelectedLV.Items.Count-1;
}
}
Don't forget to set the focus back in the buttons' Click event handler. And don't forget about the ListView.HideSelection property. Set it to False so that focus doesn't matter anymore.
The problem is once you click on the Move buttons, then you are outside of the SelectedListView control, so the logic should really be based on if you have a correct index value or not:
private void SelectedLV_SelectedIndexChanged(object sender, EventArgs e)
if (SelectedLV.SelectedIndicies.Count == 0) {
MoveUpBtn.Enabled = false;
MoveDownBtn.Enabled = false;
} else {
// normal processing
}