当前位置: 首页 > news >正文

WPF 多窗口分文件实现方案

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.ShowWindow<MainWindow>();}// 按钮事件处理private void ShowMainWindow(object sender, RoutedEventArgs e) => _windowManager.ShowWindow<MainWindow>();private void ShowSettingsWindow(object sender, RoutedEventArgs e) => _windowManager.ShowWindow<SettingsWindow>();private void ShowDataWindow(object sender, RoutedEventArgs e) => _windowManager.ShowWindow<DataWindow>();private void ShowHelpWindow(object sender, RoutedEventArgs e) => _windowManager.ShowWindow<HelpWindow>();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.ShowWindow<MainWindow>();}}
}

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 ObservableCollection<DataItem> DataItems { get; } = new ObservableCollection<DataItem>();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.ShowWindow<MainWindow>();}}
}

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.ShowWindow<MainWindow>();}}
}

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 Lazy<WindowManager> _instance = new Lazy<WindowManager>(() => new WindowManager());public static WindowManager Instance => _instance.Value;// 存储所有窗口实例private readonly Dictionary<Type, Window> _windows = new Dictionary<Type, Window>();// 当前活动窗口public Window ActiveWindow { get; private set; }private WindowManager() { }// 初始化所有窗口public void InitializeWindows(){// 创建主窗口CreateWindow<MainWindow>();// 创建其他窗口CreateWindow<SettingsWindow>();CreateWindow<DataWindow>();CreateWindow<HelpWindow>();}// 创建窗口实例private void CreateWindow<T>() where T : Window, new(){var windowType = typeof(T);if (!_windows.ContainsKey(windowType)){var window = new T();window.Closing += OnWindowClosing;_windows[windowType] = window;}}// 显示指定类型的窗口public void ShowWindow<T>() 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{// 如果窗口尚未创建,则创建并显示CreateWindow<T>();ShowWindow<T>();}}// 窗口关闭事件处理private void OnWindowClosing(object sender, CancelEventArgs e){if (sender is Window window){// 阻止实际关闭,改为隐藏e.Cancel = true;window.Hide();// 如果关闭的是当前活动窗口,则激活主窗口if (ActiveWindow == window){ShowWindow<MainWindow>();}}}// 获取特定类型的窗口public T GetWindow<T>() 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 CreateWindow<T>() where T : Window, new()
{var windowType = typeof(T);if (!_windows.ContainsKey(windowType)){var window = new T();window.Closing += OnWindowClosing;_windows[windowType] = window;}
}// 切换窗口
public void ShowWindow<T>() 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 ObservableCollection<DataItem> DataItems { get; } = new ObservableCollection<DataItem>();// 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));
}

使用说明

  1. 项目结构

    • 创建一个新的WPF应用程序项目
    • 按上述文件结构组织代码
  2. 启动应用

    • 应用程序启动时会初始化所有窗口
    • 主窗口首先显示
  3. 窗口切换

    • 使用顶部导航栏按钮在不同窗口间切换
    • 每个窗口都有返回主窗口的按钮
  4. 关闭窗口

    • 点击关闭按钮实际上是隐藏窗口
    • 使用"退出应用"按钮完全关闭程序
  5. 数据保持

    • 每个窗口的状态在切换时保持不变
    • 数据窗口中的数据在重新打开时保持

这种分文件实现方式使代码结构清晰,便于维护和扩展,同时保持了窗口切换的高性能和状态保持特性。

http://www.dtcms.com/a/281977.html

相关文章:

  • openEuler 22.03 LTS Rootless Docker 安装指南
  • 【MySQL基础】MySQL事务详解:原理、特性与实战应用
  • 每日算法刷题Day49:7.16:leetcode 差分5道题,用时2h
  • c语言-数据结构-二叉树的遍历
  • 数字ic后端设计从入门到精通11(含fusion compiler, tcl教学)全定制设计入门
  • arm版本的ubuntu安装git或者vim等方法
  • 力扣-23.合并K个升序链表
  • Linux 驱动中 Timer / Tasklet / Workqueue 的作用与对比
  • 查看.bin二进制文件的方式(HxD十六进制编辑器的安装)
  • 电路仿真——精密半波整流电路
  • 133. Java 泛型 - 目标类型与方法参数:重载解析与类型推导
  • 网络编程(数据库)
  • 在虚拟环境中复现论文(环境配置)
  • 力扣 hot100 Day46
  • 01 启动流程实例
  • 基于docker的redis集群
  • 开源 python 应用 开发(七)数据可视化
  • 基于大数据电信诈骗行为分析与可视化预测系统的设计与实现【海量数据、多种机器学习对比、数据优化、过采样】
  • 软路由 + 代理 IP 实现多手机不同公网 IP 分配教程
  • 60个功能OfficeBox 万彩办公大师:PDF 格式转换 OCR识别免费无广告
  • 【数据结构】栈与链表的区别
  • 物联网CAN通讯(控制器局域网络)(寄存器版+HAL库版)
  • 分布式缓存击穿以及本地击穿解决方案
  • xss-labs练习
  • 「源力觉醒 创作者计划」_巅峰对话:文心大模型4.5系列与DeepSeek/Qwen 3.0深度解析
  • React -自定义hooks - 封装双向数据绑定
  • 【NLP舆情分析】基于python微博舆情分析可视化系统(flask+pandas+echarts) 视频教程 - 微博类别信息爬取
  • 在 Spring Boot 中监控异步任务的执行情况
  • Flask 项目结构
  • Flask的基本概念