【问题标题】:Desktop alert does not work in sub methods桌面警报在子方法中不起作用
【发布时间】:2015-03-13 16:29:15
【问题描述】:

我正在使用 Ivan Leonenko (@codeproject.com) 的“Growl Alike WPF 通知”。

这在我在 MainWindow 中添加通知时有效。
当我在子方法中添加通知时,警报不会出现。

这是我的工作代码:

    private User user;
    private readonly GrowlNotifiactions growlNotifications = new GrowlNotifiactions();

    public MainWindow()
    {
        InitializeComponent();

        // Sample output GrowlNotification works
        addAlertDesktop("Hello #1", "Lorem Ipsum");
        addAlertDesktop("Hello #2", "Lorem Ipsum");
        addAlertDesktop("Hello #3", "Lorem Ipsum");
    }

    private void addAlertDesktop(string title, string message)
    {
        growlNotifications.AddNotification(new Notification { Title = title, ImageUrl = "pack://application:,,,/Resources/notification-icon.png", Message = message });
    }

这是不起作用的代码:

    private User user;
    private readonly GrowlNotifiactions growlNotifications = new GrowlNotifiactions();

    public MainWindow()
    {
        InitializeComponent();
    }

    private void addAlertDesktop(string title, string message)
    {
        growlNotifications.AddNotification(new Notification { Title = title, ImageUrl = "pack://application:,,,/Resources/notification-icon.png", Message = message });
    }

    private void setTimer(User user) {
        Timer timer = new Timer(5000);
        systemTimer.Elapsed += (sender, e) => OnTimerElapsed(user);
        systemTimer.AutoReset = true;
        systemTimer.Enabled = true;
    }

    private void OnTimerElapsed(User user)
    {
        checkUser(user);
    }

    private void myButton_Click(object sender, RoutedEventArgs e) {
        User currentUser = (User)sender;
        checkUser(user);
    }

    private void checkUser(User user)  {
        setTimer(user);
        addAlertDesktop("Hello #1", "Lorem Ipsum");
        user.checked = 1;
    }

【问题讨论】:

  • 确保您没有遇到异常 - 因为您在 Timer 回调中,any exceptions may be getting swallowed
  • 是的,有一个抛出的异常。但我不明白。 “如果不是由调度程序线程完成,则从这个集合视图类型不支持对“源集合”的更改。”
  • 假设当您调用 addAlertDesktop 时它会更改 UI。如果是这种情况,这可能会失败,因为计时器回调是异步的,因此不在 UI 线程上。如果是这种情况,请查看 DispatcherTimer
  • 听起来它不喜欢从未创建它的线程添加通知。不确定 WPF,但在 winforms 中你会检查 InvokeRequired 并在必要时使用 Invoke

标签: c# wpf


【解决方案1】:

如果这是您尝试从后台线程更新 UI 的问题;尝试用DispatcherTimer替换你的定时器:

DispatcherTimer timer = new DispatcherTimer();
timer.Interval = 5000;
timer.Tick += (sender, e) => OnTimerElapsed(user);
timer.Start();

如果您想继续使用 Timer 类,您仍然可以将后续代码编组到调度程序:

将 addAlertDesktop 更改为:

Application.Current.Dispatcher.Invoke(() = > growlNotifications.AddNotification(new Notification { Title = title, ImageUrl = "pack://application:,,,/Resources/notification-icon.png", Message = message }));

【讨论】:

  • 我有一个名为 TaskTimer 的类,它实现了 System.Timers.Timer,其中传递了毫秒: public TaskTimer(int interval) : base(interval); DispatcherTimer 不接受秒作为整数。我该如何自定义它?
  • 我已经更新了答案以展示一种继续使用 Timer 类的方法
  • 使用 dispatchertimer 你可以像这样以秒为单位设置间隔: timer.Interval = TimeSpan.FromSeconds(5)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-12-01
  • 2014-11-18
  • 2015-10-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多