C# Windows 10 App - 从 X1、Y1 到 X2、Y2 慢慢画线

C# Windows 10 App - Draw Line Slowly From X1, Y1 to X2,Y2

我正在努力解决这个应该很容易解决的问题。我想简单地为 canvas 上的一条线指定 X1 和 Y1 以及 X2 和 Y2 坐标,并在 1 秒的时间内在这些点之间绘制一条线。

我的canvas名字是cnvML,线名是L1。这需要在 运行 时间完成,所以我更愿意使用 C#,但如果我可以修改在 XAML 中创建的命名故事板,那很好。我假设我需要一个 Storyboard,尽管我无法让它工作。 这是我过去 2 天尝试过的方法:

  1. 搜索了 google 很多例子。通过更改动画的 X 和 Y 属性,我已经能够在 canvas 上为直线、矩形和椭圆设置动画。我一直无法弄清楚如何转换线本身的 X2 和 Y2 属性。我已经看到一些针对旧框架的示例,但是某些方法的构造函数不同,不适用于 Windows 10 个应用程序。

  2. 我试过在 Blend 中构建动画,但它仅适用于在设计时构建的动画线条。如果我不指定动画的目标,它会给我一个错误。此外,在 Blend 中执行此操作并不能真正按照我想要的方式完成转换。如果我从时间 0 开始使用一条非常短的线,那么在 1 秒时,我将线拉长到所需的长度,这会改变线的比例,从而改变路径对象的表观笔划粗细。

如果有人能告诉我如何做到这一点,我将不胜感激,甚至可能不使用故事板。我希望它全部在 C# 中。名为 cnvML 的 canvas 将在设计时存在,但这些行将在 运行 时创建。

同样,我只想将 X1、Y1、X2 和 Y2 传递给一个方法。然后将绘制线并在这 2 个点之间绘制 1 秒。

谢谢, 大卫

免责声明:我不会 WPF,所以这是从其他地方找到的示例拼凑而成的。

使用故事板,您可以为 X2Y2 属性设置动画,如下所示:

    <Storyboard>
        <DoubleAnimation Storyboard.TargetName="line1" Storyboard.TargetProperty="X2" From="10" To="100" Duration="0:0:1.0"/>
        <DoubleAnimation Storyboard.TargetName="line1" Storyboard.TargetProperty="Y2" From="10" To="100" Duration="0:0:1.0"/>
    </Storyboard>

如何启动取决于您。我刚刚将它添加到按钮控件的 Button.Click 事件触发器中。

这相当于对目标 属性 的时间进行线性插值,因此在此示例中,在一秒钟内 X1Y1 的值将在 11100 之间平稳变化。这将使线的外观从其原点(在我的测试版本中为 10,10)沿着线延伸到最终端点 100,100

这是我测试的完整 XAML。因为我不使用 WPF,所以我希望有几件事我可以做得更好 :)

<Window x:Class="AnimTest.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:AnimTest"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <Canvas HorizontalAlignment="Left" Height="300" Margin="10,10,0,0" VerticalAlignment="Top" Width="426">
            <Line Name="line1" X1="10" Y1="10" X2="10" Y2="10" StrokeThickness="3" Stroke="Black"/>
        </Canvas>
        <Button Margin="441,279,10,10">
            OK
            <Button.Triggers>
                <EventTrigger RoutedEvent="Button.Click">
                    <BeginStoryboard>
                        <Storyboard>
                            <DoubleAnimation Storyboard.TargetName="line1" Storyboard.TargetProperty="X2" From="10" To="100" Duration="0:0:1.0"/>
                            <DoubleAnimation Storyboard.TargetName="line1" Storyboard.TargetProperty="Y2" From="10" To="100" Duration="0:0:1.0"/>
                        </Storyboard>
                    </BeginStoryboard>
                </EventTrigger>
            </Button.Triggers>
        </Button>
    </Grid>
</Window>

我安装了Universal App工具并试用了。事实证明,与 WPF 相比,他们改变了 Universal Apps 中的一大堆东西,包括几乎废弃了 XAML 中路由事件的概念。这听起来像是惹恼大量开发人员的好方法,是吧?

所以现在不能给出仅适用于 WPF 的 XAML 答案,这里有一个由两部分组成的 XAML + 通用代码答案(在 W10、VS2015 上):

首先是XAML:

<Page
    x:Class="UniversalApp1.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:UniversalApp1"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">

    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <Grid.Resources>
            <Storyboard x:Name="btnClick_SB" >
                <DoubleAnimation Storyboard.TargetName="line1" Storyboard.TargetProperty="X2" From="10" To="400" Duration="0:0:1.0" EnableDependentAnimation="True"/>
                <DoubleAnimation Storyboard.TargetName="line1" Storyboard.TargetProperty="Y2" From="10" To="400" Duration="0:0:1.0" EnableDependentAnimation="True"/>
            </Storyboard>
        </Grid.Resources>
        <Canvas HorizontalAlignment="Left" Height="300" Margin="10,50,0,0" VerticalAlignment="Top" Width="426">
            <Line Name="line1" X1="10" Y1="10" X2="10" Y2="10" StrokeThickness="3" Stroke="Black"/>
        </Canvas>
        <Button Margin="441,279,10,10" Click="Button_Click">OK</Button>
    </Grid>
</Page>

和(相关部分)代码:

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        btnClick_SB.Stop();
        btnClick_SB.Begin();
    }

btnClick_SB.Stop() 调用确保您不会在故事板已经 运行 时调用它,这显然是一个会引发异常的禁止操作。