目录
[第二步:创建 WPF 界面](#第二步:创建 WPF 界面)
概述
在 WPF 中实现一个界面来显示本机网络接口的状态,通常需要以下几个步骤:
-
获取网络接口信息 :使用
System.Net.NetworkInformation
命名空间获取网络接口的状态。 -
创建 WPF 界面:使用 XAML 设计用户界面,显示每个网络接口的信息。
-
绑定数据:将获取的网络接口信息绑定到 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。