WPF MVVM ToDoList(6)
效果图
项目结构目录
主页代码
//MainWindow.xaml
<Grid> <Grid.RowDefinitions> <RowDefinition Height="60" /> <RowDefinition /> </Grid.RowDefinitions> <StackPanel Orientation="Horizontal"> <TextBlock VerticalAlignment="Center" Text="搜索条件:" /> <TextBox Width="200" Height="25" Margin="10,0,0,0" VerticalContentAlignment="Center" Text="{Binding Search}" /> <Button Width="70" Height="25" Margin="10,0,0,0" Command="{Binding QueryCommand}" Content="搜索" /> <Button Width="70" Height="25" Margin="10,0,0,0" Command="{Binding ResetCommand}" Content="重置" /> <Button Width="70" Height="25" Margin="10,0,0,0" Command="{Binding AddCommand}" Content="新增" /> </StackPanel> <DataGrid Grid.Row="1" AutoGenerateColumns="False" CanUserAddRows="False" ColumnWidth="*" ItemsSource="{Binding GridModelList}"> <DataGrid.Columns> <DataGridTextColumn Binding="{Binding Id}" Header="序号"> <DataGridTextColumn.ElementStyle> <Style TargetType="TextBlock"> <Setter Property="VerticalAlignment" Value="Center" /> <Setter Property="Margin" Value="10" /> </Style> </DataGridTextColumn.ElementStyle> </DataGridTextColumn> <DataGridTextColumn Binding="{Binding Name}" Header="姓名" /> <DataGridTemplateColumn Header="操作"> <DataGridTemplateColumn.CellTemplate> <DataTemplate> <StackPanel Orientation="Horizontal"> <Button Width="60" Height="25" Background="White" Command="{Binding DataContext.EditCommand, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=DataGrid}}" CommandParameter="{Binding Id}" Content="修改" Foreground="Black" /> <Button Width="60" Height="25" Background="red" Command="{Binding DataContext.DelCommand, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=DataGrid}}" CommandParameter="{Binding Id}" Content="删除" Foreground="White" /> </StackPanel> </DataTemplate> </DataGridTemplateColumn.CellTemplate> </DataGridTemplateColumn> </DataGrid.Columns> </DataGrid> </Grid>
{Binding DataContext.DelCommand, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=DataGrid}}
是一个在 WPF 中用于绑定命令的表达式。这个表达式的含义是从当前元素开始向上查找 DataGrid 类型的祖先元素,然后绑定该元素的 DataContext 的 DelCommand 属性。
具体解释如下:
Binding
:表示将某个属性与数据进行绑定。DataContext
:表示元素的数据上下文对象,通常用于存储数据。DelCommand
:表示 DataContext 中的 DelCommand 属性。RelativeSource
:表示在控件树中查找其他元素。Mode=FindAncestor
:表示查找祖先元素。AncestorType=DataGrid
:表示查找到 DataGrid 类型的祖先元素。
//MainWindow.xaml.cs
public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); MainViewModel mainViewModel = new MainViewModel(); mainViewModel.Query(); // 绑定数据 this.DataContext = mainViewModel; } }
主页数据
//MainViewModel
public class MainViewModel : ViewModelBase { public MainViewModel() { localDb = new localDb(); Query(); QueryCommand = new RelayCommand(Query); ResetCommand = new RelayCommand(Reset); EditCommand = new RelayCommand<int>(t => Edit(t)); DelCommand = new RelayCommand<int>(t => Del(t)); AddCommand = new RelayCommand(Add); } localDb localDb; #region Command public RelayCommand QueryCommand { get; set; } public RelayCommand ResetCommand { get; set; } public RelayCommand<int> EditCommand { get; set; } public RelayCommand<int> DelCommand { get; set; } public RelayCommand AddCommand { get; set; } #endregion private ObservableCollection<Student> gridModelList; private string search = String.Empty; public string Search { get { return search; } set { search = value; RaisePropertyChanged(); } } public ObservableCollection<Student> GridModelList { get { return gridModelList; } set { gridModelList = value; RaisePropertyChanged(); } } public void Query() { var models = localDb.GetStudentsByName(Search); GridModelList = new ObservableCollection<Student>(); if (models != null) { foreach (var model in models) { GridModelList.Add(model); } } } public void Reset() { Search = String.Empty; this.Query(); } public void Edit(int id) { var model = localDb.GetStudentById(id); if (model != null) { UserView view = new UserView(model); var r = view.ShowDialog(); if (r.Value) { var newModel = GridModelList.FirstOrDefault(model => model.Id == id); if (newModel != null) { newModel.Name = model.Name; } } } } public void Add() { Student student = new Student(); UserView view = new UserView(student); var r=view.ShowDialog(); if (r.Value) { localDb.AddStudent(student); this.Query(); } } public void Del(int id) { var model = localDb.GetStudentById(id); if (model != null) { var r = MessageBox.Show($"确认删除当前用户{model.Name}", "操作提示", MessageBoxButton.OK, MessageBoxImage.Question); if (r == MessageBoxResult.OK) { localDb.DetachStudent(model); } this.Query(); } } }
弹框结构
//userView.xaml <Grid> <Grid.RowDefinitions> <RowDefinition Height="60" /> <RowDefinition /> <RowDefinition Height="60" /> </Grid.RowDefinitions> <TextBlock Margin="10,0,0,0" VerticalAlignment="Center" FontSize="24" FontWeight="Bold" Text="编辑用户信息" /> <StackPanel Grid.Row="1" Margin="20"> <StackPanel Orientation="Horizontal"> <TextBlock VerticalAlignment="Center" Text="姓名:" /> <TextBox Width="200" Height="25" Text="{Binding Model.Name}" /> </StackPanel> </StackPanel> <StackPanel Grid.Row="2" HorizontalAlignment="Right" Orientation="Horizontal"> <Button Width="70" Height="25" Click="btnSave" Content="确定" /> <Button Width="70" Height="25" Margin="10,0,10,0" Click="btnCancel" Content="取消" /> </StackPanel> </Grid>
弹框数据
public UserView(Student student) { InitializeComponent(); this.DataContext = new { Model = student }; } private void btnSave(object sender, RoutedEventArgs e) { this.DialogResult = true; } private void btnCancel(object sender, RoutedEventArgs e) { this.DialogResult= false; }
其他
//localDb.cs public localDb() { Init(); } private List<Student> Students { get; set; } private void Init() { Students = new List<Student>(); for (int i = 0; i < 30; i++) { Students.Add(new Student() { Id = i, Name = $"Sample{i}" }); } } public List<Student> GetStudents() { return Students; } public void AddStudent(Student student) { Students.Add(new Student() { Name = student.Name, Id = Students.Count+1 }); } public void DetachStudent(Student student) { var model=Students.FirstOrDefault(e=>e.Id==student.Id); if(model != null) { Students.Remove(model); } } public List<Student> GetStudentsByName(string name) { return Students.Where(e=>e.Name.Contains(name)).ToList(); } public Student? GetStudentById(int id) { return Students.FirstOrDefault(e => e.Id.Equals(id)); }
//Student.cs public class Student:ViewModelBase { private int id; private string name; public int Id { get { return id; } set { id = value; RaisePropertyChanged(); } } public string Name { get { return name; } set { name = value; RaisePropertyChanged(); } } }