【问题标题】:How to change a picture with a timer如何使用计时器更改图片
【发布时间】:2019-02-10 08:53:48
【问题描述】:

我正在尝试以 2 秒的时间间隔更改图片。它应该只有一次,而不是无限的时间圈。

我用谷歌搜索了各种替代词,但找不到。就像 thread.sleep(2000) 不起作用,因为它冻结了界面。

public partial class Window1 : Window
{
    private static System.Timers.Timer aTimer;

public void RemoveImage()
    {
        Image.Source = new BitmapImage(new Uri("path to image 2"));
        SetTimer();            
    }

private void SetTimer()
    {
        // Create a timer with a two second interval.
        aTimer = new System.Timers.Timer(2000);
        // Hook up the Elapsed event for the timer. 
        aTimer.Elapsed += OnTimedEvent;
        aTimer.AutoReset = true;
        aTimer.Enabled = true;
    }

private void OnTimedEvent(Object source, ElapsedEventArgs e)
    {
        Image.Source = new BitmapImage(new Uri("path to image 3"));
    }

XAML 代码

<Window

<Image Source="path to image 1" Grid.Row="1" Grid.Column="8" 
Name="Image" Stretch="None" HorizontalAlignment="Center" 
VerticalAlignment="Center"></Image>

</Grid>
</Window>

使用此代码,我可以看到第二张图片,但是当它到达最后一张图片时,您会收到错误 System.InvalidOperationException for image 3。希望您能帮助我解决任何问题

【问题讨论】:

    标签: c# wpf image timer


    【解决方案1】:

    不要将Dispatcher.InvokeSystem.Timers.Timer 一起使用。

    改为使用 DispatcherTimer,它已经在 UI 线程中调用了它的 Tick 处理程序。:

    private DispatcherTimer timer;
    
    private void SetTimer()
    {
        timer = new DispatcherTimer { Interval = TimeSpan.FromSeconds(2) };
        timer.Tick += OnTimerTick;
        timer.Start();
    }
    
    private void OnTimerTick(object sender, EventArgs e)
    {
        Image.Source = new BitmapImage(new Uri("path to image 3"));
        timer.Stop();
    }
    

    【讨论】:

    • 我上面写的是微软官方的示例。说微软的官方样本是不应该做的事情,然后去投票,要求删除答案等是愚蠢的。我承认您的回答非常好,但我的回答也绝对正确,并且因为它有效而被接受。
    • @IvanIčin 这不是如何在 WPF 中使用计时器的“官方示例”。为什么你认为有 DispatcherTimer 类?任何其他方法都是无稽之谈。建议在 DispatcherTimer 以外的其他计时器中使用 Dispatcher.Invoke 的答案只是一个糟糕的建议,因此不赞成
    • 这是关于如何使用 Dispatcher.Invoke 的官方示例,它使用了 Timer。你显然不喜欢它,有自己的偏好也没关系,但你应该尊重实际制作框架的人制定的一些约定。
    • 这不是关于偏好,而是关于简单性。 Microsoft 在 Dispatcher.Invoke 文档中的一段示例代码中显示了 Timer.Elapsed 处理程序这一事实并不意味着这是在 WPF 中使用计时器的正确方法。如果您正在扩展已有 System.Timers.Timer 的遗留代码,您当然会使用 Dispatcher.Invoke,但在编写新代码时当然不会。
    • 这是关于自我的。 Microsoft 显示 Timer.Elapsed 的事实意味着它是可接受的解决方案。不管你会不会说,这只是你的自我,逻辑是显而易见的。
    【解决方案2】:

    定时器在 UI 线程上不起作用,因此您无法更改 OnTimedEvent 中的控件而不调用 Dispatcher.Invoke https://docs.microsoft.com/en-us/dotnet/api/system.windows.threading.dispatcher.invoke?view=netframework-4.7.2

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-11-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-08-28
      相关资源
      最近更新 更多