2

我的代码中有问题,我什至无法理解。

这是我的物品界面;

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

4

1 回答 1

2

我不确切知道发生了什么(我没有测试它),但我看到每次你调用时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或移动附加到构造函数的事件。(如上)

这也在 with 的Next()方法中完成list[_pIndex].Completed。(它附加到一个类成员,因此每个 buttonclick 新处理程序都添加到列表中。)

您可能会重新考虑附加事件的样式。就像将它们移至构造函数一样。

喜欢:

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

祝你好运。

于 2013-11-21T10:46:47.950 回答