在没有主窗口的 WPF 应用程序中从新线程创建窗口
我正在开发一个没有主窗口的 WPF 应用程序(它使用 http://www.codeproject.com/KB/WPF/wpf_notifyicon.aspx)。
在 App.xaml.cs 中,我创建了一个新线程,它运行一些返回自定义警报集合的监视代码。该集合有一个 render() 方法,我计划用它来显示一个包含警报信息的窗口,但我不知道如何实现它。如果有任何意见,我将不胜感激。
下面的代码示例:
App.xaml:
<Application x:Class="DowntimeReportMonitor.Views.Icon.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Startup="Application_Startup"
Exit="Application_Exit">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="IconDictionary.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>
App.xaml.cs
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Threading;
using System.Windows;
using Hardcodet.Wpf.TaskbarNotification;
using DowntimeReportMonitor.Core;
namespace DowntimeReportMonitor.Views.Icon
{
/// <summary>
/// Interaction logic for App.xaml
/// </summary>
public partial class App : Application
{
private TaskbarIcon _taskbaricon;
private AlertWorker _alertWorker;
private Thread _alertWorkerThread;
/// <summary>
/// Event handler for Application startup
/// </summary>
/// <param name="sender">The event sender</param>
/// <param name="e">Event arguments</param>
private void Application_Startup(object sender, StartupEventArgs e)
{
// Create and start a new TaskbarIcon.
this._taskbaricon = (TaskbarIcon)FindResource("notificationIcon");
// Create and start a new AlertWorker.
this._alertWorker = new AlertWorker();
this._alertWorkerThread = new Thread(this._alertWorker.doWork);
this._alertWorkerThread.SetApartmentState(ApartmentState.STA);
this._alertWorkerThread.Start();
}
/// <summary>
/// Event handler for Application exit
/// </summary>
/// <param name="sender">The event sender</param>
/// <param name="e">Event arguments</param>
private void Application_Exit(object sender, ExitEventArgs e)
{
// Stop the alert worker.
this._alertWorker.requestStop();
this._alertWorkerThread.Join();
// Dispose of the notification icon.
this._taskbaricon.Dispose();
}
}
}
AlertWorker.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using DowntimeReportMonitor.Core;
namespace DowntimeReportMonitor.Views.Icon
{
class AlertWorker
{
private volatile bool _stopRequested;
private ReportMonitor _reportMonitor;
public AlertWorker()
{
_reportMonitor = new ReportMonitor(new wpfRenderableReportAlertCollection());
}
public void doWork()
{
while (!_stopRequested)
{
this._reportMonitor.monitorReports().render();
Thread.Sleep(30000);
}
}
public void requestStop()
{
this._stopRequested = true;
}
}
}
I'm working on a WPF application that has no main window (it runs in the notification area using code from http://www.codeproject.com/KB/WPF/wpf_notifyicon.aspx).
In the App.xaml.cs, I've created a new thread which runs some monitoring code that returns a custom collection of alerts. The collection has a render() method which I planned to use to show a window with the alert information in them, but I can't figure out how to accomplish it. I'd be grateful for any input.
Code samples below:
App.xaml:
<Application x:Class="DowntimeReportMonitor.Views.Icon.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Startup="Application_Startup"
Exit="Application_Exit">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="IconDictionary.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>
App.xaml.cs
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Threading;
using System.Windows;
using Hardcodet.Wpf.TaskbarNotification;
using DowntimeReportMonitor.Core;
namespace DowntimeReportMonitor.Views.Icon
{
/// <summary>
/// Interaction logic for App.xaml
/// </summary>
public partial class App : Application
{
private TaskbarIcon _taskbaricon;
private AlertWorker _alertWorker;
private Thread _alertWorkerThread;
/// <summary>
/// Event handler for Application startup
/// </summary>
/// <param name="sender">The event sender</param>
/// <param name="e">Event arguments</param>
private void Application_Startup(object sender, StartupEventArgs e)
{
// Create and start a new TaskbarIcon.
this._taskbaricon = (TaskbarIcon)FindResource("notificationIcon");
// Create and start a new AlertWorker.
this._alertWorker = new AlertWorker();
this._alertWorkerThread = new Thread(this._alertWorker.doWork);
this._alertWorkerThread.SetApartmentState(ApartmentState.STA);
this._alertWorkerThread.Start();
}
/// <summary>
/// Event handler for Application exit
/// </summary>
/// <param name="sender">The event sender</param>
/// <param name="e">Event arguments</param>
private void Application_Exit(object sender, ExitEventArgs e)
{
// Stop the alert worker.
this._alertWorker.requestStop();
this._alertWorkerThread.Join();
// Dispose of the notification icon.
this._taskbaricon.Dispose();
}
}
}
AlertWorker.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using DowntimeReportMonitor.Core;
namespace DowntimeReportMonitor.Views.Icon
{
class AlertWorker
{
private volatile bool _stopRequested;
private ReportMonitor _reportMonitor;
public AlertWorker()
{
_reportMonitor = new ReportMonitor(new wpfRenderableReportAlertCollection());
}
public void doWork()
{
while (!_stopRequested)
{
this._reportMonitor.monitorReports().render();
Thread.Sleep(30000);
}
}
public void requestStop()
{
this._stopRequested = true;
}
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
首先,您需要一个专用的 UI 线程。通常它是初始应用程序线程,但您可以采用任何线程。 (它必须是 STA 线程。)
接下来,您在该线程中启动一个调度程序 (Dispatcher.CurrentDispatcher.运行)。
接下来,您可以使用 Dispatcher.Invoke 或 Dispatcher.BeginInvoke 将命令发布到该线程。
最后,您可以将您的自定义 Window 类发布到线程
window.Show
中。Well, first of all, you need a dedicated UI thread. Usually it's the initial application thread, but you can take any. (It must be an STA thread.)
Next, you start a dispather in that thread (Dispatcher.CurrentDispatcher.Run).
Next, you can post commands to that thread using Dispatcher.Invoke or Dispatcher.BeginInvoke.
Finally, you can post to your thread
window.Show
for your custom Window class.