WPF。以编程方式将图像移动到(X,Y)的最简单方法?

WPF。以编程方式将图像移动到(X,Y)的最简单方法?,wpf,animation,Wpf,Animation,是否有人知道一种简单的方法,可以使用WPF动画(不含XAML,100%编程)将图像从当前位置移动到新位置(X,Y)?并且没有提及“this”(带有RegisterName等) 我正在尝试为Image制作一个扩展类,以便在上面制作动画。通过动画更改宽度和高度属性很容易,但在搜索对象的位置动画后,它突然变得更高级 因为它是一个扩展类,所以我只会引用实际的图像对象以及我想将其移动到的X和Y public static void MoveTo(this Image targetControl, doub

是否有人知道一种简单的方法,可以使用WPF动画(不含XAML,100%编程)将图像从当前位置移动到新位置(X,Y)?并且没有提及“this”(带有RegisterName等)

我正在尝试为Image制作一个扩展类,以便在上面制作动画。通过动画更改宽度和高度属性很容易,但在搜索对象的位置动画后,它突然变得更高级

因为它是一个扩展类,所以我只会引用实际的图像对象以及我想将其移动到的X和Y

public static void MoveTo(this Image targetControl, double X, double Y, double Width, double Height){
 //code here
 ...
}
更新:

谢谢。几乎可以工作了。似乎GetTop和GetLeft返回的'NaN'没有显式设置。在此帖子中找到了解决方法:

我必须用0交换其中两个值(从)。我认为这一定是因为在这种情况下,图片的左上角是原点?但现在它起作用了。

试试这个:

public static void MoveTo(this Image target, double newX, double newY)
{
    var top = Canvas.GetTop(target);
    var left = Canvas.GetLeft(target);
    TranslateTransform trans = new TranslateTransform();
    target.RenderTransform = trans;
    DoubleAnimation anim1 = new DoubleAnimation(top, newY - top, TimeSpan.FromSeconds(10));
    DoubleAnimation anim2 = new DoubleAnimation(left, newX - left, TimeSpan.FromSeconds(10));
    trans.BeginAnimation(TranslateTransform.XProperty,anim1);
    trans.BeginAnimation(TranslateTransform.YProperty,anim2);
}

这是。。。它更改大小并在
画布下移动
MediaElement
。只需输入您的参数:

Storyboard story = new Storyboard();
DoubleAnimation dbWidth = new DoubleAnimation();
dbWidth.From = mediaElement1.Width;
dbWidth.To = 600;
dbWidth.Duration = new Duration(TimeSpan.FromSeconds(.25));

DoubleAnimation dbHeight = new DoubleAnimation();
dbHeight.From = mediaElement1.Height;
dbHeight.To = 400;
dbHeight.Duration = dbWidth.Duration;

story.Children.Add(dbWidth);
Storyboard.SetTargetName(dbWidth, mediaElement1.Name);
Storyboard.SetTargetProperty(dbWidth, new PropertyPath(MediaElement.WidthProperty));

story.Children.Add(dbHeight);
Storyboard.SetTargetName(dbHeight, mediaElement1.Name);
Storyboard.SetTargetProperty(dbHeight, new PropertyPath(MediaElement.HeightProperty));

DoubleAnimation dbCanvasX = new DoubleAnimation();
dbCanvasX.From = 0;
dbCanvasX.To = 5;
dbCanvasX.Duration = new Duration(TimeSpan.FromSeconds(.25));

DoubleAnimation dbCanvasY = new DoubleAnimation();
dbCanvasY.From = 0;
dbCanvasY.To = 5;
dbCanvasY.Duration = dbCanvasX.Duration;

story.Children.Add(dbCanvasX);
Storyboard.SetTargetName(dbCanvasX, mediaElement1.Name);
Storyboard.SetTargetProperty(dbCanvasX, new PropertyPath(Canvas.LeftProperty));

story.Children.Add(dbCanvasY);
Storyboard.SetTargetName(dbCanvasY, mediaElement1.Name);
Storyboard.SetTargetProperty(dbCanvasY, new PropertyPath(Canvas.TopProperty));

story.Begin(this);

别忘了把C代码放在:

private void button1_Click(object sender, RoutedEventArgs e) {}

您也可以使用
MediaElement
,但您必须定义
视频剪辑才能看到某些内容;)

此代码基于@DeanChalk的答案

它将
画布中包含的
图像
RFID_标记
)从右上角对角移动到左下角,位于
画布中另一个
图像
RFID_阅读器
)的中心位置


请找到一个将画布的左属性和上属性用于扩展方法的解决方案。请参阅以下代码:

    public static void MoveTo(this Image target, Point newP)
    {

        Point oldP = new Point();
        oldP.X = Canvas.GetLeft(target);
        oldP.Y = Canvas.GetTop(target);

        DoubleAnimation anim1 = new DoubleAnimation(oldP.X, newP.X, TimeSpan.FromSeconds(0.2));
        DoubleAnimation anim2 = new DoubleAnimation(oldP.Y, newP.Y , TimeSpan.FromSeconds(0.2));

        target.BeginAnimation(Canvas.LeftProperty , anim1);
        target.BeginAnimation(Canvas.TopProperty, anim2);

    }

我的嵌套元素一直有NaN或0值,下面是Danny答案的修改版本:

    public void MoveTo(Canvas canvas, FrameworkElement target, FrameworkElement destination)
    {
        Point oldPoint = target.TransformToAncestor(canvas).Transform(new Point(0, 0));
        Point newPoint = destination.TransformToAncestor(canvas).Transform(new Point(0, 0));

        var EndX = destination.Width / 2 + newPoint.X - oldPoint.X - (target.Width / 2);
        var EndY = destination.Height / 2 + newPoint.Y - oldPoint.Y - (target.Height / 2);

        TranslateTransform trans = new TranslateTransform();
        target.RenderTransform = trans;
        DoubleAnimation anim1 = new DoubleAnimation(0, EndX, TimeSpan.FromSeconds(0.3));
        DoubleAnimation anim2 = new DoubleAnimation(0, EndY, TimeSpan.FromSeconds(0.3));
        trans.BeginAnimation(TranslateTransform.XProperty, anim1);
        trans.BeginAnimation(TranslateTransform.YProperty, anim2);
    }

这仅在图像位于画布内时有效(否则,获取顶部和左侧属性将返回0)。如果您使用的是画布,您可以设置Canvas.Top和Canvas.Left属性来移动它。对于另一种类型的容器,您可以设置边距(eurgh),或者如Dean所述,使用translate变换。几乎可以正常工作。left和top属性必须从VisualTreeHelper.GetOffset(目标)获取,因为GetTop和GetLeft返回“NaN”。只剩下一只虫子了。动画的开始位置似乎是当前位置的两倍。0作为起始值固定了它。@Dean我爱你,伙计!两天前我一直在寻找解决方案:DYa,我将此代码放在一个新的窗口元素中,并将C代码添加到button#u click事件中。代码运行得非常好,但不执行动画。我错过了什么吗?在过去的几天里,我在WPF动画方面变得更好了。我到家后将重试。用矩形替换MediaElement使矩形移动,但它的行为不像精灵在屏幕上移动,而是使位于右下角的矩形变大。不完全是所提出的问题所期望的动画,我认为是C代码中的硬编码值。我投了更高的票,因为我知道回答问题并不容易,而且你非常关心更新你的答案。我正在用你的代码缩小UI控件。它工作正常,但如何使其恢复到以前的大小?我测试过像.Width=111和.Height=222,但不起作用…@KayLee我肯定会做些事情回来,我们必须记住上一篇文章。陈述并以某种方式重新创建它。谢谢你的好话,伙计!谢谢你的更新。很高兴看到一个如何使用向量的示例。您更新的代码非常好!非常感谢你的卓越表现!
private void button1_Click(object sender, RoutedEventArgs e) {}
<Canvas>
    <Canvas x:Name="RFID_Reader_Canvas">
        <Image x:Name="RFID_Reader" Source="RFID-Reader.png" Height="456" Width="682" Canvas.Left="37" Canvas.Top="524"/>
    </Canvas>
    <Canvas x:Name="RFID_Token_Canvas">
        <Image x:Name="RFID_Token" Source="RFID-Token.png" Height="268" Width="343" Canvas.Left="874" Canvas.Top="70"/>
    </Canvas>
</Canvas>
var StartX = Canvas.GetLeft(RFID_Token);
var StartY = Canvas.GetTop(RFID_Token);

var EndX = RFID_Reader.Width / 2 + Canvas.GetLeft(RFID_Reader) - StartX - (RFID_Token.Width / 2);
var EndY = RFID_Reader.Height / 2 + Canvas.GetTop(RFID_Reader) - StartY - (RFID_Token.Height / 2);

var AnimationX = new DoubleAnimation(0, EndX, TimeSpan.FromSeconds(1));
var AnimationY = new DoubleAnimation(0, EndY, TimeSpan.FromSeconds(1));

var Transform = new TranslateTransform();
RFID_Token_Canvas.RenderTransform = Transform;

Transform.BeginAnimation(TranslateTransform.XProperty, AnimationX);
Transform.BeginAnimation(TranslateTransform.YProperty, AnimationY);
    public static void MoveTo(this Image target, Point newP)
    {

        Point oldP = new Point();
        oldP.X = Canvas.GetLeft(target);
        oldP.Y = Canvas.GetTop(target);

        DoubleAnimation anim1 = new DoubleAnimation(oldP.X, newP.X, TimeSpan.FromSeconds(0.2));
        DoubleAnimation anim2 = new DoubleAnimation(oldP.Y, newP.Y , TimeSpan.FromSeconds(0.2));

        target.BeginAnimation(Canvas.LeftProperty , anim1);
        target.BeginAnimation(Canvas.TopProperty, anim2);

    }
    public void MoveTo(Canvas canvas, FrameworkElement target, FrameworkElement destination)
    {
        Point oldPoint = target.TransformToAncestor(canvas).Transform(new Point(0, 0));
        Point newPoint = destination.TransformToAncestor(canvas).Transform(new Point(0, 0));

        var EndX = destination.Width / 2 + newPoint.X - oldPoint.X - (target.Width / 2);
        var EndY = destination.Height / 2 + newPoint.Y - oldPoint.Y - (target.Height / 2);

        TranslateTransform trans = new TranslateTransform();
        target.RenderTransform = trans;
        DoubleAnimation anim1 = new DoubleAnimation(0, EndX, TimeSpan.FromSeconds(0.3));
        DoubleAnimation anim2 = new DoubleAnimation(0, EndY, TimeSpan.FromSeconds(0.3));
        trans.BeginAnimation(TranslateTransform.XProperty, anim1);
        trans.BeginAnimation(TranslateTransform.YProperty, anim2);
    }