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.
Related
Hello. I working a project in visual studio 2022. i created a canvas and i have a drag drop system. but i need to drag drop process more pixelate movement. if i not tell, look the this gif, maybe more easier way. someone help me?
my code is :
private void actionmodel_PreviewMouseDown(object sender, MouseButtonEventArgs e)
{
if (ismove == 0)
{
ismove += 1;
}
this.dragObject = sender as UIElement;
this.offset = e.GetPosition(this.savedCanvas);
this.offset.Y -= Canvas.GetTop(this.dragObject);
this.offset.X -= Canvas.GetLeft(this.dragObject);
this.savedCanvas.CaptureMouse();
}
//canvasmain üzerinde fare hareket etti ise
private void canvasmain_PreviewMouseMove(object sender, MouseEventArgs e)
{
if (ismove == 1)
{
ismove = 2;
}
if (this.dragObject == null)
return;
var position = e.GetPosition(sender as IInputElement);
Canvas.SetTop(this.dragObject, position.Y - this.offset.Y);
Canvas.SetLeft(this.dragObject, position.X - this.offset.X);
}
//canvasmain üzerinde fare tuşu kalktıysa
private void canvasmain_PreviewMouseUp(object sender, MouseButtonEventArgs e)
{
this.dragObject = null;
this.savedCanvas.ReleaseMouseCapture();
if (ismove == 2)
{
Diary.Items.Add("Hareket Ettirildi");
ismove = 0;
}
}
gif :
https://drive.google.com/file/d/1fHE2wVRFmPL8k2ViM3gkaNOoKl-ovvbd/view?usp=s
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 have two WPF controls. One is a TreeView and the other is a graph control.
I have dragging and dropping working between them. When I drag from the TreeView control to the graph control and drop something it works as I want it to. The mouse cursor has the dragging drop look to it during this. However I want to change the mouse cursor (to something that points up) if the user points the mouse to the top half of the graph control. If the user goes to the bottom of the graph control then I want the cursor to go back to the original dragging drop look.
I thought I could use the GiveFeedback event with the 1st control but that doesn't return the graph object to me.
I can provide code if needed but I don't think it would be helpful. I do have a method called MouseNearTop(Graph g, DragEventArgs e) that returns a bool true if the mouse is in the top half of the grid ad false if on the bottom half.
UPDATE:
I tried using the Mouse.OverrideCursor property but that seems to change the mouse after you release the button. I tried again using the static class DragDrop but that throws exceptions and still doesn't work.
This is for the code for my second attempt:
namespace WpfApplication11
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private bool pointingUp = true;
private void Rectangle_DragOver(object sender, DragEventArgs e)
{
currentPoint = e.GetPosition(MyRectangle);
if ((currentPoint.X > 0) && (currentPoint.X < MyRectangle.ActualWidth) && (currentPoint.Y > 0) && (currentPoint.Y < (MyRectangle.ActualHeight / 2)))
{
if (!pointingUp)
{
//Mouse.OverrideCursor = Cursors.UpArrow;'
try
{
DragDrop.DoDragDrop(MyRectangle1, MyRectangle1, DragDropEffects.Copy);
}
catch
{
}
pointingUp = true;
}
}
else
{
if (pointingUp)
{
//Mouse.OverrideCursor = null;
try
{
DragDrop.DoDragDrop(MyRectangle1, MyRectangle1, DragDropEffects.Move);
}
catch
{
}
pointingUp = false;
}
}
}
Point currentPoint = new Point();
private void MyRectangle1_MouseMove(object sender, MouseEventArgs e)
{
System.Media.SystemSounds.Beep.Play();
if (e.LeftButton == MouseButtonState.Pressed)
{
//if (FileTree.SelectedItem == null)
//{
// return;
//}
//var node = FileTree.SelectedItem as TreeViewNode;
// && (node.TableName.Equals("Ttmp", StringComparison.InvariantCultureIgnoreCase))
//if ((node.Items.Count == 0) && !(node.TableName == "Temp" || node.NodeDisplayName.EqualsAtLeastOne(StringComparison.InvariantCultureIgnoreCase, "DiFR", "DSFR")))
//{
var mousePos = e.GetPosition(null);
var diff = _startPoint - mousePos;
if (Math.Abs(diff.X) > SystemParameters.MinimumHorizontalDragDistance
|| Math.Abs(diff.Y) > SystemParameters.MinimumVerticalDragDistance)
{
DragDrop.DoDragDrop(MyRectangle1, MyRectangle1, DragDropEffects.Move);
}
//}
}
}
private Point _startPoint;
private void MyRectangle1_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
_startPoint = e.GetPosition(null);
}
private void MyRectangle_GiveFeedback(object sender, GiveFeedbackEventArgs e)
{
//Point p = e.GetPosition(MyRectangle);
}
private void MyRectangle_Drop(object sender, DragEventArgs e)
{
e.Effects = DragDropEffects.None;
}
}
}
I've used a Rectangle for demo purposes, but I think this should work OK with whatever graph you're using.
private void MyRectangle_DragOver(object sender, DragEventArgs e)
{
Point p = e.GetPosition(MyRectangle);
if ((p.X > 0) && (p.X < MyRectangle.ActualWidth) && (p.Y > 0) && (p.Y < (MyRectangle.ActualHeight / 2)))
{
Mouse.OverrideCursor = Cursors.UpArrow;
}
else
{
Mouse.OverrideCursor = null;
}
}
I figured a solution.
In the object I am dragging the data into I have this method:
private void ObjectDraggingInto_DragOver(object sender, DragEventArgs e)
{
if (ObjectDraggingFrom.DragDroppingOn)
{
ObjectDraggingFrom.MoveUpCursor = MouseNearTop(sender, e)
? true
: false;
}
}
Then here is the code from the object that I started dragging from:
public static bool MoveUpCursor = false;
public static bool DragDroppingOn = false;
private void ObjectDraggingFrom_GiveFeedback(object sender, GiveFeedbackEventArgs e)
{
if (MoveUpCursor)
{
e.UseDefaultCursors = false;
Mouse.SetCursor(Cursors.UpArrow);
}
else
{
e.UseDefaultCursors = true;
}
e.Handled = true;
}
private void ObjectDragging_Drop(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent(DataFormats.FileDrop))
{
((DataExploreViewModel)DataContext).ImportDraggedAndDroppedFiles((string[])e.Data.GetData(DataFormats.FileDrop));
}
DragDroppingOn = false;
}
private void ObjectDraggingFrom_MouseMove(object sender, MouseEventArgs e)
{
if (e.LeftButton == MouseButtonState.Pressed)
{
if (myData.SelectedItem == null)
{
return;
}
var mousePos = e.GetPosition(null);
var diff = _startPoint - mousePos;
if (Math.Abs(diff.X) > SystemParameters.MinimumHorizontalDragDistance
|| Math.Abs(diff.Y) > SystemParameters.MinimumVerticalDragDistance)
{
DragDroppingOn = true;
DragDrop.DoDragDrop(FileTree, data, DragDropEffects.Move | DragDropEffects.Copy);
}
}
}
So this will change the mouse drag cursor to a up arrow when you are in the upper half of the object you are dragging to. Otherwise the cursor will look like the normal drag cursor.
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.
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.