C#教程

关注公众号 jb51net

关闭
首页 > 软件编程 > C#教程 > WPF系统资源监控

利用WPF实现系统资源监控的完整代码

作者:code_shenbing

在现代软件开发中,系统资源监控是系统管理、性能分析和故障诊断的重要工具,WPF是构建现代化、美观实用的系统监控应用的理想选择,本文将详细介绍如何使用WPF创建一个功能全面的系统资源监控仪表盘,需要的朋友可以参考下

一、引言

在现代软件开发中,系统资源监控是系统管理、性能分析和故障诊断的重要工具。WPF(Windows Presentation Foundation)凭借其强大的数据绑定、样式模板和动画功能,是构建现代化、美观实用的系统监控应用的理想选择。本文将详细介绍如何使用WPF创建一个功能全面的系统资源监控仪表盘。

二、整体架构设计

2.1 系统架构

┌─────────────────────────────────────────────────────┐
│                 WPF UI层 (视图层)                    │
│  ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐  │
│  │ CPU监控 │ │ 内存监控 │ │ 磁盘监控 │ │ 网络监控 │  │
│  └─────────┘ └─────────┘ └─────────┘ └─────────┘  │
└─────────────────────────────────────────────────────┘
                       │
┌─────────────────────────────────────────────────────┐
│              监控服务层 (ViewModel)                   │
│  ┌─────────────────────────────────────────────┐  │
│  │     ResourceMonitorService (单例模式)       │  │
│  └─────────────────────────────────────────────┘  │
└─────────────────────────────────────────────────────┘
                       │
┌─────────────────────────────────────────────────────┐
│             数据采集层 (PerformanceCounter)         │
│  ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐  │
│  │  CPU    │ │  Memory  │ │  Disk   │ │ Network │  │
│  └─────────┘ └─────────┘ └─────────┘ └─────────┘  │
└─────────────────────────────────────────────────────┘

2.2 技术要点

三、完整代码实现

3.1 实体模型层

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SystemResouceWpfApp.Models;

public class SystemResourceInfo : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanged(string propertyName)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }

    // CPU信息
    private float _cpuUsage;
    public float CpuUsage
    {
        get => _cpuUsage;
        set
        {
            if (Math.Abs(_cpuUsage - value) > 0.01)
            {
                _cpuUsage = value;
                OnPropertyChanged(nameof(CpuUsage));
            }
        }
    }

    private List<ProcessInfo> _topProcesses = new List<ProcessInfo>();
    public List<ProcessInfo> TopProcesses
    {
        get => _topProcesses;
        set
        {
            _topProcesses = value;
            OnPropertyChanged(nameof(TopProcesses));
        }
    }

    // 内存信息
    private float _memoryUsage;
    public float MemoryUsage
    {
        get => _memoryUsage;
        set
        {
            if (Math.Abs(_memoryUsage - value) > 0.01)
            {
                _memoryUsage = value;
                OnPropertyChanged(nameof(MemoryUsage));
            }
        }
    }

    private ulong _totalMemory;
    public ulong TotalMemory
    {
        get => _totalMemory;
        set
        {
            if (_totalMemory != value)
            {
                _totalMemory = value;
                OnPropertyChanged(nameof(TotalMemory));
            }
        }
    }

    private ulong _usedMemory;
    public ulong UsedMemory
    {
        get => _usedMemory;
        set
        {
            if (_usedMemory != value)
            {
                _usedMemory = value;
                OnPropertyChanged(nameof(UsedMemory));
            }
        }
    }

    // 磁盘信息
    private List<DiskInfo> _diskInfos = new List<DiskInfo>();
    public List<DiskInfo> DiskInfos
    {
        get => _diskInfos;
        set
        {
            _diskInfos = value;
            OnPropertyChanged(nameof(DiskInfos));
        }
    }

    // 网络信息
    private float _networkUploadSpeed;
    public float NetworkUploadSpeed
    {
        get => _networkUploadSpeed;
        set
        {
            if (Math.Abs(_networkUploadSpeed - value) > 0.01)
            {
                _networkUploadSpeed = value;
                OnPropertyChanged(nameof(NetworkUploadSpeed));
            }
        }
    }

    private float _networkDownloadSpeed;
    public float NetworkDownloadSpeed
    {
        get => _networkDownloadSpeed;
        set
        {
            if (Math.Abs(_networkDownloadSpeed - value) > 0.01)
            {
                _networkDownloadSpeed = value;
                OnPropertyChanged(nameof(NetworkDownloadSpeed));
            }
        }
    }

    // 系统信息
    private DateTime _systemUptime;
    public DateTime SystemUptime
    {
        get => _systemUptime;
        set
        {
            if (_systemUptime != value)
            {
                _systemUptime = value;
                OnPropertyChanged(nameof(SystemUptime));
            }
        }
    }
}

public class ProcessInfo : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    protected virtual void OnPropertyChanged(string propertyName)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }


    public int ProcessId { get; set; }
    public string ProcessName { get; set; }

    private float _cpuPercent;
    public float CpuPercent
    {
        get => _cpuPercent;
        set
        {
            if (Math.Abs(_cpuPercent - value) > 0.01)
            {
                _cpuPercent = value;
                OnPropertyChanged(nameof(CpuPercent));
            }
        }
    }

    private float _memoryMB;
    public float MemoryMB
    {
        get => _memoryMB;
        set
        {
            if (Math.Abs(_memoryMB - value) > 0.01)
            {
                _memoryMB = value;
                OnPropertyChanged(nameof(MemoryMB));
            }
        }
    }
}

public class DiskInfo : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    protected virtual void OnPropertyChanged(string propertyName)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }


    public string DriveLetter { get; set; }
    public string DriveName { get; set; }

    private float _usagePercent;
    public float UsagePercent
    {
        get => _usagePercent;
        set
        {
            if (Math.Abs(_usagePercent - value) > 0.01)
            {
                _usagePercent = value;
                OnPropertyChanged(nameof(UsagePercent));
            }
        }
    }

    private ulong _totalSizeGB;
    public ulong TotalSizeGB
    {
        get => _totalSizeGB;
        set
        {
            if (_totalSizeGB != value)
            {
                _totalSizeGB = value;
                OnPropertyChanged(nameof(TotalSizeGB));
            }
        }
    }

    private ulong _freeSpaceGB;
    public ulong FreeSpaceGB
    {
        get => _freeSpaceGB;
        set
        {
            if (_freeSpaceGB != value)
            {
                _freeSpaceGB = value;
                OnPropertyChanged(nameof(FreeSpaceGB));
            }
        }
    }

    private float _readSpeed;
    public float ReadSpeed
    {
        get => _readSpeed;
        set
        {
            if (Math.Abs(_readSpeed - value) > 0.01)
            {
                _readSpeed = value;
                OnPropertyChanged(nameof(ReadSpeed));
            }
        }
    }

    private float _writeSpeed;
    public float WriteSpeed
    {
        get => _writeSpeed;
        set
        {
            if (Math.Abs(_writeSpeed - value) > 0.01)
            {
                _writeSpeed = value;
                OnPropertyChanged(nameof(WriteSpeed));
            }
        }
    }
}

3.2 监控服务层

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Management;
using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
using SystemResouceWpfApp.Models;



namespace SystemResouceWpfApp.Services;

public class SystemMonitorService : INotifyPropertyChanged
{
    #region Singleton Instance
    private static readonly Lazy<SystemMonitorService> _instance =
        new Lazy<SystemMonitorService>(() => new SystemMonitorService());

    public static SystemMonitorService Instance => _instance.Value;
    #endregion

    #region Native Methods
    [DllImport("kernel32.dll", SetLastError = true)]
    [return: MarshalAs(UnmanagedType.Bool)]
    private static extern bool GetSystemTimes(
        out long lpIdleTime,
        out long lpKernelTime,
        out long lpUserTime);

    [DllImport("psapi.dll")]
    private static extern bool GetProcessMemoryInfo(
        IntPtr Process,
        out PROCESS_MEMORY_COUNTERS ppsmemCounters,
        uint cb);

    [StructLayout(LayoutKind.Sequential, Size = 72)]
    private struct PROCESS_MEMORY_COUNTERS
    {
        public uint cb;
        public uint PageFaultCount;
        public UIntPtr PeakWorkingSetSize;
        public UIntPtr WorkingSetSize;
        public UIntPtr QuotaPeakPagedPoolUsage;
        public UIntPtr QuotaPagedPoolUsage;
        public UIntPtr QuotaPeakNonPagedPoolUsage;
        public UIntPtr QuotaNonPagedPoolUsage;
        public UIntPtr PagefileUsage;
        public UIntPtr PeakPagefileUsage;
    }
    #endregion

    #region Fields
    private readonly PerformanceCounter _cpuCounter;
    private readonly PerformanceCounter _memoryCounter;
    private readonly PerformanceCounter _diskReadCounter;
    private readonly PerformanceCounter _diskWriteCounter;
    private readonly List<PerformanceCounter> _networkCounters = new List<PerformanceCounter>();

    private readonly SystemResourceInfo _resourceInfo = new SystemResourceInfo();
    private readonly List<PerformanceCounter> _processCpuCounters = new List<PerformanceCounter>();
    private readonly Dictionary<int, ProcessInfo> _processCache = new Dictionary<int, ProcessInfo>();

    private CancellationTokenSource _monitoringCts;
    private Task _monitoringTask;
    private bool _isMonitoring;

    // CPU计算相关
    private long _prevIdleTime;
    private long _prevKernelTime;
    private long _prevUserTime;

    // 网络计算相关
    private Dictionary<string, (long Received, long Sent)> _prevNetworkValues =
        new Dictionary<string, (long, long)>();
    #endregion

    #region Properties
    public SystemResourceInfo ResourceInfo => _resourceInfo;

    public bool IsMonitoring
    {
        get => _isMonitoring;
        private set
        {
            if (_isMonitoring != value)
            {
                _isMonitoring = value;
                OnPropertyChanged(nameof(IsMonitoring));
            }
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    #endregion

    #region Constructor
    private SystemMonitorService()
    {
        try
        {
            // 初始化性能计数器
            _cpuCounter = new PerformanceCounter("Processor", "% Processor Time", "_Total");
            _memoryCounter = new PerformanceCounter("Memory", "Available MBytes");

            // 初始化磁盘计数器
            _diskReadCounter = new PerformanceCounter("PhysicalDisk", "Disk Read Bytes/sec", "_Total");
            _diskWriteCounter = new PerformanceCounter("PhysicalDisk", "Disk Write Bytes/sec", "_Total");

            // 初始化网络计数器
            InitializeNetworkCounters();

            // 初始化进程计数器
            InitializeProcessCounters();

            // 获取总内存
            GetTotalMemory();

            // 获取磁盘信息
            GetDiskInfo();
        }
        catch (Exception ex)
        {
            Debug.WriteLine($"性能计数器初始化失败: {ex.Message}");
        }
    }
    #endregion

    #region Public Methods
    public void StartMonitoring(int intervalMs = 1000)
    {
        if (IsMonitoring) return;

        _monitoringCts = new CancellationTokenSource();
        _monitoringTask = Task.Run(() => MonitorLoop(intervalMs, _monitoringCts.Token));
        IsMonitoring = true;
    }

    public void StopMonitoring()
    {
        if (!IsMonitoring) return;

        _monitoringCts?.Cancel();
        _monitoringTask?.Wait();
        IsMonitoring = false;
    }

    public SystemResourceInfo GetCurrentStatus()
    {
        UpdateSystemResources();
        return _resourceInfo;
    }

    public List<ProcessInfo> GetTopProcessesByCpu(int count = 5)
    {
        UpdateProcessInfo();
        return _resourceInfo.TopProcesses
            .OrderByDescending(p => p.CpuPercent)
            .Take(count)
            .ToList();
    }

    public List<ProcessInfo> GetTopProcessesByMemory(int count = 5)
    {
        UpdateProcessInfo();
        return _resourceInfo.TopProcesses
            .OrderByDescending(p => p.MemoryMB)
            .Take(count)
            .ToList();
    }
    #endregion

    #region Private Methods
    private void InitializeNetworkCounters()
    {
        try
        {
            var category = new PerformanceCounterCategory("Network Interface");
            var instances = category.GetInstanceNames();

            foreach (var instance in instances)
            {
                // 排除虚拟适配器和回环接口
                if (instance.Contains("Loopback") ||
                    instance.Contains("isatap") ||
                    instance.Contains("Teredo"))
                    continue;

                var receivedCounter = new PerformanceCounter("Network Interface",
                    "Bytes Received/sec", instance);
                var sentCounter = new PerformanceCounter("Network Interface",
                    "Bytes Sent/sec", instance);

                _networkCounters.Add(receivedCounter);
                _networkCounters.Add(sentCounter);
            }
        }
        catch (Exception ex)
        {
            Debug.WriteLine($"网络计数器初始化失败: {ex.Message}");
        }
    }

    private void InitializeProcessCounters()
    {
        try
        {
            var processes = Process.GetProcesses();
            foreach (var process in processes)
            {
                try
                {
                    var counter = new PerformanceCounter("Process", "% Processor Time",
                        process.ProcessName, true);
                    _processCpuCounters.Add(counter);
                }
                catch
                {
                    // 忽略无权限访问的进程
                }
            }
        }
        catch (Exception ex)
        {
            Debug.WriteLine($"进程计数器初始化失败: {ex.Message}");
        }
    }

    private void GetTotalMemory()
    {
        try
        {
            using (var searcher = new ManagementObjectSearcher("SELECT TotalVisibleMemorySize FROM Win32_OperatingSystem"))
            {
                foreach (var obj in searcher.Get())
                {
                    if (ulong.TryParse(obj["TotalVisibleMemorySize"]?.ToString(), out ulong totalMemoryKB))
                    {
                        _resourceInfo.TotalMemory = totalMemoryKB / 1024; // 转换为MB
                    }
                }
            }
        }
        catch (Exception ex)
        {
            Debug.WriteLine($"获取总内存失败: {ex.Message}");
        }
    }

    private void GetDiskInfo()
    {
        try
        {
            var diskInfos = new List<DiskInfo>();

            using (var searcher = new ManagementObjectSearcher("SELECT * FROM Win32_LogicalDisk WHERE DriveType = 3"))
            {
                foreach (var disk in searcher.Get())
                {
                    var diskInfo = new DiskInfo
                    {
                        DriveLetter = disk["DeviceID"]?.ToString() ?? "Unknown",
                        DriveName = disk["VolumeName"]?.ToString() ?? "Local Disk"
                    };

                    if (ulong.TryParse(disk["Size"]?.ToString(), out ulong totalSize))
                    {
                        diskInfo.TotalSizeGB = totalSize / (1024 * 1024 * 1024);
                    }

                    if (ulong.TryParse(disk["FreeSpace"]?.ToString(), out ulong freeSpace))
                    {
                        diskInfo.FreeSpaceGB = freeSpace / (1024 * 1024 * 1024);
                    }

                    if (diskInfo.TotalSizeGB > 0)
                    {
                        diskInfo.UsagePercent = 100f -
                            ((float)diskInfo.FreeSpaceGB / diskInfo.TotalSizeGB * 100);
                    }

                    diskInfos.Add(diskInfo);
                }
            }

            _resourceInfo.DiskInfos = diskInfos;
        }
        catch (Exception ex)
        {
            Debug.WriteLine($"获取磁盘信息失败: {ex.Message}");
        }
    }

    private async Task MonitorLoop(int intervalMs, CancellationToken cancellationToken)
    {
        while (!cancellationToken.IsCancellationRequested)
        {
            try
            {
                UpdateSystemResources();
                await Task.Delay(intervalMs, cancellationToken);
            }
            catch (TaskCanceledException)
            {
                break;
            }
            catch (Exception ex)
            {
                Debug.WriteLine($"监控循环错误: {ex.Message}");
            }
        }
    }

    private void UpdateSystemResources()
    {
        try
        {
            UpdateCpuUsage();
            UpdateMemoryUsage();
            UpdateDiskUsage();
            UpdateNetworkUsage();
            UpdateProcessInfo();
            UpdateSystemUptime();
        }
        catch (Exception ex)
        {
            Debug.WriteLine($"更新系统资源失败: {ex.Message}");
        }
    }

    private void UpdateCpuUsage()
    {
        try
        {
            // 方法1: 使用PerformanceCounter
            if (_cpuCounter != null)
            {
                _resourceInfo.CpuUsage = _cpuCounter.NextValue();
            }

            // 方法2: 使用GetSystemTimes(更精确)
            if (GetSystemTimes(out long idleTime, out long kernelTime, out long userTime))
            {
                long totalTime = kernelTime + userTime;
                long idleTimeDiff = idleTime - _prevIdleTime;
                long totalTimeDiff = totalTime - (_prevKernelTime + _prevUserTime);

                if (_prevIdleTime != 0 && _prevKernelTime != 0 && _prevUserTime != 0)
                {
                    if (totalTimeDiff > 0)
                    {
                        float cpuUsage = 100.0f * (1.0f - (float)idleTimeDiff / totalTimeDiff);
                        _resourceInfo.CpuUsage = Math.Min(Math.Max(cpuUsage, 0), 100);
                    }
                }

                _prevIdleTime = idleTime;
                _prevKernelTime = kernelTime;
                _prevUserTime = userTime;
            }
        }
        catch (Exception ex)
        {
            Debug.WriteLine($"更新CPU使用率失败: {ex.Message}");
        }
    }

    private void UpdateMemoryUsage()
    {
        try
        {
            if (_memoryCounter != null)
            {
                float availableMB = _memoryCounter.NextValue();
                if (_resourceInfo.TotalMemory > 0)
                {
                    _resourceInfo.UsedMemory = _resourceInfo.TotalMemory - (ulong)availableMB;
                    _resourceInfo.MemoryUsage = (float)_resourceInfo.UsedMemory / _resourceInfo.TotalMemory * 100;
                }
            }

            // 备用方法: 使用WMI
            if (_resourceInfo.TotalMemory == 0)
            {
                using (var searcher = new ManagementObjectSearcher(
                    "SELECT TotalVisibleMemorySize, FreePhysicalMemory FROM Win32_OperatingSystem"))
                {
                    foreach (var obj in searcher.Get())
                    {
                        if (ulong.TryParse(obj["TotalVisibleMemorySize"]?.ToString(), out ulong totalMemoryKB) &&
                            ulong.TryParse(obj["FreePhysicalMemory"]?.ToString(), out ulong freeMemoryKB))
                        {
                            _resourceInfo.TotalMemory = totalMemoryKB / 1024; // KB to MB
                            _resourceInfo.UsedMemory = (totalMemoryKB - freeMemoryKB) / 1024;
                            _resourceInfo.MemoryUsage = (float)_resourceInfo.UsedMemory /
                                                       _resourceInfo.TotalMemory * 100;
                        }
                    }
                }
            }
        }
        catch (Exception ex)
        {
            Debug.WriteLine($"更新内存使用率失败: {ex.Message}");
        }
    }

    private void UpdateDiskUsage()
    {
        try
        {
            if (_diskReadCounter != null && _diskWriteCounter != null)
            {
                float readSpeed = _diskReadCounter.NextValue();
                float writeSpeed = _diskWriteCounter.NextValue();

                // 转换为MB/s
                readSpeed /= 1024 * 1024;
                writeSpeed /= 1024 * 1024;

                // 更新磁盘信息
                foreach (var disk in _resourceInfo.DiskInfos)
                {
                    disk.ReadSpeed = readSpeed / _resourceInfo.DiskInfos.Count;
                    disk.WriteSpeed = writeSpeed / _resourceInfo.DiskInfos.Count;
                }
            }
        }
        catch (Exception ex)
        {
            Debug.WriteLine($"更新磁盘使用率失败: {ex.Message}");
        }
    }

    private void UpdateNetworkUsage()
    {
        try
        {
            float totalDownloadSpeed = 0;
            float totalUploadSpeed = 0;

            for (int i = 0; i < _networkCounters.Count; i += 2)
            {
                if (i + 1 < _networkCounters.Count)
                {
                    float downloadSpeed = _networkCounters[i].NextValue();
                    float uploadSpeed = _networkCounters[i + 1].NextValue();

                    // 转换为KB/s
                    downloadSpeed /= 1024;
                    uploadSpeed /= 1024;

                    totalDownloadSpeed += downloadSpeed;
                    totalUploadSpeed += uploadSpeed;
                }
            }

            _resourceInfo.NetworkDownloadSpeed = totalDownloadSpeed;
            _resourceInfo.NetworkUploadSpeed = totalUploadSpeed;
        }
        catch (Exception ex)
        {
            Debug.WriteLine($"更新网络使用率失败: {ex.Message}");
        }
    }

    private void UpdateProcessInfo()
    {
        try
        {
            var processList = new List<ProcessInfo>();
            var processes = Process.GetProcesses();

            foreach (var process in processes.Take(20)) // 限制数量以提高性能
            {
                try
                {
                    var processInfo = new ProcessInfo
                    {
                        ProcessId = process.Id,
                        ProcessName = process.ProcessName
                    };

                    // 获取CPU使用率
                    if (_processCpuCounters.Any(p => p.InstanceName == process.ProcessName))
                    {
                        var counter = _processCpuCounters.FirstOrDefault(p =>
                            p.InstanceName == process.ProcessName);
                        if (counter != null)
                        {
                            processInfo.CpuPercent = counter.NextValue() /
                                                     Environment.ProcessorCount;
                        }
                    }

                    // 获取内存使用
                    process.Refresh();
                    processInfo.MemoryMB = process.WorkingSet64 / (1024f * 1024f);

                    processList.Add(processInfo);
                }
                catch
                {
                    // 忽略无权限访问的进程
                }
            }

            _resourceInfo.TopProcesses = processList
                .OrderByDescending(p => p.CpuPercent)
                .Take(10)
                .ToList();
        }
        catch (Exception ex)
        {
            Debug.WriteLine($"更新进程信息失败: {ex.Message}");
        }
    }

    private void UpdateSystemUptime()
    {
        try
        {
            using (var uptime = new PerformanceCounter("System", "System Up Time"))
            {
                uptime.NextValue(); // 第一次调用初始化
                float seconds = uptime.NextValue();
                _resourceInfo.SystemUptime = DateTime.Now.AddSeconds(-seconds);
            }
        }
        catch
        {
            // 备用方法
            _resourceInfo.SystemUptime = DateTime.Now - TimeSpan.FromTicks(
                Environment.TickCount * TimeSpan.TicksPerMillisecond);
        }
    }

    private void OnPropertyChanged(string propertyName)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
    #endregion

    #region IDisposable
    public void Dispose()
    {
        StopMonitoring();

        _cpuCounter?.Dispose();
        _memoryCounter?.Dispose();
        _diskReadCounter?.Dispose();
        _diskWriteCounter?.Dispose();

        foreach (var counter in _networkCounters)
            counter?.Dispose();

        foreach (var counter in _processCpuCounters)
            counter?.Dispose();
    }
    #endregion
}

3.3 ViewModel层

using System;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
using System.Timers;
using SystemResouceWpfApp.Models;
using SystemResouceWpfApp.Services;
using Timer = System.Timers.Timer;


namespace SystemResouceWpfApp.ViewModel;

// ViewModels/MainViewModel.cs


    public class MainViewModel : INotifyPropertyChanged
    {
        #region Fields
        private readonly SystemMonitorService _monitorService;
        private readonly Timer _updateTimer;
        private readonly ObservableCollection<ChartDataPoint> _cpuHistory = new ObservableCollection<ChartDataPoint>();
        private readonly ObservableCollection<ChartDataPoint> _memoryHistory = new ObservableCollection<ChartDataPoint>();
        private readonly ObservableCollection<ChartDataPoint> _networkHistory = new ObservableCollection<ChartDataPoint>();
        private const int MAX_HISTORY_POINTS = 60;
        #endregion

        #region Properties
        public SystemResourceInfo ResourceInfo => _monitorService.ResourceInfo;

        public ObservableCollection<ChartDataPoint> CpuHistory => _cpuHistory;
        public ObservableCollection<ChartDataPoint> MemoryHistory => _memoryHistory;
        public ObservableCollection<ChartDataPoint> NetworkHistory => _networkHistory;

        private bool _isMonitoring;
        public bool IsMonitoring
        {
            get => _isMonitoring;
            set
            {
                if (_isMonitoring != value)
                {
                    _isMonitoring = value;
                    OnPropertyChanged();
                }
            }
        }

        private DateTime _startTime = DateTime.Now;
        public DateTime StartTime
        {
            get => _startTime;
            set
            {
                if (_startTime != value)
                {
                    _startTime = value;
                    OnPropertyChanged();
                }
            }
        }

        public string UptimeString => GetUptimeString();
        #endregion

        #region Commands
        public RelayCommand StartCommand { get; }
        public RelayCommand StopCommand { get; }
        public RelayCommand RefreshCommand { get; }
        public RelayCommand ExportCommand { get; }
        #endregion

        #region Constructor
        public MainViewModel()
        {
            _monitorService = SystemMonitorService.Instance;
            _monitorService.PropertyChanged += OnMonitorServicePropertyChanged;

            _updateTimer = new System.Timers.Timer(1000); // 1秒更新一次
            _updateTimer.Elapsed += OnUpdateTimerElapsed;

            // 初始化历史数据
            InitializeHistoryData();

            // 初始化命令
            StartCommand = new RelayCommand(StartMonitoring, () => !IsMonitoring);
            StopCommand = new RelayCommand(StopMonitoring, () => IsMonitoring);
            RefreshCommand = new RelayCommand(RefreshData);
            ExportCommand = new RelayCommand(ExportData);

            // 开始监控
            StartMonitoring();
        }
        #endregion

        #region Private Methods
        private void InitializeHistoryData()
        {
            for (int i = 0; i < MAX_HISTORY_POINTS; i++)
            {
                var time = DateTime.Now.AddSeconds(-(MAX_HISTORY_POINTS - i));
                _cpuHistory.Add(new ChartDataPoint { Time = time, Value = 0 });
                _memoryHistory.Add(new ChartDataPoint { Time = time, Value = 0 });
                _networkHistory.Add(new ChartDataPoint { Time = time, Value = 0 });
            }
        }

        private void UpdateHistoryData()
        {
            var now = DateTime.Now;

            // 更新CPU历史
            _cpuHistory.Add(new ChartDataPoint
            {
                Time = now,
                Value = ResourceInfo.CpuUsage
            });
            if (_cpuHistory.Count > MAX_HISTORY_POINTS)
                _cpuHistory.RemoveAt(0);

            // 更新内存历史
            _memoryHistory.Add(new ChartDataPoint
            {
                Time = now,
                Value = ResourceInfo.MemoryUsage
            });
            if (_memoryHistory.Count > MAX_HISTORY_POINTS)
                _memoryHistory.RemoveAt(0);

            // 更新网络历史(下载速度)
            _networkHistory.Add(new ChartDataPoint
            {
                Time = now,
                Value = ResourceInfo.NetworkDownloadSpeed
            });
            if (_networkHistory.Count > MAX_HISTORY_POINTS)
                _networkHistory.RemoveAt(0);
        }

        private string GetUptimeString()
        {
            var uptime = DateTime.Now - ResourceInfo.SystemUptime;
            return $"{uptime.Days}d {uptime.Hours}h {uptime.Minutes}m {uptime.Seconds}s";
        }

        private void OnMonitorServicePropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            if (e.PropertyName == nameof(SystemMonitorService.IsMonitoring))
            {
                IsMonitoring = _monitorService.IsMonitoring;
            }
        }

        private void OnUpdateTimerElapsed(object sender, ElapsedEventArgs e)
        {
            UpdateHistoryData();
            OnPropertyChanged(nameof(UptimeString));
        }
        #endregion

        #region Command Methods
        private void StartMonitoring()
        {
            _monitorService.StartMonitoring();
            _updateTimer.Start();
            StartTime = DateTime.Now;
        }

        private void StopMonitoring()
        {
            _updateTimer.Stop();
            _monitorService.StopMonitoring();
        }

        private void RefreshData()
        {
            _monitorService.GetCurrentStatus();
        }

        private void ExportData()
        {
            // 导出数据逻辑
            // 这里可以实现导出为CSV、JSON等格式
        }
        #endregion

        #region INotifyPropertyChanged
        public event PropertyChangedEventHandler PropertyChanged;

        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
        #endregion
    }

    public class ChartDataPoint
    {
        public DateTime Time { get; set; }
        public double Value { get; set; }
    }

    public class RelayCommand : System.Windows.Input.ICommand
    {
        private readonly Action _execute;
        private readonly Func<bool> _canExecute;

        public event EventHandler CanExecuteChanged
        {
            add { System.Windows.Input.CommandManager.RequerySuggested += value; }
            remove { System.Windows.Input.CommandManager.RequerySuggested -= value; }
        }

        public RelayCommand(Action execute, Func<bool> canExecute = null)
        {
            _execute = execute ?? throw new ArgumentNullException(nameof(execute));
            _canExecute = canExecute;
        }

        public bool CanExecute(object parameter) => _canExecute?.Invoke() ?? true;

        public void Execute(object parameter) => _execute();
    }

3.4 WPF界面实现

<Window
    x:Class="SystemResouceWpfApp.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:local="clr-namespace:SystemResouceWpfApp"
    xmlns:lvc="clr-namespace:LiveCharts.Wpf;assembly=LiveCharts.Wpf"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    Title="系统资源监控仪表盘"
    Width="1600"
    Height="900"
    Background="#0F0F23"
    WindowStartupLocation="CenterScreen"
    mc:Ignorable="d">
    <Window.Resources>
        <!--  颜色资源  -->
        <Color x:Key="PrimaryColor">#2196F3</Color>
        <Color x:Key="SuccessColor">#4CAF50</Color>
        <Color x:Key="WarningColor">#FF9800</Color>
        <Color x:Key="DangerColor">#F44336</Color>
        <Color x:Key="InfoColor">#00BCD4</Color>
        <Color x:Key="DarkColor">#121212</Color>
        <Color x:Key="LightColor">#F5F5F5</Color>

        <!--  渐变画刷  -->
        <LinearGradientBrush x:Key="PrimaryGradient" StartPoint="0,0" EndPoint="1,1">
            <GradientStop Offset="0" Color="#2196F3" />
            <GradientStop Offset="1" Color="#1976D2" />
        </LinearGradientBrush>

        <LinearGradientBrush x:Key="SuccessGradient" StartPoint="0,0" EndPoint="1,1">
            <GradientStop Offset="0" Color="#4CAF50" />
            <GradientStop Offset="1" Color="#388E3C" />
        </LinearGradientBrush>

        <LinearGradientBrush x:Key="WarningGradient" StartPoint="0,0" EndPoint="1,1">
            <GradientStop Offset="0" Color="#FF9800" />
            <GradientStop Offset="1" Color="#F57C00" />
        </LinearGradientBrush>

        <!--  样式  -->
        <Style x:Key="MetricCardStyle" TargetType="Border">
            <Setter Property="Background" Value="#1E1E2E" />
            <Setter Property="CornerRadius" Value="12" />
            <Setter Property="BorderThickness" Value="1" />
            <Setter Property="BorderBrush" Value="#2D2D3D" />
            <Setter Property="Padding" Value="20" />
            <Setter Property="Effect">
                <Setter.Value>
                    <DropShadowEffect
                        BlurRadius="20"
                        Opacity="0.3"
                        ShadowDepth="0" />
                </Setter.Value>
            </Setter>
        </Style>

        <Style x:Key="MetricTitleStyle" TargetType="TextBlock">
            <Setter Property="Foreground" Value="#AAAAAA" />
            <Setter Property="FontSize" Value="14" />
            <Setter Property="FontWeight" Value="SemiBold" />
            <Setter Property="Margin" Value="0,0,0,8" />
        </Style>

        <Style x:Key="MetricValueStyle" TargetType="TextBlock">
            <Setter Property="Foreground" Value="White" />
            <Setter Property="FontSize" Value="32" />
            <Setter Property="FontWeight" Value="Bold" />
        </Style>

        <Style x:Key="MetricUnitStyle" TargetType="TextBlock">
            <Setter Property="Foreground" Value="#888888" />
            <Setter Property="FontSize" Value="16" />
            <Setter Property="Margin" Value="4,0,0,0" />
        </Style>

        <Style x:Key="ButtonStyle" TargetType="Button">
            <Setter Property="Background" Value="#2D2D3D" />
            <Setter Property="Foreground" Value="White" />
            <Setter Property="BorderThickness" Value="0" />
            <Setter Property="Padding" Value="12,8" />
            <Setter Property="Margin" Value="4" />
            <Setter Property="Cursor" Value="Hand" />
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="Button">
                        <Border
                            Background="{TemplateBinding Background}"
                            BorderBrush="#3D3D4D"
                            BorderThickness="1"
                            CornerRadius="6">
                            <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" />
                        </Border>
                        <ControlTemplate.Triggers>
                            <Trigger Property="IsMouseOver" Value="True">
                                <Setter Property="Background" Value="#3D3D4D" />
                            </Trigger>
                            <Trigger Property="IsPressed" Value="True">
                                <Setter Property="Background" Value="#4D4D5D" />
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </Window.Resources>

    <Grid>
        <!--  背景  -->
        <Rectangle>
            <Rectangle.Fill>
                <LinearGradientBrush StartPoint="0,0" EndPoint="1,1">
                    <GradientStop Offset="0" Color="#0F0F23" />
                    <GradientStop Offset="1" Color="#1A1A2E" />
                </LinearGradientBrush>
            </Rectangle.Fill>
        </Rectangle>

        <!--  主布局  -->
        <Grid Margin="20">
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto" />
                <RowDefinition Height="*" />
                <RowDefinition Height="Auto" />
            </Grid.RowDefinitions>

            <!--  标题栏  -->
            <Border
                Grid.Row="0"
                Padding="0,0,0,20"
                Background="Transparent">
                <StackPanel HorizontalAlignment="Stretch" Orientation="Horizontal">
                    <StackPanel>
                        <TextBlock
                            FontSize="28"
                            FontWeight="Bold"
                            Foreground="White"
                            Text="🚀 系统资源监控仪表盘" />
                        <TextBlock
                            Margin="0,4,0,0"
                            FontSize="14"
                            Foreground="#888888"
                            Text="实时监控系统性能指标" />
                    </StackPanel>

                    <StackPanel
                        Margin="20,0,0,0"
                        HorizontalAlignment="Right"
                        VerticalAlignment="Center"
                        Orientation="Horizontal">
                        <Button
                            Command="{Binding StartCommand}"
                            Content="▶ 开始监控"
                            Style="{StaticResource ButtonStyle}" />
                        <Button
                            Command="{Binding StopCommand}"
                            Content="⏸ 暂停监控"
                            Style="{StaticResource ButtonStyle}" />
                        <Button
                            Command="{Binding RefreshCommand}"
                            Content="🔄 刷新"
                            Style="{StaticResource ButtonStyle}" />
                        <Button
                            Command="{Binding ExportCommand}"
                            Content="📤 导出数据"
                            Style="{StaticResource ButtonStyle}" />
                    </StackPanel>
                </StackPanel>
            </Border>

            <!--  监控数据区域  -->
            <ScrollViewer
                Grid.Row="1"
                HorizontalScrollBarVisibility="Disabled"
                VerticalScrollBarVisibility="Auto">
                <Grid>
                    <Grid.RowDefinitions>
                        <RowDefinition Height="Auto" />
                        <RowDefinition Height="Auto" />
                        <RowDefinition Height="Auto" />
                    </Grid.RowDefinitions>

                    <!--  第一行:核心指标  -->
                    <StackPanel Grid.Row="0" Orientation="Horizontal">
                        <!--  CPU监控卡片  -->
                        <Border
                            Width="300"
                            Margin="0,0,20,20"
                            Style="{StaticResource MetricCardStyle}">
                            <StackPanel>
                                <TextBlock Style="{StaticResource MetricTitleStyle}" Text="CPU使用率" />

                                <StackPanel VerticalAlignment="Center" Orientation="Horizontal">
                                    <TextBlock Style="{StaticResource MetricValueStyle}" Text="{Binding ResourceInfo.CpuUsage, StringFormat={}{0:F1}}" />
                                    <TextBlock
                                        Margin="0,0,0,8"
                                        VerticalAlignment="Bottom"
                                        Style="{StaticResource MetricUnitStyle}"
                                        Text="%" />
                                </StackPanel>

                                <!--  CPU进度条  -->
                                <Border
                                    Height="12"
                                    Margin="0,12,0,0"
                                    Background="#2D2D3D"
                                    CornerRadius="6">
                                    <Border Width="{Binding ResourceInfo.CpuUsage}" HorizontalAlignment="Left">
                                        <Border.Background>
                                            <LinearGradientBrush StartPoint="0,0" EndPoint="1,0">
                                                <GradientStop Offset="0" Color="#4CAF50" />
                                                <GradientStop Offset="0.7" Color="#FF9800" />
                                                <GradientStop Offset="1" Color="#F44336" />
                                            </LinearGradientBrush>
                                        </Border.Background>
                                    </Border>
                                </Border>

                                <TextBlock
                                    Margin="0,8,0,0"
                                    Foreground="#888888"
                                    Text="{Binding ResourceInfo.CpuUsage, StringFormat={}核心数: {0:F0}}" />
                            </StackPanel>
                        </Border>

                        <!--  内存监控卡片  -->
                        <Border
                            Width="300"
                            Margin="0,0,20,20"
                            Style="{StaticResource MetricCardStyle}">
                            <StackPanel>
                                <TextBlock Style="{StaticResource MetricTitleStyle}" Text="内存使用" />

                                <StackPanel VerticalAlignment="Center" Orientation="Horizontal">
                                    <TextBlock Style="{StaticResource MetricValueStyle}" Text="{Binding ResourceInfo.MemoryUsage, StringFormat={}{0:F1}}" />
                                    <TextBlock
                                        Margin="0,0,0,8"
                                        VerticalAlignment="Bottom"
                                        Style="{StaticResource MetricUnitStyle}"
                                        Text="%" />
                                </StackPanel>

                                <!--  内存进度条  -->
                                <Border
                                    Height="12"
                                    Margin="0,12,0,0"
                                    Background="#2D2D3D"
                                    CornerRadius="6">
                                    <Border Width="{Binding ResourceInfo.MemoryUsage}" HorizontalAlignment="Left">
                                        <Border.Background>
                                            <LinearGradientBrush StartPoint="0,0" EndPoint="1,0">
                                                <GradientStop Offset="0" Color="#2196F3" />
                                                <GradientStop Offset="1" Color="#1976D2" />
                                            </LinearGradientBrush>
                                        </Border.Background>
                                    </Border>
                                </Border>

                                <TextBlock
                                    Margin="0,8,0,0"
                                    Foreground="#888888"
                                    Text="{Binding ResourceInfo.UsedMemory, StringFormat={}已用: {0} MB / {1} MB}" />
                            </StackPanel>
                        </Border>

                        <!--  网络监控卡片  -->
                        <Border
                            Width="300"
                            Margin="0,0,20,20"
                            Style="{StaticResource MetricCardStyle}">
                            <Grid>
                                <Grid.RowDefinitions>
                                    <RowDefinition Height="Auto" />
                                    <RowDefinition Height="*" />
                                </Grid.RowDefinitions>

                                <StackPanel Grid.Row="0">
                                    <TextBlock Style="{StaticResource MetricTitleStyle}" Text="网络活动" />

                                    <StackPanel Orientation="Horizontal">
                                        <StackPanel Margin="0,0,20,0">
                                            <TextBlock
                                                FontSize="12"
                                                Foreground="#888888"
                                                Text="上传" />
                                            <StackPanel VerticalAlignment="Center" Orientation="Horizontal">
                                                <TextBlock
                                                    FontSize="24"
                                                    Style="{StaticResource MetricValueStyle}"
                                                    Text="{Binding ResourceInfo.NetworkUploadSpeed, StringFormat={}{0:F1}}" />
                                                <TextBlock
                                                    FontSize="12"
                                                    Style="{StaticResource MetricUnitStyle}"
                                                    Text="KB/s" />
                                            </StackPanel>
                                        </StackPanel>

                                        <StackPanel>
                                            <TextBlock
                                                FontSize="12"
                                                Foreground="#888888"
                                                Text="下载" />
                                            <StackPanel VerticalAlignment="Center" Orientation="Horizontal">
                                                <TextBlock
                                                    FontSize="24"
                                                    Style="{StaticResource MetricValueStyle}"
                                                    Text="{Binding ResourceInfo.NetworkDownloadSpeed, StringFormat={}{0:F1}}" />
                                                <TextBlock
                                                    FontSize="12"
                                                    Style="{StaticResource MetricUnitStyle}"
                                                    Text="KB/s" />
                                            </StackPanel>
                                        </StackPanel>
                                    </StackPanel>
                                </StackPanel>

                                <!--  网络图标  -->
                                <Viewbox
                                    Grid.Row="1"
                                    Width="80"
                                    Height="80"
                                    HorizontalAlignment="Right"
                                    VerticalAlignment="Bottom">
                                    <Canvas Width="100" Height="100">
                                        <!--  网络波动图形  -->
                                        <Path
                                            Data="M 0,50 Q 25,30 50,50 T 100,50"
                                            Stroke="#2196F3"
                                            StrokeDashArray="5,2"
                                            StrokeThickness="2" />
                                        <Path
                                            Data="M 0,60 Q 25,40 50,60 T 100,60"
                                            Stroke="#4CAF50"
                                            StrokeThickness="2" />
                                    </Canvas>
                                </Viewbox>
                            </Grid>
                        </Border>

                        <!--  系统运行时间卡片  -->
                        <Border
                            Width="300"
                            Margin="0,0,0,20"
                            Style="{StaticResource MetricCardStyle}">
                            <StackPanel>
                                <TextBlock Style="{StaticResource MetricTitleStyle}" Text="系统运行时间" />

                                <TextBlock
                                    FontSize="24"
                                    Style="{StaticResource MetricValueStyle}"
                                    Text="{Binding UptimeString}" />

                                <TextBlock
                                    Margin="0,8,0,0"
                                    Foreground="#888888"
                                    Text="{Binding ResourceInfo.SystemUptime, StringFormat={}启动时间: {0:yyyy-MM-dd HH:mm:ss}}" />

                                <!--  运行时间图标  -->
                                <Viewbox
                                    Width="60"
                                    Height="60"
                                    Margin="0,12,0,0"
                                    HorizontalAlignment="Left">
                                    <Canvas Width="100" Height="100">
                                        <Ellipse
                                            Width="80"
                                            Height="80"
                                            Stroke="#FF9800"
                                            StrokeDashArray="314"
                                            StrokeDashOffset="100"
                                            StrokeThickness="8">
                                            <Ellipse.RenderTransform>
                                                <RotateTransform Angle="90" CenterX="40" CenterY="40" />
                                            </Ellipse.RenderTransform>
                                        </Ellipse>
                                        <TextBlock
                                            Margin="30,30,0,0"
                                            HorizontalAlignment="Center"
                                            VerticalAlignment="Center"
                                            FontSize="40"
                                            Text="⏱" />
                                    </Canvas>
                                </Viewbox>
                            </StackPanel>
                        </Border>
                    </StackPanel>

                    <!--  第二行:历史图表  -->
                    <Border
                        Grid.Row="1"
                        Margin="0,0,0,20"
                        Style="{StaticResource MetricCardStyle}">
                        <Grid>
                            <Grid.RowDefinitions>
                                <RowDefinition Height="Auto" />
                                <RowDefinition Height="*" />
                            </Grid.RowDefinitions>

                            <TextBlock Style="{StaticResource MetricTitleStyle}" Text="历史趋势" />

                            <!--  使用LiveCharts图表  -->
                            <lvc:CartesianChart
                                Grid.Row="1"
                                Margin="0,20,0,0"
                                LegendLocation="Right"
                                Series="{Binding ChartSeries}">
                                <lvc:CartesianChart.AxisX>
                                    <lvc:Axis Title="时间" LabelFormatter="{Binding DateTimeFormatter}" />
                                </lvc:CartesianChart.AxisX>
                                <lvc:CartesianChart.AxisY>
                                    <lvc:Axis
                                        Title="使用率 (%)"
                                        MaxValue="100"
                                        MinValue="0" />
                                </lvc:CartesianChart.AxisY>
                            </lvc:CartesianChart>
                        </Grid>
                    </Border>

                    <!--  第三行:磁盘和进程信息  -->
                    <Grid Grid.Row="2">
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="*" />
                            <ColumnDefinition Width="*" />
                        </Grid.ColumnDefinitions>

                        <!--  磁盘信息  -->
                        <Border
                            Grid.Column="0"
                            Margin="0,0,10,0"
                            Style="{StaticResource MetricCardStyle}">
                            <StackPanel>
                                <TextBlock Style="{StaticResource MetricTitleStyle}" Text="磁盘使用情况" />

                                <ItemsControl Margin="0,10,0,0" ItemsSource="{Binding ResourceInfo.DiskInfos}">
                                    <ItemsControl.ItemTemplate>
                                        <DataTemplate>
                                            <Border
                                                Margin="0,0,0,8"
                                                Padding="12"
                                                Background="#2D2D3D"
                                                CornerRadius="6">
                                                <Grid>
                                                    <Grid.RowDefinitions>
                                                        <RowDefinition Height="Auto" />
                                                        <RowDefinition Height="Auto" />
                                                        <RowDefinition Height="Auto" />
                                                    </Grid.RowDefinitions>

                                                    <!--  磁盘名称和容量  -->
                                                    <StackPanel
                                                        Grid.Row="0"
                                                        HorizontalAlignment="Center"
                                                        Orientation="Horizontal">
                                                        <TextBlock
                                                            FontWeight="Bold"
                                                            Foreground="White"
                                                            Text="{Binding DriveLetter}" />
                                                        <TextBlock
                                                            Margin="8,0,0,0"
                                                            Foreground="#888888"
                                                            Text="{Binding DriveName}" />
                                                        <TextBlock
                                                            HorizontalAlignment="Right"
                                                            Foreground="#888888"
                                                            Text="{Binding TotalSizeGB, StringFormat={}{0} GB}" />
                                                    </StackPanel>

                                                    <!--  磁盘使用率  -->
                                                    <Border
                                                        Grid.Row="1"
                                                        Height="8"
                                                        Margin="0,8,0,4"
                                                        Background="#3D3D4D"
                                                        CornerRadius="4">
                                                        <Border Width="{Binding UsagePercent}" HorizontalAlignment="Left">
                                                            <Border.Background>
                                                                <LinearGradientBrush StartPoint="0,0" EndPoint="1,0">
                                                                    <GradientStop Offset="0" Color="#4CAF50" />
                                                                    <GradientStop Offset="0.7" Color="#FF9800" />
                                                                    <GradientStop Offset="1" Color="#F44336" />
                                                                </LinearGradientBrush>
                                                            </Border.Background>
                                                        </Border>
                                                    </Border>

                                                    <!--  磁盘读写速度  -->
                                                    <StackPanel
                                                        Grid.Row="2"
                                                        HorizontalAlignment="Center"
                                                        Orientation="Horizontal">
                                                        <StackPanel Orientation="Horizontal">
                                                            <TextBlock
                                                                Margin="0,0,4,0"
                                                                Foreground="#2196F3"
                                                                Text="📥" />
                                                            <TextBlock
                                                                FontSize="12"
                                                                Foreground="#888888"
                                                                Text="{Binding ReadSpeed, StringFormat={}{0:F1} MB/s}" />
                                                        </StackPanel>
                                                        <StackPanel Orientation="Horizontal">
                                                            <TextBlock
                                                                Margin="0,0,4,0"
                                                                Foreground="#FF9800"
                                                                Text="📤" />
                                                            <TextBlock
                                                                FontSize="12"
                                                                Foreground="#888888"
                                                                Text="{Binding WriteSpeed, StringFormat={}{0:F1} MB/s}" />
                                                        </StackPanel>
                                                        <TextBlock
                                                            FontSize="12"
                                                            Foreground="#888888"
                                                            Text="{Binding UsagePercent, StringFormat={}{0:F1}% 已用}" />
                                                    </StackPanel>
                                                </Grid>
                                            </Border>
                                        </DataTemplate>
                                    </ItemsControl.ItemTemplate>
                                </ItemsControl>
                            </StackPanel>
                        </Border>

                        <!--  进程信息  -->
                        <Border
                            Grid.Column="1"
                            Margin="10,0,0,0"
                            Style="{StaticResource MetricCardStyle}">
                            <StackPanel>
                                <TextBlock Style="{StaticResource MetricTitleStyle}" Text="进程监控" />

                                <!--  进程列表  -->
                                <DataGrid
                                    Margin="0,10,0,0"
                                    AutoGenerateColumns="False"
                                    Background="Transparent"
                                    BorderThickness="0"
                                    HeadersVisibility="Column"
                                    ItemsSource="{Binding ResourceInfo.TopProcesses}"
                                    RowBackground="Transparent">
                                    <DataGrid.Columns>
                                        <DataGridTextColumn
                                            Width="*"
                                            Binding="{Binding ProcessName}"
                                            Foreground="White"
                                            Header="进程名" />
                                        <DataGridTextColumn
                                            Width="80"
                                            Binding="{Binding ProcessId}"
                                            Foreground="#888888"
                                            Header="PID" />
                                        <DataGridTemplateColumn Width="120" Header="CPU">
                                            <DataGridTemplateColumn.CellTemplate>
                                                <DataTemplate>
                                                    <Grid>
                                                        <Border
                                                            Height="6"
                                                            VerticalAlignment="Center"
                                                            Background="#2D2D3D"
                                                            CornerRadius="3">
                                                            <Border Width="{Binding CpuPercent}" HorizontalAlignment="Left">
                                                                <Border.Background>
                                                                    <LinearGradientBrush StartPoint="0,0" EndPoint="1,0">
                                                                        <GradientStop Offset="0" Color="#4CAF50" />
                                                                        <GradientStop Offset="0.7" Color="#FF9800" />
                                                                        <GradientStop Offset="1" Color="#F44336" />
                                                                    </LinearGradientBrush>
                                                                </Border.Background>
                                                            </Border>
                                                        </Border>
                                                        <TextBlock
                                                            HorizontalAlignment="Center"
                                                            VerticalAlignment="Center"
                                                            FontSize="10"
                                                            Foreground="White"
                                                            Text="{Binding CpuPercent, StringFormat={}{0:F1}%}" />
                                                    </Grid>
                                                </DataTemplate>
                                            </DataGridTemplateColumn.CellTemplate>
                                        </DataGridTemplateColumn>
                                        <DataGridTextColumn
                                            Width="100"
                                            Binding="{Binding MemoryMB, StringFormat={}{0:F1} MB}"
                                            Foreground="#888888"
                                            Header="内存" />
                                    </DataGrid.Columns>
                                </DataGrid>
                            </StackPanel>
                        </Border>
                    </Grid>
                </Grid>
            </ScrollViewer>

            <!--  状态栏  -->
            <Border
                Grid.Row="2"
                Height="40"
                Margin="0,20,0,0"
                Background="#1A1A2E"
                CornerRadius="6">
                <StackPanel
                    HorizontalAlignment="Center"
                    VerticalAlignment="Center"
                    Orientation="Horizontal">
                    <Ellipse
                        Width="8"
                        Height="8"
                        Margin="0,0,8,0"
                        Fill="#4CAF50">
                        <Ellipse.Style>
                            <Style TargetType="Ellipse">
                                <Style.Triggers>
                                    <DataTrigger Binding="{Binding IsMonitoring}" Value="True">
                                        <Setter Property="Fill" Value="#4CAF50" />
                                    </DataTrigger>
                                    <DataTrigger Binding="{Binding IsMonitoring}" Value="False">
                                        <Setter Property="Fill" Value="#F44336" />
                                    </DataTrigger>
                                </Style.Triggers>
                            </Style>
                        </Ellipse.Style>
                    </Ellipse>
                    <TextBlock Foreground="#888888" Text="{Binding IsMonitoring}" />
                    <TextBlock
                        Margin="20,0,0,0"
                        Foreground="#666666"
                        Text=" | 最后更新: " />
                    <TextBlock Foreground="#888888" Text="{Binding StartTime, StringFormat={}HH:mm:ss}" />
                </StackPanel>
            </Border>
        </Grid>
    </Grid>
</Window>
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using SystemResouceWpfApp.ViewModel;

namespace SystemResouceWpfApp
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            this.DataContext = new MainViewModel();
        }
    }
}

运行效果:

本文详细介绍了如何使用WPF创建一个功能完整的系统资源监控工具,包括:

  1. 核心功能:CPU、内存、磁盘、网络监控
  2. MVVM架构:清晰的代码分离和可测试性
  3. 美观UI:现代化设计,实时数据可视化
  4. 扩展性:易于添加新监控项和功能
  5. 部署方案:单文件发布,便于分发

这个监控工具具有以下特点:

通过这个项目,您不仅学习了WPF的高级应用,还掌握了系统编程、性能监控和现代UI设计的最佳实践。您可以根据需要进一步扩展功能,如添加GPU监控、温度监控、日志记录等功能。

以上就是利用WPF实现系统资源监控的完整代码的详细内容,更多关于WPF系统资源监控的资料请关注脚本之家其它相关文章!

您可能感兴趣的文章:
阅读全文