C# 视口原点动画

C# 视口原点动画,c#,animation,windows-phone-8,storyboard,C#,Animation,Windows Phone 8,Storyboard,我正在开发一个Windows phone应用程序,其中有一个viewportcontroller,可以放大和缩小内容。 我想将缩放集中在我缩放的点上。我可以用它 Viewportcontroller.SetViewportOrigin() 但这会使viewportcontroller跳转到我设置的原点。看起来不太好。因此,我想创建一个故事板,随着缩放的发生逐渐改变原点 因此,我想问我应该如何使用ViewportControl的属性来实现这一点。我尝试了一些不同的动画类型,翻译和xy。但要么我选

我正在开发一个Windows phone应用程序,其中有一个viewportcontroller,可以放大和缩小内容。 我想将缩放集中在我缩放的点上。我可以用它

Viewportcontroller.SetViewportOrigin()
但这会使viewportcontroller跳转到我设置的原点。看起来不太好。因此,我想创建一个故事板,随着缩放的发生逐渐改变原点

因此,我想问我应该如何使用ViewportControl的属性来实现这一点。我尝试了一些不同的动画类型,翻译和xy。但要么我选择了错误的属性,要么选择了错误的动画类型。因为什么都不起作用:(

因此,我的问题是双重的。 我应该选择哪种类型的动画。我该如何更改它?
应该是双重动画吗?但我似乎无法在这里设置点?非常感谢您的帮助!

我没有ViewportControl的经验,我假设ViewportControl.SetViewportOrigin()是设置原点的唯一方法(即:没有属性来设置原点)

如果是这种情况,可以将ViewportControl包装在自定义控件中

添加两个控制的依赖项属性(ViewportX和ViewportY,或一个Point类型的依赖项属性),并在情节提要中设置这两个属性的动画(使用简单的DoubleAnimation)

在这些属性的值更改回调中,然后可以使用更改的值调用SetViewportOrigin()

比如:

public class WrappedViewport : Control
{
    private ViewportControl _viewportControl;
    protected override OnApplyTemplate()
    {
        // make sure there is an appropriate default style in generic.xaml
        _viewportControl = (ViewportControl)GetTemplateChild("Viewport"); 
    }

    #region ViewportX
    private static void ViewportXChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        WrappedViewport owner = (WrappedViewport)d;
        owner._viewportControl.SetViewportOrigin(ViewportX, ViewportY);
    }

    private static readonly DependencyProperty ViewportXProperty = DependencyProperty.Register("ViewportX",
                                                                                          typeof(double),
                                                                                          typeof(WrappedViewport),
                                                                                          new PropertyMetadata(0d, ViewportXChangedCallback));

    public double ViewportX
    {
        get { return (double)GetValue(ViewportXProperty ); }
        set { SetValue(ViewportXProperty , value); }
    }
    #endregion

    #region ViewportY
    private static void ViewportYChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        WrappedViewport owner = (WrappedViewport)d;
        owner._viewportControl.SetViewportOrigin(ViewportX, ViewportY);
    }

    private static readonly DependencyProperty ViewportYProperty = DependencyProperty.Register("ViewportY",
                                                                                          typeof(double),
                                                                                          typeof(WrappedViewport),
                                                                                          new PropertyMetadata(0d, ViewportYChangedCallback));

    public double ViewportY
    {
        get { return (double)GetValue(ViewportYProperty ); }
        set { SetValue(ViewportYProperty , value); }
    }
    #endregion
}

另请参见

我尝试了几种不同的方法,结果证明这是最平滑的方法。它不漂亮,但很有效

public partial class MainPage : PhoneApplicationPage
{
    private const int MoveCount = 25;

    private double _tickX;
    private double _tickY;

    private int _adjustCount = MoveCount+1;

    public MainPage()
    {
        InitializeComponent();
        Viewport.ViewportChanged += ViewportOnViewportChanged;
    }

    private void ViewportOnViewportChanged(object sender, ViewportChangedEventArgs viewportChangedEventArgs)
    {
        AdjstViewport();
    }

    private void AdjstViewport()
    {
        if (_adjustCount >= MoveCount) return;
        _adjustCount++;
        Viewport.SetViewportOrigin(new Point(Viewport.Viewport.X + _tickX, Viewport.Viewport.Y + _tickY));                        
    }

    private async void OnButtonClick(object sender, System.Windows.RoutedEventArgs e)
    {
        _adjustCount = 0;

        var content = (FrameworkElement)Viewport.Content;
        double zoomOriginX = (content.ActualWidth / 2) - (Viewport.Viewport.Width / 2);
        double zoomOriginY = (content.ActualHeight / 2) - (Viewport.Viewport.Height / 2);

        double distanceX = zoomOriginX - Viewport.Viewport.X;
        double distanceY = zoomOriginY - Viewport.Viewport.Y;

        _tickX = distanceX / MoveCount;
        _tickY = distanceY / MoveCount;

        AdjstViewport();
    }
}

@Willvanrumpt我还没有找到另一种方法来设置中心。好吧,我从来没有玩过依赖属性,你能再解释一下代码中发生了什么,以及应该在(…)处放置什么吗?谢谢,我稍后会尝试。在OnApplyTemplate中,您忘记了一个空格。在setViewportOrigin中需要一个点。ViewportX和ViewportY给出了一个错误。要解决此错误,我需要将变量更改为静态。这会在使用get和set时引入错误。您能帮助我解决此错误吗?感谢您查看另一个示例我的问题:)好的,所以我当然想用收缩缩放来做这个。所以你可以通过事件而不是动画来完成。我看那可能有用。我会在一点时间内尝试这个。但我们正忙于其他一些问题,试图在周日晚上丹麦时间将这些问题提交给ImagineCup。因此,在使用视口方面,我们有一个更紧迫的问题。如果你有时间的话,我们希望能得到一些帮助,帮助你用尽一切可能:)我先尝试了动画,但这是最流畅的