gpt4 book ai didi

c# - WPF 将 Canvas.Left/Canvas.Top 绑定(bind)到点 DependencyProperty,使用 PointAnimation

转载 作者:行者123 更新时间:2023-12-03 11:09:50 27 4
gpt4 key购买 nike

请考虑以下说明我的问题的简化示例:

主窗口.xaml

<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="500" Height="500"
Title="Click anywhere to animate the movement of the blue thingy...">
<Canvas
x:Name="canvas"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Background="AntiqueWhite"
MouseDown="canvas_MouseDown" />
</Window>

主窗口.xaml.cs
using System;
using System.Windows;
using System.Windows.Input;
using System.Windows.Media.Animation;

namespace WpfApplication1
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();

this.canvas.Children.Add(new Thingy());
}

private void canvas_MouseDown(object sender, MouseButtonEventArgs e)
{
var thingy = (Thingy)this.canvas.Children[0];

var from = new Point(0.0, 0.0);

var to = new Point(
canvas.ActualWidth - thingy.ActualWidth,
canvas.ActualHeight - thingy.ActualHeight
);

var locAnim = new PointAnimation(
from,
to,
new Duration(TimeSpan.FromSeconds(5))
);

locAnim.Completed += (s, a) =>
{
// Only at this line does the thingy move to the
// correct position...
thingy.Location = to;
};

thingy.Location = from;
thingy.BeginAnimation(Thingy.LocationProperty, locAnim);
}
}
}

Thingy.xaml
<UserControl x:Class="WpfApplication1.Thingy"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="50" Height="50" Background="Blue" />

Thingy.xaml.cs
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;

namespace WpfApplication1
{
public partial class Thingy : UserControl
{
public static DependencyProperty LocationProperty =
DependencyProperty.Register(
"Location",
typeof(Point),
typeof(Thingy)
);

public Thingy()
{
InitializeComponent();

Canvas.SetLeft(this, 0.0);
Canvas.SetTop(this, 0.0);

var xBind = new Binding();
xBind.Source = this;
xBind.Path = new PropertyPath(Canvas.LeftProperty);
xBind.Mode = BindingMode.TwoWay;

var yBind = new Binding();
yBind.Source = this;
yBind.Path = new PropertyPath(Canvas.TopProperty);
yBind.Mode = BindingMode.TwoWay;

var locBind = new MultiBinding();
locBind.Converter = new PointConverter();
locBind.Mode = BindingMode.TwoWay;
locBind.Bindings.Add(xBind);
locBind.Bindings.Add(yBind);
BindingOperations.SetBinding(
this,
Thingy.LocationProperty,
locBind
);
}

public Point Location
{
get
{
return (Point)this.GetValue(LocationProperty);
}

set
{
this.SetValue(LocationProperty, value);
}
}
}
}

点转换器.cs
using System;
using System.Globalization;
using System.Windows;
using System.Windows.Data;

namespace WpfApplication1
{
public class PointConverter : IMultiValueConverter
{
public object Convert(object[] v, Type t, object p, CultureInfo c)
{
return new Point((double)v[0], (double)v[1]);
}

public object[] ConvertBack(object v, Type[] t, object p, CultureInfo c)
{
return new object[] { ((Point)v).X, ((Point)v).Y };
}
}
}

这里的目标是:
  • 使用 LocationProperty操纵和访问Canvas.LeftPropertyCanvas.TopProperty值(value)观。
  • 动画说LocationPropertyPointAnimation类(class)。

  • 目标 #1 似乎工作正常,仅在尝试为 LocationProperty 设置动画时才出现。它的行为是否不符合预期。

    “预期”是指 Thingy 的实例应该随着动画的进行而移动。

    我可以使用 DoubleAnimation 的两个实例来完成此操作。类(class)。

    如果问题是 Point是值类型,那么我怀疑我可以定义自己的 Point输入和我自己的 AnimationTimeline .这不是我想做的。这是一个更大的项目的一部分, LocationProperty将用于其他事情。

    老实说,最重要的是,在我看来这应该是可行的,你能告诉我:
  • 为什么不呢?
  • 如果定义的问题有解决方案?

  • 我还要提到我的目标是 .Net Framework 4.5 用于这个项目。

    谢谢你。

    最佳答案

    这是动画某些东西的最简单的代码。

  • 它利用依赖属性回调
  • 不使用绑定(bind)
  • 不使用转换器
  • 不使用 Storyboard

  • 主窗口:
    using System;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Input;
    using System.Windows.Media.Animation;

    namespace WpfApplication1
    {
    public partial class MainWindow
    {
    public MainWindow()
    {
    InitializeComponent();
    }

    private void MainWindow_OnMouseDown(object sender, MouseButtonEventArgs e)
    {
    var x = Canvas.GetLeft(Control1);
    var y = Canvas.GetTop(Control1);
    x = double.IsNaN(x) ? 0 : x;
    y = double.IsNaN(y) ? 0 : y;
    var point1 = new Point(x, y);
    var point2 = e.GetPosition(this);
    var animation = new PointAnimation(point1, point2, new Duration(TimeSpan.FromSeconds(1)));
    animation.EasingFunction = new CubicEase();
    Control1.BeginAnimation(UserControl1.LocationProperty, animation);
    }
    }
    }

    主窗口:
    <Window x:Class="WpfApplication1.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:WpfApplication1"
    mc:Ignorable="d"
    Title="MainWindow" Height="350" Width="525" MouseDown="MainWindow_OnMouseDown">
    <Canvas>
    <local:UserControl1 Background="Red" Height="100" Width="100" x:Name="Control1" />
    </Canvas>
    </Window>

    控制:
    using System.Windows;
    using System.Windows.Controls;

    namespace WpfApplication1
    {
    public partial class UserControl1
    {
    public static readonly DependencyProperty LocationProperty = DependencyProperty.Register(
    "Location", typeof(Point), typeof(UserControl1), new UIPropertyMetadata(default(Point), OnLocationChanged));

    public UserControl1()
    {
    InitializeComponent();
    }

    public Point Location
    {
    get { return (Point) GetValue(LocationProperty); }
    set { SetValue(LocationProperty, value); }
    }

    private static void OnLocationChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
    var control1 = (UserControl1) d;
    var value = (Point) e.NewValue;
    Canvas.SetLeft(control1, value.X);
    Canvas.SetTop(control1, value.Y);
    }
    }
    }

    控制:
    <UserControl x:Class="WpfApplication1.UserControl1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:local="clr-namespace:WpfApplication1"
    mc:Ignorable="d"
    d:DesignHeight="300" d:DesignWidth="300">

    </UserControl>

    待办事项:根据您的需要调整代码:)

    编辑:一个简单的双向绑定(bind),监听 Canvas.[Left|Top]Property :

    (待加强)
    using System;
    using System.ComponentModel;
    using System.Windows;
    using System.Windows.Controls;

    namespace WpfApplication1
    {
    public partial class UserControl1
    {
    public static readonly DependencyProperty LocationProperty = DependencyProperty.Register(
    "Location", typeof(Point), typeof(UserControl1), new PropertyMetadata(default(Point), OnLocationChanged));

    public UserControl1()
    {
    InitializeComponent();

    DependencyPropertyDescriptor.FromProperty(Canvas.LeftProperty, typeof(Canvas))
    .AddValueChanged(this, OnLeftChanged);
    DependencyPropertyDescriptor.FromProperty(Canvas.TopProperty, typeof(Canvas))
    .AddValueChanged(this, OnTopChanged);
    }

    public Point Location
    {
    get { return (Point) GetValue(LocationProperty); }
    set { SetValue(LocationProperty, value); }
    }

    private void OnLeftChanged(object sender, EventArgs eventArgs)
    {
    var left = Canvas.GetLeft(this);
    Location = new Point(left, Location.Y);
    }

    private void OnTopChanged(object sender, EventArgs e)
    {
    var top = Canvas.GetTop(this);
    Location = new Point(Location.X, top);
    }

    private static void OnLocationChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
    var control1 = (UserControl1) d;
    var value = (Point) e.NewValue;
    Canvas.SetLeft(control1, value.X);
    Canvas.SetTop(control1, value.Y);
    }
    }
    }

    关于c# - WPF 将 Canvas.Left/Canvas.Top 绑定(bind)到点 DependencyProperty,使用 PointAnimation,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41767915/

    27 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com