文章目录
隐藏
WPF 多窗口分文件实现方案
项目文件结构
WindowSwitcher/
├── App.xaml
├── App.xaml.cs
├── MainWindow.xaml
├── MainWindow.xaml.cs
├── Views/
│ ├── SettingsWindow.xaml
│ ├── SettingsWindow.xaml.cs
│ ├── DataWindow.xaml
│ ├── DataWindow.xaml.cs
│ ├── HelpWindow.xaml
│ └── HelpWindow.xaml.cs
└── Services/
└── WindowManager.cs
1. 主窗口 (MainWindow.xaml)
Window x:Class="WindowSwitcher.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WindowSwitcher"
Title="窗口切换管理器" Height="450" Width="800">
Grid>
Grid.RowDefinitions>
RowDefinition Height="Auto"/>
RowDefinition Height="*"/>
Grid.RowDefinitions>
StackPanel Grid.Row="0" Orientation="Horizontal" Background="#f0f0f0" Padding="10">
Button Content="主窗口" Margin="5" Padding="10,5" Click="ShowMainWindow"/>
Button Content="设置窗口" Margin="5" Padding="10,5" Click="ShowSettingsWindow"/>
Button Content="数据窗口" Margin="5" Padding="10,5" Click="ShowDataWindow"/>
Button Content="帮助窗口" Margin="5" Padding="10,5" Click="ShowHelpWindow"/>
Button Content="退出应用" Margin="5" Padding="10,5" Click="ExitApplication"
Background="#ffcccc" Foreground="DarkRed"/>
StackPanel>
StackPanel Grid.Row="1" VerticalAlignment="Center" HorizontalAlignment="Center">
TextBlock Text="欢迎使用窗口切换管理器" FontSize="24" Margin="0,0,0,20"/>
TextBlock Text="{Binding CurrentStatus}" FontSize="18" Foreground="#666"/>
Button Content="刷新窗口状态" Margin="0,20,0,0" Padding="10,5" Click="RefreshStatus"/>
StackPanel>
Grid>
Window>
2. 主窗口代码 (MainWindow.xaml.cs)
using WindowSwitcher.Services;
using System.Windows;
namespace WindowSwitcher
{
public partial class MainWindow : Window
{
private readonly WindowManager _windowManager = WindowManager.Instance;
public string CurrentStatus => $"当前活动窗口: {_windowManager.ActiveWindow?.Title}";
public MainWindow()
{
InitializeComponent();
DataContext = this;
// 初始化所有窗口
_windowManager.InitializeWindows();
// 显示主窗口
_windowManager.ShowWindowMainWindow>();
}
// 按钮事件处理
private void ShowMainWindow(object sender, RoutedEventArgs e) =>
_windowManager.ShowWindowMainWindow>();
private void ShowSettingsWindow(object sender, RoutedEventArgs e) =>
_windowManager.ShowWindowSettingsWindow>();
private void ShowDataWindow(object sender, RoutedEventArgs e) =>
_windowManager.ShowWindowDataWindow>();
private void ShowHelpWindow(object sender, RoutedEventArgs e) =>
_windowManager.ShowWindowHelpWindow>();
private void ExitApplication(object sender, RoutedEventArgs e) =>
Application.Current.Shutdown();
private void RefreshStatus(object sender, RoutedEventArgs e)
{
// 刷新数据绑定
OnPropertyChanged(nameof(CurrentStatus));
}
// 实现简单的属性变更通知
public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName));
}
}
}
3. 设置窗口 (Views/SettingsWindow.xaml)
Window x:Class="WindowSwitcher.Views.SettingsWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="系统设置" Height="400" Width="600">
Grid Margin="20">
Grid.RowDefinitions>
RowDefinition Height="Auto"/>
RowDefinition Height="Auto"/>
RowDefinition Height="Auto"/>
RowDefinition Height="Auto"/>
RowDefinition Height="*"/>
Grid.RowDefinitions>
TextBlock Grid.Row="0" Text="系统设置" FontSize="20" FontWeight="Bold" Margin="0,0,0,20"/>
StackPanel Grid.Row="1" Orientation="Horizontal" Margin="0,0,0,10">
TextBlock Text="主题:" Width="100" VerticalAlignment="Center"/>
ComboBox Width="200">
ComboBoxItem Content="浅色主题"/>
ComboBoxItem Content="深色主题" IsSelected="True"/>
ComboBox>
StackPanel>
StackPanel Grid.Row="2" Orientation="Horizontal" Margin="0,0,0,10">
TextBlock Text="语言:" Width="100" VerticalAlignment="Center"/>
ComboBox Width="200">
ComboBoxItem Content="中文"/>
ComboBoxItem Content="English"/>
ComboBox>
StackPanel>
StackPanel Grid.Row="3" Orientation="Horizontal" Margin="0,0,0,20">
TextBlock Text="自动保存:" Width="100" VerticalAlignment="Center"/>
CheckBox IsChecked="True" VerticalAlignment="Center"/>
StackPanel>
Button Grid.Row="4" Content="返回主窗口" HorizontalAlignment="Center"
Padding="10,5" Click="ReturnToMain" VerticalAlignment="Bottom"/>
Grid>
Window>
4. 设置窗口代码 (Views/SettingsWindow.xaml.cs)
using System.Windows;
using WindowSwitcher.Services;
namespace WindowSwitcher.Views
{
public partial class SettingsWindow : Window
{
private readonly WindowManager _windowManager = WindowManager.Instance;
public SettingsWindow()
{
InitializeComponent();
}
private void ReturnToMain(object sender, RoutedEventArgs e)
{
_windowManager.ShowWindowMainWindow>();
}
}
}
5. 数据窗口 (Views/DataWindow.xaml)
Window x:Class="WindowSwitcher.Views.DataWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="数据分析" Height="500" Width="700">
Grid Margin="15">
Grid.RowDefinitions>
RowDefinition Height="Auto"/>
RowDefinition Height="*"/>
RowDefinition Height="Auto"/>
Grid.RowDefinitions>
TextBlock Grid.Row="0" Text="数据分析面板" FontSize="20" FontWeight="Bold" Margin="0,0,0,15"/>
DataGrid Grid.Row="1" AutoGenerateColumns="True" ItemsSource="{Binding DataItems}">
DataGrid.Columns>
DataGridTextColumn Header="ID" Binding="{Binding Id}" Width="Auto"/>
DataGridTextColumn Header="名称" Binding="{Binding Name}" Width="*"/>
DataGridTextColumn Header="数值" Binding="{Binding Value}" Width="Auto"/>
DataGridTextColumn Header="日期" Binding="{Binding Date, StringFormat=yyyy-MM-dd}" Width="Auto"/>
DataGrid.Columns>
DataGrid>
StackPanel Grid.Row="2" Orientation="Horizontal" HorizontalAlignment="Right" Margin="0,15,0,0">
Button Content="加载数据" Padding="10,5" Margin="0,0,10,0" Click="LoadData"/>
Button Content="返回主窗口" Padding="10,5" Click="ReturnToMain"/>
StackPanel>
Grid>
Window>
6. 数据窗口代码 (Views/DataWindow.xaml.cs)
using System.Windows;
using System.Collections.ObjectModel;
using WindowSwitcher.Services;
namespace WindowSwitcher.Views
{
public partial class DataWindow : Window
{
private readonly WindowManager _windowManager = WindowManager.Instance;
// 数据模型
public class DataItem
{
public int Id { get; set; }
public string Name { get; set; }
public double Value { get; set; }
public DateTime Date { get; set; }
}
// 数据集合
public ObservableCollectionDataItem> DataItems { get; } = new ObservableCollectionDataItem>();
public DataWindow()
{
InitializeComponent();
DataContext = this;
// 初始加载一些示例数据
LoadSampleData();
}
private void LoadSampleData()
{
DataItems.Clear();
// 添加示例数据
DataItems.Add(new DataItem { Id = 1, Name = "项目A", Value = 42.5, Date = DateTime.Now.AddDays(-2) });
DataItems.Add(new DataItem { Id = 2, Name = "项目B", Value = 78.3, Date = DateTime.Now.AddDays(-1) });
DataItems.Add(new DataItem { Id = 3, Name = "项目C", Value = 15.2, Date = DateTime.Now });
}
private void LoadData(object sender, RoutedEventArgs e)
{
// 模拟加载更多数据
int startId = DataItems.Count + 1;
for (int i = 0; i 5; i++)
{
DataItems.Add(new DataItem
{
Id = startId + i,
Name = $"新增项目{startId + i}",
Value = new Random().NextDouble() * 100,
Date = DateTime.Now.AddDays(-i)
});
}
}
private void ReturnToMain(object sender, RoutedEventArgs e)
{
_windowManager.ShowWindowMainWindow>();
}
}
}
7. 帮助窗口 (Views/HelpWindow.xaml)
Window x:Class="WindowSwitcher.Views.HelpWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="帮助文档" Height="350" Width="500">
Grid Margin="15">
Grid.RowDefinitions>
RowDefinition Height="Auto"/>
RowDefinition Height="*"/>
RowDefinition Height="Auto"/>
Grid.RowDefinitions>
TextBlock Grid.Row="0" Text="帮助与支持" FontSize="20" FontWeight="Bold" Margin="0,0,0,10"/>
ScrollViewer Grid.Row="1" VerticalScrollBarVisibility="Auto">
TextBlock TextWrapping="Wrap">
Run FontWeight="Bold">如何使用窗口切换功能:Run>
LineBreak/>
1. 点击顶部导航栏中的按钮可在不同窗口间切换
LineBreak/>
2. 每个窗口都提供"返回主窗口"按钮
LineBreak/>
3. 窗口状态会被保留,再次打开时保持上次的状态
LineBreak/>LineBreak/>
Run FontWeight="Bold">常见问题:Run>
LineBreak/>
Q: 为什么关闭按钮只是隐藏窗口?
LineBreak/>
A: 这是设计选择,为了保持窗口状态并快速切换。要完全退出应用,请使用"退出应用"按钮。
LineBreak/>LineBreak/>
Run FontWeight="Bold">技术支持:Run>
LineBreak/>
如有任何问题,请联系 support@windowswitcher.com
TextBlock>
ScrollViewer>
Button Grid.Row="2" Content="返回主窗口" Padding="10,5"
HorizontalAlignment="Center" Margin="0,15,0,0" Click="ReturnToMain"/>
Grid>
Window>
8. 帮助窗口代码 (Views/HelpWindow.xaml.cs)
using System.Windows;
using WindowSwitcher.Services;
namespace WindowSwitcher.Views
{
public partial class HelpWindow : Window
{
private readonly WindowManager _windowManager = WindowManager.Instance;
public HelpWindow()
{
InitializeComponent();
}
private void ReturnToMain(object sender, RoutedEventArgs e)
{
_windowManager.ShowWindowMainWindow>();
}
}
}
9. 窗口管理器 (Services/WindowManager.cs)
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Windows;
using WindowSwitcher.Views;
namespace WindowSwitcher.Services
{
public sealed class WindowManager
{
// 单例实例
private static readonly LazyWindowManager> _instance =
new LazyWindowManager>(() => new WindowManager());
public static WindowManager Instance => _instance.Value;
// 存储所有窗口实例
private readonly DictionaryType, Window> _windows = new DictionaryType, Window>();
// 当前活动窗口
public Window ActiveWindow { get; private set; }
private WindowManager() { }
// 初始化所有窗口
public void InitializeWindows()
{
// 创建主窗口
CreateWindowMainWindow>();
// 创建其他窗口
CreateWindowSettingsWindow>();
CreateWindowDataWindow>();
CreateWindowHelpWindow>();
}
// 创建窗口实例
private void CreateWindowT>() where T : Window, new()
{
var windowType = typeof(T);
if (!_windows.ContainsKey(windowType))
{
var window = new T();
window.Closing += OnWindowClosing;
_windows[windowType] = window;
}
}
// 显示指定类型的窗口
public void ShowWindowT>() where T : Window
{
var windowType = typeof(T);
if (_windows.TryGetValue(windowType, out Window window))
{
// 隐藏当前活动窗口
if (ActiveWindow != null && ActiveWindow != window)
{
ActiveWindow.Hide();
}
// 显示新窗口
window.Show();
window.Activate();
window.Focus();
ActiveWindow = window;
}
else
{
// 如果窗口尚未创建,则创建并显示
CreateWindowT>();
ShowWindowT>();
}
}
// 窗口关闭事件处理
private void OnWindowClosing(object sender, CancelEventArgs e)
{
if (sender is Window window)
{
// 阻止实际关闭,改为隐藏
e.Cancel = true;
window.Hide();
// 如果关闭的是当前活动窗口,则激活主窗口
if (ActiveWindow == window)
{
ShowWindowMainWindow>();
}
}
}
// 获取特定类型的窗口
public T GetWindowT>() where T : Window
{
return _windows.TryGetValue(typeof(T), out Window window) ? (T)window : null;
}
// 关闭所有窗口并退出
public void ShutdownApplication()
{
// 关闭所有窗口
foreach (var window in _windows.Values)
{
window.Closing -= OnWindowClosing;
window.Close();
}
_windows.Clear();
Application.Current.Shutdown();
}
}
}
10. 应用程序入口 (App.xaml)
Application x:Class="WindowSwitcher.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="MainWindow.xaml">
Application.Resources>
Application.Resources>
Application>
11. 应用程序入口代码 (App.xaml.cs)
using System.Windows;
using WindowSwitcher.Services;
namespace WindowSwitcher
{
public partial class App : Application
{
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
// 初始化窗口管理器
var windowManager = WindowManager.Instance;
windowManager.InitializeWindows();
}
protected override void OnExit(ExitEventArgs e)
{
// 清理资源
WindowManager.Instance.ShutdownApplication();
base.OnExit(e);
}
}
}
关键实现说明
1. 分文件组织
- MainWindow:主窗口,作为应用入口
- Views文件夹:包含所有其他窗口(设置、数据、帮助)
- Services文件夹:包含窗口管理器服务
2. 窗口管理器核心功能
// 创建窗口
private void CreateWindowT>() where T : Window, new()
{
var windowType = typeof(T);
if (!_windows.ContainsKey(windowType))
{
var window = new T();
window.Closing += OnWindowClosing;
_windows[windowType] = window;
}
}
// 切换窗口
public void ShowWindowT>() where T : Window
{
// ...
window.Show();
window.Activate();
window.Focus();
ActiveWindow = window;
}
// 处理关闭事件
private void OnWindowClosing(object sender, CancelEventArgs e)
{
e.Cancel = true; // 阻止实际关闭
window.Hide(); // 改为隐藏
}
3. 数据绑定示例
在数据窗口中,展示了如何使用数据绑定:
// 数据模型
public class DataItem
{
public int Id { get; set; }
public string Name { get; set; }
public double Value { get; set; }
public DateTime Date { get; set; }
}
// 数据集合
public ObservableCollectionDataItem> DataItems { get; } = new ObservableCollectionDataItem>();
// XAML绑定
DataGrid ItemsSource="{Binding DataItems}">
4. 属性变更通知
在主窗口中实现了简单的属性变更通知:
public string CurrentStatus => $"当前活动窗口: {_windowManager.ActiveWindow?.Title}";
// 刷新方法
private void RefreshStatus(object sender, RoutedEventArgs e)
{
OnPropertyChanged(nameof(CurrentStatus));
}
// 实现INotifyPropertyChanged
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
使用说明
-
项目结构:
- 创建一个新的WPF应用程序项目
- 按上述文件结构组织代码
-
启动应用:
- 应用程序启动时会初始化所有窗口
- 主窗口首先显示
-
窗口切换:
- 使用顶部导航栏按钮在不同窗口间切换
- 每个窗口都有返回主窗口的按钮
-
关闭窗口:
- 点击关闭按钮实际上是隐藏窗口
- 使用”退出应用”按钮完全关闭程序
-
数据保持:
- 每个窗口的状态在切换时保持不变
- 数据窗口中的数据在重新打开时保持
这种分文件实现方式使代码结构清晰,便于维护和扩展,同时保持了窗口切换的高性能和状态保持特性。
文章来源于互联网:WPF 多窗口分文件实现方案
相关推荐: CSS 布局系统深度解析:从传统到现代的布局方案
CSS布局系统深度解析:从传统到现代的布局方案 一、CSS布局发展概述 CSS布局的演进历程反映了前端开发对页面结构控制的需求升级。早期的布局依赖HTML表格()和浮动(float),但存在语义混乱、布局僵化等问题。随着CSS2.1到CSS3的发展,现代布局系…
5bei.cn大模型教程网










