.net DispatcherTimer重复触发tick事件

时间:2013-11-21 10:15:56

标签: c# .net dispatchertimer

我的代码中有问题,我甚至都不理解。

这是我的项目界面;

internal interface IItem
{
    void Show();
    event EventHandler Completed;
    TimeSpan Duration { get; set; }
    string Name { get; set; }
}

internal class ItemImage : IItem
{

    public TimeSpan Duration { get; set; }
    public string Name { get; set; }
    public event EventHandler Completed;

    private DispatcherTimer _dt = new DispatcherTimer();

    public void Show()
    {

        _dt.Interval = this.Duration;
        _dt.Tick += (s, e) =>
        {
            _dt.Stop();
            Completed(this, new EventArgs());
        };
        _dt.Start();

    }
}

这是我的播放器:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
    }

    int _pIndex = 0;
    List<IItem> list = new List<IItem>();

    private void Button1_Click(object sender, RoutedEventArgs e)
    {
        list = new List<IItem>()
        {
            new ItemImage() { Duration = TimeSpan.FromSeconds(5), Name = "Image1" },
            new ItemImage() { Duration = TimeSpan.FromSeconds(3), Name = "Image2" },
            new ItemImage() { Duration = TimeSpan.FromSeconds(5), Name = "Image3" },
            new ItemImage() { Duration = TimeSpan.FromSeconds(7), Name = "Image4" }
        };
        Next();
    }

    void Next()
    {
        var tb = new TextBlock();
        tb.Text = ((IItem)list[_pIndex]).Name;
        StackPanel1.Children.Add(tb);

        list[_pIndex].Completed += (s, e) =>
        {
            Next();
        };
        list[_pIndex].Show();
        _pIndex++;
        _pIndex %= list.Count;

    }
}

第一个列表没有问题,但在第二个回合中,DispatcherTimer不会等待我的持续时间值,并立即触发完成事件。我做错了什么? 感谢。

1 个答案:

答案 0 :(得分:2)

我不确切知道发生了什么(我没有测试过),但我发现每次拨打Show()时,另一个事件处理程序都附加到Tick ItemImage 1}}对象。这可能会导致您遇到的一些副作用。

您可以将其更改为:

internal class ItemImage : IItem 
{   

    public TimeSpan Duration { get; set; }
    public string Name { get; set; }
    public event EventHandler Completed;

    private DispatcherTimer _dt = new DispatcherTimer();

    // constructor
    public ItemImage()
    {
        _dt.Tick += (s, e) =>
        {
            _dt.Stop();
            Completed(this, new EventArgs());
        };
    }

    public void Show()
    {
        _dt.Interval = this.Duration;
        _dt.Start();

    }
}

您可以重新创建DispatcherTimer或移动附加到构造函数的事件。 (如上所述)

这也是使用Next()list[_pIndex].Completed方法中完成的。 (它附加到类成员,因此每个按钮单击新处理程序都会添加到列表中。)

您可以协调附加事件的风格。就像将它们移动到构造函数一样。

像:

public partial class MainWindow : Window
{
    int _pIndex = 0;
    List<IItem> list = new List<IItem>();


    public MainWindow()
    {
        InitializeComponent();

        list[_pIndex].Completed += (s, e) =>
        {
            _pIndex++;
            _pIndex %= list.Count;

            Next();
        };

    }

    private void Button1_Click(object sender, RoutedEventArgs e)
    {
        list = new List<IItem>()
        {
            new ItemImage() { Duration = TimeSpan.FromSeconds(5), Name = "Image1" },
            new ItemImage() { Duration = TimeSpan.FromSeconds(3), Name = "Image2" },
            new ItemImage() { Duration = TimeSpan.FromSeconds(5), Name = "Image3" },
            new ItemImage() { Duration = TimeSpan.FromSeconds(7), Name = "Image4" }
        };
        Next();
    }

    void Next()
    {
        var tb = new TextBlock();
        tb.Text = ((IItem)list[_pIndex]).Name;
        StackPanel1.Children.Add(tb);
        list[_pIndex].Show();
    }
}
祝你好运。