0
点赞
收藏
分享

微信扫一扫

【愚公系列】2023年09月 WPF控件专题 DataGrid控件详解

(文章目录)

前言

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控件的常见属性如下:

  1. AutoGenerateColumns:是否自动生成列,默认为true。

  2. CanUserAddRows:是否允许用户新增行,默认为true。

  3. CanUserDeleteRows:是否允许用户删除行,默认为true。

  4. CanUserResizeColumns:是否允许用户调整列宽,默认为true。

  5. CanUserResizeRows:是否允许用户调整行高,默认为true。

  6. CanUserSortColumns:是否允许用户排序列,默认为true。

  7. IsReadOnly:是否只读,默认为false。

  8. HeadersVisibility:列头的可见性,默认为Column。

  9. SelectionMode:选择模式,有Single和Extended两种模式可选,默认为Extended。

  10. RowHeaderWidth:行头宽度。

  11. RowHeight:行高。

  12. AlternatingRowBackground:交替行的背景色。

  13. GridLinesVisibility:网格线的可见性,默认为None。

  14. ItemsSource:数据源。

  15. Columns:列集合,可以手动定义和配置每一列的属性。

2.常用场景

WPF中DataGrid控件常用场景包括以下几个方面:

  1. 数据展示:DataGrid控件可以方便地展示数据表格,特别是当数据量比较大时,使用DataGrid可以快速地进行数据查看和筛选。

  2. 数据编辑:DataGrid控件可以支持数据的编辑,包括单元格编辑、行编辑和列编辑等方式,方便用户对数据进行修改和更新。

  3. 数据排序和筛选:DataGrid控件支持数据的排序和筛选功能,可以根据用户需求方便地对数据进行排序和筛选。

  4. 数据分页:DataGrid控件可以支持数据的分页显示,当数据量比较大时,可以将数据分页展示,方便用户进行快速的数据浏览和查找。

  5. 数据导入导出:DataGrid控件可以支持数据的导入和导出,可以将数据快速地导入到DataGrid中进行展示,也可以将DataGrid中的数据导出到其他文件格式中,方便数据的共享和使用。

  6. 自定义样式和模板: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。

举报

相关推荐

0 条评论