c# - .net DispatcherTimer 重复触发刻度事件

标签 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 不会等待我的持续时间值,并立即触发完成事件。我做错了什么? 谢谢。

最佳答案

我不知道到底发生了什么(我没有测试它),但我看到每次调用 Show() 时,另一个事件处理程序会附加到 Tick 在您的 ItemImage 对象中。这可能会导致您遇到一些副作用。

您可以将其更改为:

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();
    }
}

祝你好运。

关于c# - .net DispatcherTimer 重复触发刻度事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20118101/

相关文章:

c# - 如何从 XML 反序列化未知类型?

c# - 是否可以在有人连接之前在 WCF 服务中执行启动代码?

c# - Ninject - Binding.GetProvider 抛出 NullReferenceException

.net - WCF数据服务SaveChanges问题

.net - .NET 中的调试和发布二进制文件有什么区别?

c# - 在 wpf C# 中显示标签 3/5 秒,但点击后不会停留那么久

c# - DispatcherTimer 仍然在 Stop() 之后勾选事件并设置为 null

c# - 如何清除内存流

c# - 使用 XmlSerializer 序列化 ArrayList