I have a use case where my diagram will be used only through a touchscreen (no keyboard or mouse present). Generally, all the functionality I need is available except zooming. I am trying to implement pinch to zoom on my diagram. I can get it to work by using the ManipulationDelta scale to modify the Diagram.Panel scale. However, implementing manipulation (IsManipulationEnabled = true) on the Diagram causes all other functionality to cease working via touch (e.g., I can no longer pan nor select a node with a finger or stylus). Is there an example I can look at where pinch to zoom and basic diagram interactions coexist all through a touch interface?
This is experimental code that I tried a long time ago:
// support pinch zooming
private void Touch_FrameReported(object sender, TouchFrameEventArgs e) {
var touchpoints = e.GetTouchPoints(myDiagram.Panel);
if (touchpoints.Count > 1) {
var tp0 = touchpoints[0].Position;
var tp1 = touchpoints[1].Position;
var newDist = Math.Sqrt((tp0.X-tp1.X)*(tp0.X-tp1.X) + (tp0.Y-tp1.Y)*(tp0.Y-tp1.Y));
if (Double.IsNaN(startDist)) {
startDist = newDist;
startScale = myDiagram.Panel.Scale;
var primary = e.GetPrimaryTouchPoint(myDiagram.Panel);
if (primary != null) myDiagram.Panel.ZoomPoint = primary.Position;
} else {
myDiagram.Panel.Scale = startScale * newDist / startDist;
}
} else {
startDist = Double.NaN;
}
}
private double startDist = Double.NaN;
private double startScale = 1;
Register via:
Touch.FrameReported += Touch_FrameReported;
I hope this gets you started on pinch-zoom functionality that works in your app.
This works nicely. Thanks!!
Hi,
I know this is working, but I want to share another solution with the forum.
Name your Diagram e.g. “MainDiagram”.``
In the View or Window your diagram is hosted override this three methods:
protected override void OnManipulationStarting(ManipulationStartingEventArgs e)
{
e.ManipulationContainer = MainDiagram;
e.Handled = true;
base.OnManipulationStarting(e);
}
protected override void OnManipulationDelta(ManipulationDeltaEventArgs e)
{
if (e.Manipulators.Count() > 1)
{
var delta = e.DeltaManipulation;
MainDiagram.Panel.Scale *= delta.Scale.X;
e.Handled = true;
}
else
{
e.Cancel();
}
base.OnManipulationDelta(e);
}
protected override void OnManipulationInertiaStarting(ManipulationInertiaStartingEventArgs e)
{
e.Cancel();
base.OnManipulationInertiaStarting(e);
}
That’s interesting – thanks for sharing this
Is the difference between the two implementations whether it handles inertia? In my opinion it is better not to zoom with inertia, since it makes precise scaling easier.
Thank you Walter and Andy. I experimented with both solutions. 1) Anyone using Andy’s solution needs to put IsManipulationEnabled = true setting on his/her diagram. 2) I found Andy’s solution to jump a bit at the end of each zoom. Walter’s solution seemed to allow for a smoother zoom. 3) I also found the transition between zooming and panning to be easier under Walter’s solution. Under Andy’s solution, the user needed to be more deliberate between using 2 fingers for zoom and one finger for panning.
That said, when researching pinch to zoom on the Internet, almost every single article mentions using the ManipulationDelta method. Almost no one suggests the “Frame_Reported” method. Not sure why. Let me add one last point for anyone deciding between the two options: where I have experimented with using Manipulation for scaling on other parts of my application, I found that it would break the responsiveness of hyperlinks, checkboxes, and buttons to touch.
I hope this thread is helpful to others. It was certainly helpful to me.