WPF应用开发:窗口交互、单实例应用与文件类型注册
立即解锁
发布时间: 2025-08-26 02:03:38 阅读量: 1 订阅数: 15 


WPF开发核心精要
### WPF 应用开发:窗口交互、单实例应用与文件类型注册
#### 1. 主窗口初始化与文件加载
在应用启动时,我们通常需要初始化主窗口并加载可能的文件。以下是一段示例代码:
```csharp
string file = e.Args[0];
if (System.IO.File.Exists(file))
{
// Configure the main window.
win.LoadFile(file);
}
else
{
// (Perform alternate initialization here when
// no command-line arguments are supplied.)
}
// This window will automatically be set as the Application.MainWindow.
win.Show();
```
此代码假设 `FileViewer` 类有一个名为 `LoadFile()` 的公共方法,用于读取并显示指定文件的文本内容。示例如下:
```csharp
public partial class FileViewer : Window
{
...
public void LoadFile(string path)
{
this.Content = File.ReadAllText(path);
this.Title = path;
}
}
```
需要注意的是,WPF 窗口实际上是一种内容控件,它可以包含并显示单个对象,这个对象可以是字符串、控件或能容纳多个控件的面板。
#### 2. 访问当前应用
通过 `Application.Current` 属性,我们可以在应用的任何位置获取当前应用实例。这使得窗口之间能够进行基本的交互,因为任何窗口都可以访问当前应用对象,并通过它获取主窗口的引用。示例代码如下:
```csharp
Window main = Application.Current.MainWindow;
MessageBox.Show("The main window is " + main.Title);
```
如果要访问自定义主窗口类中添加的方法、属性或事件,则需要将窗口对象转换为正确的类型。例如:
```csharp
MainWindow main = (MainWindow)Application.Current.MainWindow;
main.DoSomething();
```
此外,我们还可以通过 `Application.Windows` 集合查看所有当前打开的窗口:
```csharp
foreach (Window window in Application.Current.Windows)
{
MessageBox.Show(window.Title + " is open.");
}
```
不过,在实际应用中,大多数应用更倾向于使用更结构化的窗口交互方式。
#### 3. 窗口间的交互
自定义应用类不仅可以放置响应不同应用事件的代码,还可以存储重要窗口的引用,以便一个窗口能够访问另一个窗口。例如,我们可以在自定义应用类中创建一个集合来跟踪所有文档窗口:
```csharp
public partial class App : Application
{
private List<Document> documents = new List<Document>();
public List<Document> Documents
{
get { return documents; }
set { documents = value; }
}
}
```
当创建新文档时,需要将其添加到 `Documents` 集合中。以下是一个响应按钮点击事件的示例:
```csharp
private void cmdCreate_Click(object sender, RoutedEventArgs e)
{
Document doc = new Document();
doc.Owner = this;
doc.Show();
((App)Application.Current).Documents.Add(doc);
}
```
我们也可以在 `Document` 类的 `Window.Loaded` 事件中确保文档对象在创建时自动注册到 `Documents` 集合中。之后,我们可以在代码的其他地方使用该集合遍历所有文档并调用其公共成员:
```csharp
private void cmdUpdate_Click(object sender, RoutedEventArgs e)
{
foreach (Document doc in ((App)Application.Current).Documents)
{
doc.SetContent("Refreshed at " + DateTime.Now.ToLongTimeString() + ".");
}
}
```
这种通过自定义应用类进行窗口交互的方式是安全且规范的,它比直接使用 `Windows` 属性更具优势,因为它是强类型的,并且只包含文档窗口。
#### 4. 单实例应用
通常情况下,我们可以随意启动多个 WPF 应用副本,但在某些场景下,特别是文档型应用,这可能会带来问题。例如,Microsoft Word 无论打开多少文档,同一时间只加载一个 `winword.exe` 实例。
WPF 本身没有为单实例应用提供原生解决方案,但我们可以采用一些变通方法。其中,最简单的方法是在 `Application.Startup` 事件触发时检查应用的另一个实例是否已经在运行,可使用系统范围的互斥体(mutex)来实现。不过,这种方法存在局限性,新实例无法与现有实例进行通信。更复杂的通信通常通过远程处理或 Windows Communication Foundation (WCF) 来完成。
目前,WPF 团队推荐的最简单方法是使用 Windows Forms 中内置的支持,原本是为 Visual Basic 应用设计的。具体实现如下:
首先,添加对 `Microsoft.VisualBasic.dll` 程序集的引用,并从 `Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase` 类派生一个自定义类:
```csharp
public class SingleInstanceApplicationWrapper :
Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase
{
public SingleInstanceApplicationWrapper()
{
// Enable single-instance mode.
this.IsSingleInstance = true;
}
// Create the WPF application class.
private WpfApp app;
protected override bool OnStartup(
Microsoft.VisualBasic.ApplicationServices.StartupEventArgs e)
{
app = new WpfApp();
app.Run();
return f
```
0
0
复制全文
相关推荐










