WPF C# DataGrid 示例:添加、删除行,日期选择,下拉框,事件处理
WPF C# DataGrid 示例:添加、删除行,日期选择,下拉框,事件处理
本示例演示如何在 WPF DataGrid 中添加行,删除行,使用 DatePicker 选择日期,ComboBox 下拉框,并添加事件处理,例如鼠标左键按下事件、文本元素改变事件等。
XAML 部分
<Window x:Class="WpfApp1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="450" Width="800">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<StackPanel Orientation="Horizontal" Margin="10">
<Button Content="添加行" Margin="0 0 10 0" Click="AddRow"/>
<Button Content="删除行" Click="DeleteRow"/>
</StackPanel>
<DataGrid Grid.Row="1" x:Name="dataGrid" AutoGenerateColumns="False" CanUserAddRows="False">
<DataGrid.Columns>
<DataGridTextColumn Header="序号" Binding="{Binding Path=Index}" Width="50" IsReadOnly="True"/>
<DataGridTemplateColumn Header="开始日期">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<DatePicker SelectedDate="{Binding Path=StartDate, Mode=TwoWay}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="结束日期">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<DatePicker SelectedDate="{Binding Path=EndDate, Mode=TwoWay}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="电源设备">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ComboBox ItemsSource="{Binding Path=PowerDevices}" SelectedItem="{Binding Path=SelectedPowerDevice, Mode=TwoWay}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="端口号">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ComboBox ItemsSource="{Binding Path=SerialPorts}" SelectedItem="{Binding Path=SelectedSerialPort, Mode=TwoWay}" Loaded="SerialPorts_Loaded"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="功率瓦数">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ComboBox ItemsSource="{Binding Path=PowerLevels}" SelectedItem="{Binding Path=SelectedPowerLevel, Mode=TwoWay}" Loaded="PowerLevels_Loaded" SelectionChanged="PowerLevel_SelectionChanged"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="泵温度">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBox Text="{Binding Path=PumpTemperature, Mode=TwoWay}" TextChanged="PumpTemperature_TextChanged"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="功率值">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBox Text="{Binding Path=PowerValue, Mode=TwoWay}" TextChanged="PowerValue_TextChanged"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="开关">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Button Content="{Binding Path=PowerDeviceStatus}" Click="PowerDeviceStatus_Click"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="状态">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Image Source="{Binding Path=PowerDeviceStatusImage}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
</Grid>
</Window>
C# 部分
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO.Ports;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media.Imaging;
namespace WpfApp1
{
public partial class MainWindow : Window
{
private List<DataItem> dataItems = new List<DataItem>();
public MainWindow()
{
InitializeComponent();
dataGrid.ItemsSource = dataItems;
}
private void AddRow(object sender, RoutedEventArgs e)
{
int index = dataItems.Count + 1;
dataItems.Add(new DataItem(index));
dataGrid.Items.Refresh();
}
private void DeleteRow(object sender, RoutedEventArgs e)
{
if (dataGrid.SelectedItem != null)
{
dataItems.Remove((DataItem)dataGrid.SelectedItem);
dataGrid.Items.Refresh();
}
}
private void SerialPorts_Loaded(object sender, RoutedEventArgs e)
{
ComboBox comboBox = (ComboBox)sender;
string[] ports = SerialPort.GetPortNames();
comboBox.ItemsSource = ports;
if (ports.Length > 0)
{
comboBox.SelectedIndex = 0;
}
}
private void PowerLevels_Loaded(object sender, RoutedEventArgs e)
{
ComboBox comboBox = (ComboBox)sender;
comboBox.ItemsSource = Enumerable.Range(1, 10).Select(i => i * 100).ToList();
comboBox.SelectedIndex = 0;
}
private void PowerLevel_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
ComboBox comboBox = (ComboBox)sender;
DataItem dataItem = (DataItem)comboBox.DataContext;
dataItem.PowerValue = dataItem.SelectedPowerLevel.ToString();
}
private void PumpTemperature_TextChanged(object sender, TextChangedEventArgs e)
{
TextBox textBox = (TextBox)sender;
DataItem dataItem = (DataItem)textBox.DataContext;
double temperature;
if (double.TryParse(textBox.Text, out temperature))
{
dataItem.PumpTemperature = temperature;
}
}
private void PowerValue_TextChanged(object sender, TextChangedEventArgs e)
{
TextBox textBox = (TextBox)sender;
DataItem dataItem = (DataItem)textBox.DataContext;
double powerValue;
if (double.TryParse(textBox.Text, out powerValue))
{
dataItem.PowerValue = powerValue.ToString();
}
}
private void PowerDeviceStatus_Click(object sender, RoutedEventArgs e)
{
Button button = (Button)sender;
DataItem dataItem = (DataItem)button.DataContext;
dataItem.TogglePowerDeviceStatus();
button.Content = dataItem.PowerDeviceStatus;
}
}
public class DataItem : INotifyPropertyChanged
{
public int Index { get; set; }
public DateTime StartDate { get; set; }
public DateTime EndDate { get; set; }
public List<string> PowerDevices { get; set; }
public string SelectedPowerDevice { get; set; }
public List<string> SerialPorts { get; set; }
public string SelectedSerialPort { get; set; }
public List<int> PowerLevels { get; set; }
public int SelectedPowerLevel { get; set; }
public double PumpTemperature { get; set; }
public string PowerValue { get; set; }
public string PowerDeviceStatus { get; set; }
public BitmapImage PowerDeviceStatusImage { get; set; }
public DataItem(int index)
{
Index = index;
StartDate = DateTime.Today;
EndDate = DateTime.Today.AddDays(7);
PowerDevices = Enumerable.Range(1, 20).Select(i => '设备' + i).ToList();
SelectedPowerDevice = PowerDevices.First();
SerialPorts = new List<string>();
PowerLevels = new List<int>();
PumpTemperature = 25;
PowerValue = "100";
PowerDeviceStatus = "关";
PowerDeviceStatusImage = new BitmapImage(new Uri("pack://application:,,,/Images/Off.png"));
}
public void TogglePowerDeviceStatus()
{
if (PowerDeviceStatus == "关")
{
PowerDeviceStatus = "开";
PowerDeviceStatusImage = new BitmapImage(new Uri("pack://application:,,,/Images/On.png"));
}
else
{
PowerDeviceStatus = "关";
PowerDeviceStatusImage = new BitmapImage(new Uri("pack://application:,,,/Images/Off.png"));
}
RaisePropertyChanged("PowerDeviceStatus");
RaisePropertyChanged("PowerDeviceStatusImage");
}
public event PropertyChangedEventHandler PropertyChanged;
private void RaisePropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
}
功能说明
- 添加行:点击 “添加行” 按钮,在 DataGrid 末尾添加一行数据,并自动增加序号。
- 删除行:选中 DataGrid 中的一行,点击 “删除行” 按钮,删除该行数据。
- 日期选择:第二、三列使用 DatePicker 选择开始日期和结束日期。
- 电源设备下拉框:第四列使用 ComboBox,下拉框显示 20 行数据,从 “设备1” 到 “设备20”。
- 端口号下拉框:第五列使用 ComboBox,点击下拉框后,获取当前电脑的串口号并显示在下拉框中。
- 功率瓦数下拉框:第六列使用 ComboBox,下拉框显示 10 行数据,从 “100” 到 “1000”,每次增加 100。
- 功率瓦数下拉框选中事件:选中下拉框中的数据后,将数据赋值给第七列的 TextBox。
- 泵温度文本框:第七列使用 TextBox,输入数值,输入完成后,将数值赋值给数据源。
- 功率值文本框:第八列使用 TextBox,输入数值,输入完成后,将数值赋值给数据源。
- 开关按钮:第九列使用 Button,显示 “开” 或 “关”,点击按钮,切换按钮状态,并将状态赋值给数据源。
- 状态图片:第十列使用 Image,显示当前电源设备的状态图片(开/关)。
注意
- 需要在项目中添加 “Images” 文件夹,并放入 “On.png” 和 “Off.png” 图片。
- 需要添加 “System.IO.Ports” 命名空间,用于获取串口号。
- 需要添加 “System.ComponentModel” 命名空间,用于实现 INotifyPropertyChanged 接口。
- 可以根据实际需求修改代码,添加其他功能。
原文地址: https://www.cveoy.top/t/topic/gviK 著作权归作者所有。请勿转载和采集!