C#应用开发:基于C# WPF界面实现本机网络通讯状态(下载速度)的显示

目录

概述

具体实现

第一步:获取网络接口信息

代码解释:

[第二步:创建 WPF 界面](#第二步:创建 WPF 界面)

第三步:绑定数据

注意事项


概述

在 WPF 中实现一个界面来显示本机网络接口的状态,通常需要以下几个步骤:

  1. 获取网络接口信息 :使用 System.Net.NetworkInformation 命名空间获取网络接口的状态。

  2. 创建 WPF 界面:使用 XAML 设计用户界面,显示每个网络接口的信息。

  3. 绑定数据:将获取的网络接口信息绑定到 WPF 界面的控件中。

具体实现

下面是一个简单的示例,展示如何实现这一功能。

第一步:获取网络接口信息

使用 NetworkInterface 类获取当前机器的网络接口信息,我们将获取网络接口的名称、连接类型、IP 地址和当前的网络接收速率。为了获取接收速率,我们可以使用性能计数器 System.Diagnostics.PerformanceCounter

cs 复制代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.NetworkInformation;
using System.Net;
using System.Diagnostics;
using System.Threading.Tasks;
using System.Windows.Threading;

// 定义 NetworkInterfaceInfo 类用于封装网络接口的关键信息
public class NetworkInterfaceInfo
{
    // 网络接口的名称
    public string Name { get; set; }

    // 网络接口的描述信息
    public string Description { get; set; }

    // 网络连接类型(如以太网、无线等)
    public string ConnectionType { get; set; }

    // 网络接口的 IP 地址
    public string IPAddress { get; set; }

    // 网络接口的接收数据速率
    public string ReceiveRate { get; set; }
}

// 定义 NetworkInfoProvider 类用于提供网络接口的信息
public class NetworkInfoProvider
{
    // 存储网络接口与其对应的 PerformanceCounter 的映射
    private readonly Dictionary<string, PerformanceCounter> receiveCounters = new Dictionary<string, PerformanceCounter>();

    // 构造函数,初始化网络接口的性能计数器
    public NetworkInfoProvider()
    {
        // 遍历所有可用的网络接口
        foreach (var ni in NetworkInterface.GetAllNetworkInterfaces())
        {
            // 仅处理正在运行的网络接口
            if (ni.OperationalStatus == OperationalStatus.Up)
            {
                try
                {
                    // 创建一个 PerformanceCounter 用于获取接收速率
                    var counter = new PerformanceCounter("Network Interface", "Bytes Received/sec", ni.Description);
                    
                    // 初次读取来初始化计数器,避免首次读取时数据不准确
                    counter.NextValue();
                    
                    // 将计数器存储到字典中,以接口描述为键
                    receiveCounters[ni.Description] = counter;
                }
                catch (InvalidOperationException ex)
                {
                    // 处理初始化计数器时的异常
                    Console.WriteLine($"Error initializing counter for {ni.Description}: {ex.Message}");
                }
            }
        }
    }

    // 获取所有正在运行的网络接口的信息
    public List<NetworkInterfaceInfo> GetNetworkInterfaces()
    {
        var interfaces = new List<NetworkInterfaceInfo>();

        // 遍历所有可用的网络接口
        foreach (var ni in NetworkInterface.GetAllNetworkInterfaces())
        {
            // 仅处理正在运行的网络接口
            if (ni.OperationalStatus == OperationalStatus.Up)
            {
                // 获取该接口的 IP 属性
                var ipProps = ni.GetIPProperties();

                // 获取第一个 IPv4 地址
                var ipAddress = ipProps.UnicastAddresses
                                       .Where(ip => ip.Address.AddressFamily == 
                                   System.Net.Sockets.AddressFamily.InterNetwork)
                                       .Select(ip => ip.Address.ToString())
                                       .FirstOrDefault();

                // 获取接收速率并转换为 Kbps
                string receiveRate = GetReceiveRate(ni.Description) + " Kbps";

                // 创建一个 NetworkInterfaceInfo 实例并添加到列表中
                interfaces.Add(new NetworkInterfaceInfo
                {
                    Name = ni.Name,
                    Description = ni.Description,
                    ConnectionType = ni.NetworkInterfaceType.ToString(),
                    IPAddress = ipAddress ?? "N/A",
                    ReceiveRate = receiveRate
                });
            }
        }
        return interfaces;
    }

    // 获取指定网络接口的接收速率
    private string GetReceiveRate(string interfaceDescription)
    {
        // 检查字典中是否存在指定接口的计数器
        if (receiveCounters.TryGetValue(interfaceDescription, out var counter))
        {
            // 将字节每秒转换为千比特每秒 (Kbps)
            return (counter.NextValue() * 8 / 1024).ToString("F2");
        }
        // 如果没有计数器,返回 0.00
        return "0.00";
    }
}

代码解释:

  • NetworkInterfaceInfo 类:用来封装单个网络接口的信息,包括名称、描述、连接类型、IP 地址和接收速率。这样可以方便地将接口信息展示到UI。

  • NetworkInfoProvider 类:负责初始化和管理网络接口的性能计数器,并提供方法来获取当前活动的网络接口及其相关信息。

    • 构造函数 :遍历所有网络接口,仅对处于活动状态(OperationalStatus.Up)的接口进行处理。为每个接口创建一个 PerformanceCounter,用于监测接收速率。初次调用 NextValue() 是为了初始化计数器值。

    • GetNetworkInterfaces 方法:返回当前活动网络接口的信息列表。对于每个接口,获取其 IPv4 地址和接收速率。

    • GetReceiveRate 方法:返回指定接口的接收速率,转换为 Kbps。如果该接口没有计数器,返回 "0.00"。

第二步:创建 WPF 界面

设计一个简单的 WPF 界面,在 MainWindow.xaml 中使用 ListView 来显示信息。

XML 复制代码
<Window x:Class="NetworkStatusApp.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Network Status" Height="400" Width="600">
    <Grid>
        <ListView Name="NetworkInterfacesListView">
            <ListView.View>
                <GridView>
                    <GridViewColumn Header="Name" DisplayMemberBinding="{Binding Name}" Width="120" />
                    <GridViewColumn Header="Description" DisplayMemberBinding="{Binding Description}" Width="180" />
                    <GridViewColumn Header="Connection Type" DisplayMemberBinding="{Binding ConnectionType}" Width="100" />
                    <GridViewColumn Header="IP Address" DisplayMemberBinding="{Binding IPAddress}" Width="120" />
                    <GridViewColumn Header="Receive Rate (Kbps)" DisplayMemberBinding="{Binding ReceiveRate}" Width="120" />
                </GridView>
            </ListView.View>
        </ListView>
    </Grid>
</Window>

第三步:绑定数据

MainWindow.xaml.cs 中,从 NetworkInfoProvider 获取数据并绑定到 ListView

cs 复制代码
using System.Windows;
using System.Windows.Threading;
using System.Collections.ObjectModel;

// 定义 MainWindow 类,继承自 WPF 的 Window 类
public partial class MainWindow : Window
{
    // 定义一个 NetworkInfoProvider 实例,用于获取网络接口信息
    private NetworkInfoProvider provider;

    // 定义一个可观察的集合,用于存储和更新网络接口信息
    private ObservableCollection<NetworkInterfaceInfo> networkInterfaces;

    // MainWindow 构造函数
    public MainWindow()
    {
        // 初始化 XAML 界面组件
        InitializeComponent();

        // 初始化 ObservableCollection 实例,并将其绑定到 ListView 控件
        networkInterfaces = new ObservableCollection<NetworkInterfaceInfo>();
        NetworkInterfacesListView.ItemsSource = networkInterfaces;

        // 使用 BackgroundWorker 执行异步初始化,以避免阻塞 UI 线程
        BackgroundWorker worker = new BackgroundWorker();
        
        // 注册 DoWork 事件,用于后台线程执行
        worker.DoWork += (s, e) => InitializeNetworkProvider();
        
        // 注册 RunWorkerCompleted 事件,用于后台线程完成后执行
        worker.RunWorkerCompleted += (s, e) =>
        {
            // 初始化完成后,立即更新界面
            UpdateNetworkInterfacesImmediately();
            
            // 启动定时更新网络接口信息
            StartUpdating();
        };
        
        // 开始执行后台操作
        worker.RunWorkerAsync();
    }

    // 初始化 NetworkInfoProvider 实例
    private void InitializeNetworkProvider()
    {
        provider = new NetworkInfoProvider();
    }

    // 启动定时器,用于定期更新网络接口信息
    private void StartUpdating()
    {
        // 创建调度计时器
        DispatcherTimer timer = new DispatcherTimer();
        
        // 设置定时间隔为2秒
        timer.Interval = TimeSpan.FromSeconds(2);
        
        // 注册定时器的 Tick 事件,用于触发更新操作
        timer.Tick += UpdateNetworkInterfaces;
        
        // 启动定时器
        timer.Start();
    }

    // 立即更新网络接口信息,并更新到界面
    private void UpdateNetworkInterfacesImmediately()
    {
        // 清空当前的网络接口信息
        networkInterfaces.Clear();
        
        // 获取最新的网络接口信息并添加到集合中
        foreach (var ni in provider.GetNetworkInterfaces())
        {
            networkInterfaces.Add(ni);
        }
    }

    // 定期更新网络接口信息的方法
    private void UpdateNetworkInterfaces(object sender, EventArgs e)
    {
        // 清空当前的网络接口信息
        networkInterfaces.Clear();
        
        // 获取最新的网络接口信息并添加到集合中
        foreach (var ni in provider.GetNetworkInterfaces())
        {
            networkInterfaces.Add(ni);
        }
    }
}

注意事项

  • 权限:某些网络接口信息可能需要管理员权限才能访问。
  • 更新接口状态:如果需要动态更新网络接口状态,可以使用定时器或事件通知机制。

这个示例展示了一个基础实现,我们可以根据自己的实际需求进一步扩展和美化 UI。

相关推荐
智能与优化8 分钟前
C++打造局域网聊天室第十一课: 程序关闭及线程的结束
开发语言·c++
boligongzhu14 分钟前
Dalsa线阵CCD相机使用开发手册
c#
lsx20240621 分钟前
MongoDB 更新文档
开发语言
爱数学的程序猿44 分钟前
Python入门:1.Python介绍
开发语言·python
γ..1 小时前
基于MATLAB的图像增强
开发语言·深度学习·神经网络·学习·机器学习·matlab·音视频
小王爱吃月亮糖1 小时前
C++进阶-1-单继承、多继承、虚继承
开发语言·c++·笔记·学习·visual studio
m0_607548761 小时前
什么是单例模式
开发语言·javascript·单例模式
檀越剑指大厂2 小时前
【Python系列】Python中的`any`函数:检查“至少有一个”条件满足
开发语言·python
I_Am_Me_3 小时前
【JavaEE初阶】线程安全问题
开发语言·python