c# - 你如何在 C# 中为 Canvas 上的线条设置动画?

标签 c# wpf animation canvas

如何让一条线慢慢划过屏幕?

我正在尝试在 C#/WPF 项目中为 Canvas 上的线条设置动画。

我想使用 C# 代码而不是 XAML。

最佳答案

我有一个运行示例,它使用 MVVM 模式并在 ListBox 中创建线,该列表框具有 Canvas 作为其 ItemsPanel

我实际上是为 this question 做的,但是 OP 有点消失了,并且从未就此与我联系。

这是它在我的电脑中的样子:

enter image description here

主要部分是这样的:

<ListBox ItemsSource="{Binding}" x:Name="lst" Height="500" Width="500">
    <ListBox.ItemsPanel>
        <ItemsPanelTemplate>
            <Canvas IsItemsHost="True"/>
        </ItemsPanelTemplate>
    </ListBox.ItemsPanel>
    <ListBox.ItemContainerStyle>
        <Style TargetType="ListBoxItem">
            <Setter Property="FocusVisualStyle">
                <Setter.Value>
                    <Style TargetType="Control">
                        <Setter Property="Opacity" Value="0"/>
                    </Style>
                </Setter.Value>
            </Setter>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="ListBoxItem">
                        <Line X1="{Binding X1}" Y1="{Binding Y1}"
                              X2="{Binding X2}" Y2="{Binding Y2}" 
                              StrokeThickness="{Binding Thickness}"
                              Opacity="{Binding Opacity}"
                              x:Name="Line">
                            <Line.Stroke>
                                <LinearGradientBrush StartPoint="0,0" EndPoint="1,1">
                                    <GradientStop Color="{Binding Color1}" Offset="0"/>
                                    <GradientStop Color="{Binding Color2}" Offset="1"/>
                                </LinearGradientBrush>
                            </Line.Stroke>
                        </Line>
                        <ControlTemplate.Triggers>
                            <Trigger Property="IsSelected" Value="true">
                                <Setter Property="Effect" TargetName="Line">
                                    <Setter.Value>
                                        <DropShadowEffect Color="CornflowerBlue" ShadowDepth="3" BlurRadius="10"/>
                                    </Setter.Value>
                                </Setter>
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </ListBox.ItemContainerStyle>
</ListBox>

View 模型:

public class LineViewModel : INotifyPropertyChanged
{
    #region Timer-based Animation

    private System.Threading.Timer Timer;
    private static Random Rnd = new Random();

    private bool _animate;
    public bool Animate
    {
        get { return _animate; }
        set
        {
            _animate = value;
            NotifyPropertyChanged("Animate");
            if (value)
                StartTimer();
            else
                StopTimer();
        }
    }

    private int _animationSpeed = 1;
    public int AnimationSpeed
    {
        get { return _animationSpeed; }
        set
        {
            _animationSpeed = value;
            NotifyPropertyChanged("AnimationSpeed");
            if (Timer != null)
                Timer.Change(0, 100/value);
        }
    }

    private static readonly List<int> _animationSpeeds = new List<int>{1,2,3,4,5};
    public List<int> AnimationSpeeds
    {
        get { return _animationSpeeds; }
    }

    public void StartTimer()
    {
        StopTimer();
        Timer = new Timer(x => Timer_Tick(), null, 0, 100/AnimationSpeed);
    }

    public void StopTimer()
    {
        if (Timer != null)
        {
            Timer.Dispose();
            Timer = null;
        }
    }

    private void Timer_Tick()
    {
        X1 = X1 + Rnd.Next(-2, 3);
        Y1 = Y1 + Rnd.Next(-2, 3);
        X2 = X2 + Rnd.Next(-2, 3);
        Y2 = Y2 + Rnd.Next(-2, 3);
    }

    #endregion

    #region Coordinates

    private double _x1;
    public double X1
    {
        get { return _x1; }
        set
        {
            _x1 = value;
            NotifyPropertyChanged("X1");
        }
    }

    private double _y1;
    public double Y1
    {
        get { return _y1; }
        set
        {
            _y1 = value;
            NotifyPropertyChanged("Y1");
        }
    }

    private double _x2;
    public double X2
    {
        get { return _x2; }
        set
        {
            _x2 = value;
            NotifyPropertyChanged("X2");
        }
    }

    private double _y2;
    public double Y2
    {
        get { return _y2; }
        set
        {
            _y2 = value;
            NotifyPropertyChanged("Y2");
        }
    }

    #endregion

    #region Other Properties

    private string _name;
    public string Name
    {
        get { return _name; }
        set
        {
            _name = value;
            NotifyPropertyChanged("Name");
        }
    }

    private double _thickness;
    public double Thickness
    {
        get { return _thickness; }
        set
        {
            _thickness = value;
            NotifyPropertyChanged("Thickness");
        }
    }

    public Color Color1 { get; set; }
    public Color Color2 { get; set; }

    private double _opacity = 1;
    public double Opacity
    {
        get { return _opacity; }
        set
        {
            _opacity = value;
            NotifyPropertyChanged("Opacity");
        }
    }

    #endregion

    #region INotifyPropertyChanged

    public event PropertyChangedEventHandler PropertyChanged;

    private void NotifyPropertyChanged(string propertyName)
    {
        Application.Current.Dispatcher.BeginInvoke((Action)(() =>
            {
                if (PropertyChanged != null)
                    PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }));
    }

    #endregion
}

编辑源代码现在在GitHub

关于c# - 你如何在 C# 中为 Canvas 上的线条设置动画?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15469283/

相关文章:

C# for循环显示所有记录

android - 动嘴动画

c# - 使用 HttpResponse 在 C# 中下载具有非英文字符的文件

c# - 将 LineGeometry 与 EllipseGeometry 组合(在代码中,而不是 XAML)

c# - WPF 数据网格单元格为空

wpf - 将 WPF ContextMenu 子菜单绑定(bind)到集合

html - 在 html 中飘扬的旗帜

javascript - 如何使用onclick Javascript制作div幻灯片动画

c# - LINQ-NHibernate - 只为复杂对象选择几个字段(包括集合)

c# - 取决于列表框项目类型的上下文菜单