【愚公系列】2023年10月 WPF控件专题 DataGrid控件详解
🏆 作者简介,愚公搬代码
🏆《头衔》:华为云特约编辑,华为云云享专家,华为开发者专家,华为产品云测专家,CSDN博客专家,阿里云专家博主,腾讯云优秀博主,掘金优秀博主,51CTO博客专家等。
🏆《近期荣誉》:2022年CSDN博客之星TOP2,2022年华为云十佳博主等。
🏆《博客内容》:.NET、Java、Python、Go、Node、前端、IOS、Android、鸿蒙、Linux、物联网、网络安全、大数据、人工智能、U3D游戏、小程序等相关领域知识。
🏆🎉欢迎 👍点赞✍评论⭐收藏
🚀前言
WPF控件是Windows Presentation Foundation(WPF)中的基本用户界面元素。它们是可视化对象,可以用来创建各种用户界面。WPF控件可以分为两类:原生控件和自定义控件。
原生控件是由Microsoft提供的内置控件,如Button、TextBox、Label、ComboBox等。这些控件都是WPF中常见的标准用户界面元素。
自定义控件则允许开发人员使用XAML和C#等编程语言来创建个性化的用户界面元素。自定义控件可以根据需求提供更多的功能和自定义化选项,以及更好的用户体验。
🚀一、DataGrid控件详解
WPF中的DataGrid是一个非常强大和灵活的控件,它可用于展示和编辑数据。DataGrid可以与各种数据源进行绑定,如数据表、XML文件、对象集合等,并且可以进行列的自定义、排序、过滤和分组等操作。以下是一些常用的DataGrid控件属性和方法:
属性:
- AutoGenerateColumns:指定是否自动生成列。
- ItemsSource:指定数据源。
- IsReadOnly:指定是否只读。
- Columns:指定列集合。
- RowHeaderWidth:指定行头宽度。
- RowHeadersVisibility:指定行头的可见性。
- SelectionMode:指定选择模式。
方法:
- BeginEdit():开始编辑当前单元格。
- CancelEdit():取消当前单元格的编辑状态。
- CommitEdit():提交当前单元格的编辑状态。
- CancelEdit():取消当前单元格的编辑状态。
- Sort():对数据进行排序。
- Refresh():刷新数据。
DataGrid还有许多其他的属性和方法,可以根据需求进行使用。
🔎1.属性介绍
WPF中DataGrid控件的常见属性如下:
AutoGenerateColumns:是否自动生成列,默认为true。
CanUserAddRows:是否允许用户新增行,默认为true。
CanUserDeleteRows:是否允许用户删除行,默认为true。
CanUserResizeColumns:是否允许用户调整列宽,默认为true。
CanUserResizeRows:是否允许用户调整行高,默认为true。
CanUserSortColumns:是否允许用户排序列,默认为true。
IsReadOnly:是否只读,默认为false。
HeadersVisibility:列头的可见性,默认为Column。
SelectionMode:选择模式,有Single和Extended两种模式可选,默认为Extended。
RowHeaderWidth:行头宽度。
RowHeight:行高。
AlternatingRowBackground:交替行的背景色。
GridLinesVisibility:网格线的可见性,默认为None。
ItemsSource:数据源。
Columns:列集合,可以手动定义和配置每一列的属性。
🔎2.常用场景
WPF中DataGrid控件常用场景包括以下几个方面:
数据展示:DataGrid控件可以方便地展示数据表格,特别是当数据量比较大时,使用DataGrid可以快速地进行数据查看和筛选。
数据编辑:DataGrid控件可以支持数据的编辑,包括单元格编辑、行编辑和列编辑等方式,方便用户对数据进行修改和更新。
数据排序和筛选:DataGrid控件支持数据的排序和筛选功能,可以根据用户需求方便地对数据进行排序和筛选。
数据分页:DataGrid控件可以支持数据的分页显示,当数据量比较大时,可以将数据分页展示,方便用户进行快速的数据浏览和查找。
数据导入导出:DataGrid控件可以支持数据的导入和导出,可以将数据快速地导入到DataGrid中进行展示,也可以将DataGrid中的数据导出到其他文件格式中,方便数据的共享和使用。
自定义样式和模板:DataGrid控件可以根据用户需要进行自定义样式和模板,可自由修改表格的外观和布局,使数据的展示更加美观和易于阅读。
🔎3.具体案例
🦋3.1 数据绑定案例
<Window x:Class="WpfAppTest.DataGridWindow"
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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfAppTest"
mc:Ignorable="d"
Title="DataGridWindow" Height="450" Width="600" Loaded="Window_Loaded">
<Grid>
<DataGrid HeadersVisibility="All" AutoGenerateColumns="False" CanUserAddRows="False" IsReadOnly="False" VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Hidden" AlternationCount="3" RowHeaderWidth="20" GridLinesVisibility="All" SelectionUnit="FullRow" SelectionMode="Extended" Background="White" Name="dgList" ItemsSource="{Binding UserList}" >
<DataGrid.RowStyle>
<Style TargetType="DataGridRow">
<Setter Property="Background" Value="Transparent"/>
<Style.Triggers>
<Trigger Property="ItemsControl.AlternationIndex" Value="0">
<Setter Property="Background" Value="LightGray"/>
</Trigger>
<Trigger Property="ItemsControl.AlternationIndex" Value="1">
<Setter Property="Background" Value="LightBlue"/>
</Trigger>
<Trigger Property="ItemsControl.AlternationIndex" Value="2">
<Setter Property="Background" Value="Orange"/>
</Trigger>
</Style.Triggers>
</Style>
</DataGrid.RowStyle>
<DataGrid.Columns>
<DataGridTextColumn Header="编号" Binding="{Binding UserId}" Width="50"/>
<DataGridTextColumn Header="姓名" Binding="{Binding UserName}" Width="80">
<DataGridTextColumn.HeaderTemplate>
<DataTemplate>
<TextBlock Text="{Binding}" Foreground="Red"/>
</DataTemplate>
</DataGridTextColumn.HeaderTemplate>
</DataGridTextColumn>
<DataGridCheckBoxColumn Header="状态" Binding="{Binding UserState}" Width="50"/>
<DataGridComboBoxColumn Header="部门" SelectedValueBinding="{Binding DeptId}" Width="100" DisplayMemberPath="DeptName" SelectedValuePath="DeptId" >
<DataGridComboBoxColumn.ElementStyle>
<Style TargetType="ComboBox">
<Setter Property="ItemsSource" Value="{Binding DataContext.DeptList,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=Window}}"/>
</Style>
</DataGridComboBoxColumn.ElementStyle>
<DataGridComboBoxColumn.EditingElementStyle>
<Style TargetType="ComboBox">
<Setter Property="ItemsSource" Value="{Binding DataContext.DeptList,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=Window}}"/>
</Style>
</DataGridComboBoxColumn.EditingElementStyle>
</DataGridComboBoxColumn>
<DataGridTemplateColumn Header="年龄" Width="50" >
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Label Content="{Binding UserAge}" Foreground="Green" Background="LightBlue"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<TextBox Text="{Binding UserAge}"/>
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
</Grid>
</Window>
/// <summary>
/// 获取用户信息列表
/// </summary>
/// <returns></returns>
private List<UserInfoNew> GetUserList()
{
List<UserInfoNew> list = new List<UserInfoNew>();
string sql = "select UserId,UserName,UserState,UserAge,DeptId from UserInfos where DeptId>0";
SqlDataReader dr = SqlHelper.ExecuteReader(sql, 1);
while (dr.Read())
{
UserInfoNew user = new UserInfoNew();
user.UserId = (int)dr["UserId"];
user.UserName = dr["UserName"].ToString();
user.UserState = (int)dr["UserState"] == 1 ? true : false;
user.UserAge = (int)dr["UserAge"];
user.DeptId = (int)dr["DeptId"];
list.Add(user);
}
dr.Close();
return list;
}
/// <summary>
/// 获取部门列表
/// </summary>
/// <returns></returns>
private List<DeptInfo> GetDepts()
{
List<DeptInfo> list = new List<DeptInfo>();
string sql = "select DeptId,DeptName from DeptInfos";
SqlDataReader dr = SqlHelper.ExecuteReader(sql, 1);
while (dr.Read())
{
DeptInfo dept = new DeptInfo();
dept.DeptId = (int)dr["DeptId"];
dept.DeptName = dr["DeptName"].ToString();
list.Add(dept);
}
dr.Close();
return list;
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
//首先,设置comboBox列的数据源
//colDept.DisplayMemberPath = "DeptName";
//colDept.SelectedValuePath = "DeptId";
//colDept.ItemsSource = GetDepts();
//如果没有设置列的Name属性
//DataGridComboBoxColumn deptCol = dgList.Columns[3] as DataGridComboBoxColumn;
//deptCol.ItemsSource = GetDepts();
//dgList.ItemsSource = GetUserList();
//初始化DGVModel
DGVModel vmodel = new DGVModel();
vmodel.UserList = GetUserList();
vmodel.DeptList = GetDepts();
this.DataContext = vmodel;
}
}
public class UserInfoNew
{
public int UserId { get; set; }
public string UserName { get; set; }
public bool UserState { get; set; }
public int UserAge { get; set; }
public int DeptId { get; set; }
}
public class DeptInfo
{
public int DeptId { get; set; }
public string DeptName { get; set; }
}
/// <summary>
/// Window的数据上下文
/// </summary>
public class DGVModel
{
public List<UserInfoNew> UserList { get; set; }
public List<DeptInfo> DeptList { get; set; }
}
🦋3.2 增删改查案例
以下是一个简单的WPF DataGrid增删改查的案例,其中使用了MVVM的设计模式:
ViewModel:
public class MainViewModel : INotifyPropertyChanged
{
private ObservableCollection<Student> _students;
public ObservableCollection<Student> Students
{
get { return _students; }
set
{
_students = value;
NotifyPropertyChanged("Students");
}
}
private Student _selectedStudent;
public Student SelectedStudent
{
get { return _selectedStudent; }
set
{
_selectedStudent = value;
NotifyPropertyChanged("SelectedStudent");
}
}
public MainViewModel()
{
Students = new ObservableCollection<Student>
{
new Student {Id = 1, Name = "Tom", Gender = "Male", Age = 18},
new Student {Id = 2, Name = "Lucy", Gender = "Female", Age = 20},
new Student {Id = 3, Name = "Jack", Gender = "Male", Age = 22}
};
}
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
Model:
public class Student
{
public int Id { get; set; }
public string Name { get; set; }
public string Gender { get; set; }
public int Age { get; set; }
}
View:
<Window.DataContext>
<local:MainViewModel/>
</Window.DataContext>
<Grid>
<DataGrid ItemsSource="{Binding Students}"
SelectedItem="{Binding SelectedStudent}"
AutoGenerateColumns="False">
<DataGrid.Columns>
<DataGridTextColumn Header="ID" Binding="{Binding Id}"/>
<DataGridTextColumn Header="Name" Binding="{Binding Name}"/>
<DataGridTextColumn Header="Gender" Binding="{Binding Gender}"/>
<DataGridTextColumn Header="Age" Binding="{Binding Age}"/>
</DataGrid.Columns>
</DataGrid>
<StackPanel Grid.Row="1" Orientation="Horizontal" HorizontalAlignment="Right">
<Button Content="Add" Command="{Binding AddCommand}"/>
<Button Content="Delete" Command="{Binding DeleteCommand}" Margin="5"/>
<Button Content="Edit" Command="{Binding EditCommand}"/>
</StackPanel>
</Grid>
ViewModel中的AddCommand、DeleteCommand、EditCommand:
public ICommand AddCommand => new RelayCommand(() =>
{
var student = new Student {Id = Students.Count + 1};
var dialog = new StudentDialog(student);
if (dialog.ShowDialog() == true)
{
Students.Add(student);
}
});
public ICommand DeleteCommand => new RelayCommand(() =>
{
if (SelectedStudent != null)
{
Students.Remove(SelectedStudent);
}
});
public ICommand EditCommand => new RelayCommand(() =>
{
if (SelectedStudent != null)
{
var dialog = new StudentDialog(SelectedStudent);
if (dialog.ShowDialog() == true)
{
// 通知DataGrid更新
var index = Students.IndexOf(SelectedStudent);
Students.RemoveAt(index);
Students.Insert(index, SelectedStudent);
}
}
});
StudentDialog.xaml:
<Window.DataContext>
<local:StudentDialogViewModel/>
</Window.DataContext>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Label Grid.Column="0" Grid.Row="0" Content="ID"/>
<TextBox Grid.Column="1" Grid.Row="0" Text="{Binding Id}" IsReadOnly="{Binding IsReadOnly}"/>
<Label Grid.Column="0" Grid.Row="1" Content="Name"/>
<TextBox Grid.Column="1" Grid.Row="1" Text="{Binding Name}" IsReadOnly="{Binding IsReadOnly}"/>
<Label Grid.Column="0" Grid.Row="2" Content="Gender"/>
<TextBox Grid.Column="1" Grid.Row="2" Text="{Binding Gender}" IsReadOnly="{Binding IsReadOnly}"/>
<Label Grid.Column="0" Grid.Row="3" Content="Age"/>
<TextBox Grid.Column="1" Grid.Row="3" Text="{Binding Age}" IsReadOnly="{Binding IsReadOnly}"/>
<Button Grid.Column="0" Grid.Row="4" Content="OK" Command="{Binding OKCommand}" Width="60" Margin="5"/>
<Button Grid.Column="0" Grid.Row="4" Content="Cancel" Command="{Binding CancelCommand}" Width="60" Margin="5"/>
</Grid>
StudentDialogViewModel:
public class StudentDialogViewModel : INotifyPropertyChanged
{
private Student _student;
public bool IsReadOnly { get; set; }
public StudentDialogViewModel()
{
OKCommand = new RelayCommand(() => { Close(true); });
CancelCommand = new RelayCommand(() => { Close(false); });
}
public StudentDialogViewModel(Student student)
: this()
{
_student = student;
if (_student.Id > 0)
{
IsReadOnly = true;
}
}
public int Id
{
get { return _student.Id; }
set
{
if (_student.Id != value)
{
_student.Id = value;
NotifyPropertyChanged("Id");
}
}
}
public string Name
{
get { return _student.Name; }
set
{
if (_student.Name != value)
{
_student.Name = value;
NotifyPropertyChanged("Name");
}
}
}
public string Gender
{
get { return _student.Gender; }
set
{
if (_student.Gender != value)
{
_student.Gender = value;
NotifyPropertyChanged("Gender");
}
}
}
public int Age
{
get { return _student.Age; }
set
{
if (_student.Age != value)
{
_student.Age = value;
NotifyPropertyChanged("Age");
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
public RelayCommand OKCommand { get; set; }
public RelayCommand CancelCommand { get; set; }
private void Close(bool result)
{
var window = Application.Current.Windows.OfType<Window>().SingleOrDefault(x => x.IsActive);
window.DialogResult = result;
window.Close();
}
}
StudentDialogViewModel中使用了RelayCommand,这是一个继承自ICommand的自定义命令类,用于绑定按钮的点击事件。
在StudentDialogViewModel中,我们使用了一个私有字段_student来存储传入的Student对象,以及一些属性来绑定StudentDialog的控件,在属性的setter中通知界面更新。
在StudentDialogViewModel中,我们还定义了两个RelayCommand,分别绑定OK和Cancel按钮的点击事件,并在Close方法中关闭窗口并返回结果。
最后,将StudentDialogViewModel传递给StudentDialog.xaml的DataContext,即可实现一个简单的增删改查功能的WPF DataGrid。
🚀感谢:给读者的一封信
亲爱的读者,
我在这篇文章中投入了大量的心血和时间,希望为您提供有价值的内容。这篇文章包含了深入的研究和个人经验,我相信这些信息对您非常有帮助。
如果您觉得这篇文章对您有所帮助,我诚恳地请求您考虑赞赏1元钱的支持。这个金额不会对您的财务状况造成负担,但它会对我继续创作高质量的内容产生积极的影响。
我之所以写这篇文章,是因为我热爱分享有用的知识和见解。您的支持将帮助我继续这个使命,也鼓励我花更多的时间和精力创作更多有价值的内容。
如果您愿意支持我的创作,请扫描下面二维码,您的支持将不胜感激。同时,如果您有任何反馈或建议,也欢迎与我分享。
再次感谢您的阅读和支持!
最诚挚的问候, “愚公搬代码”
- 点赞
- 收藏
- 关注作者
评论(0)