2
votes

I'm adding to the canvas a textblock that the user can bring everywhere but now I'm stuck trying to figure out how to make textblock able to be enlarged or rotated pinching it, this is my code so far:

//create the textblock 
TextBlock txt = new TextBlock() { Text = UserString, FontSize = 56 };

//Adding gesture listener here
GestureListener TextGestureListener = GestureService.GetGestureListener(txt);
txt.MouseEnter += txt_MouseEnter;
TextGestureListener.DragStarted += new EventHandler<DragStartedGestureEventArgs>(GestureListener_DragStarted);
TextGestureListener.DragDelta += new EventHandler<DragDeltaGestureEventArgs>(GestureListener_DragDelta);
TextGestureListener.DragCompleted += new EventHandler<DragCompletedGestureEventArgs>(GestureListener_DragCompleted);
TextGestureListener.PinchDelta += new EventHandler<PinchGestureEventArgs>(GestureListener_PinchDelta);
WholePicture.Children.Add(txt);

//pinch to zoom or at least try!
void GestureListener_PinchDelta(object sender, PinchGestureEventArgs e)
{
    TextBlock txt = (TextBlock)sender;
    Scale = (ScaleTransform)txt.RenderTransform;
    Scale.ScaleX = e.DistanceRatio;
    Scale.ScaleY = e.DistanceRatio;
}

Now, if I try to enlarge the textblock it simply crash with this errors

       $exception   {System.InvalidCastException: Unable to cast object of type 'System.Windows.Media.TranslateTransform' to type 'System.Windows.Media.ScaleTransform'.
       at CrazyFill.Pages.CrazyFillCore.GestureListener_PinchDelta(Object sender, PinchGestureEventArgs e)
       at Microsoft.Phone.Controls.SafeRaise.Raise[T](EventHandler`1 eventToRaise, Object sender, GetEventArgs`1 getEventArgs)
       at Microsoft.Phone.Controls.GestureListener.RaiseGestureEvent[T](Func`2 eventGetter, Func`1 argsGetter, Boolean releaseMouseCapture)
       at Microsoft.Phone.Controls.GestureListener.ProcessTouchPanelEvents()
       at Microsoft.Phone.Controls.GestureListener.TouchDelta()
       at Microsoft.Phone.Controls.GestureListener.OnTouchFrameReported(Object sender, TouchFrameEventArgs e)
       at System.Windows.Input.Touch.OnTouch(Object sender, TouchFrameEventArgs e)
       at MS.Internal.JoltHelper.RaiseEvent(IntPtr target, UInt32 eventId, IntPtr coreEventArgs, UInt32 eventArgsTypeIndex)}    System.Exception {System.InvalidCastException}
2
What is the 'crash' that is being thrown? Do you have the exception or a stack trace? - Brian

2 Answers

1
votes

I think you have a bug because you overwrite the rendertransform of your textblock with a new transform. The older one the translatex-y will be lost that way. You could use CompositeTransform to that and just set scaletransform too on it.

In that cases I would use Databinding not just manipulating from code-behind.

    <TextBox Text="This will move" Height="80" Width="200" x:Name="ToMoveTextBox" RenderTransformOrigin="0.5,0.5">
        <TextBox.RenderTransform>
            <CompositeTransform ScaleX="{Binding ScaleXY}" ScaleY="{Binding ScaleXY}" 
                                TranslateX="{Binding TranslateX}" TranslateY="{Binding TranslateY}"/>
        </TextBox.RenderTransform>
        <toolkit:GestureService.GestureListener>
            <toolkit:GestureListener DragDelta="GestureListener_DragDelta" PinchDelta="GestureListener_PinchDelta"/>
        </toolkit:GestureService.GestureListener>
    </TextBox>

In my sample I used code-behind to calculate the values but in other way you could do it from ViewModel too with CallMethodAction (It is a UI manipulation so you can choose.)

    private void GestureListener_DragDelta(object sender, DragDeltaGestureEventArgs e)
    {
        TranslateX += e.HorizontalChange;
        TranslateY += e.VerticalChange;
        e.Handled = true;
    }

    private void GestureListener_PinchDelta(object sender, PinchGestureEventArgs e)
    {
        ScaleXY = e.DistanceRatio;
        e.Handled = true;
    }

I hope it could help you.

0
votes

The GestureListener_PinchDelta was obviously wrong, here's the working one

void GestureListener_PinchDelta(object sender, PinchGestureEventArgs e)
{
        TextBlock ui = (TextBlock)sender;
        if (ui != null)
        {
            if (!(ui.RenderTransform is ScaleTransform))
                ui.RenderTransform = new ScaleTransform();

            ScaleTransform t = ui.RenderTransform as ScaleTransform;

            t.ScaleX = e.DistanceRatio;
            t.ScaleY = e.DistanceRatio;
            e.Handled = true;
        }
}

this just have a little bug and it's that when I start the gesture the textblock forgot about where it was placed by the user and return where it was firt created (top of the page), working for a solution and when foundi'll let you know