背景:该功能为几乎所有系统开发都需要使用的功能,现提供简单的案例。
1、MyCommand
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;namespace WpfApplication25_DataGrid.ViewModels
{public class MyCommand:ICommand{private readonly Action _execute;private readonly Func<bool> _canExecute;private readonly Action<object> _execute2;public MyCommand(Action execute, Func<bool> canExecute = null){_execute = execute;// throw new ArgumentNullException(nameof(execute));_canExecute = canExecute;}public event EventHandler CanExecuteChanged{add { CommandManager.RequerySuggested += value; }remove { CommandManager.RequerySuggested -= value; }}public bool CanExecute(object parameter){return _canExecute == null || _canExecute();}public void Execute(object parameter){_execute();}}
}
2、Notify
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;namespace WpfApplication25_DataGrid.ViewModels
{public abstract class Notify : INotifyPropertyChanged{public event PropertyChangedEventHandler PropertyChanged;public void OnPropertyChanged([CallerMemberName] string name = null){PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));}}
}
3、数据模型Person
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;namespace WpfApplication25_DataGrid.Models
{public class Person{public int Id { get; set; }public string Name { get; set; }public int Age { get; set; }}
}
4、编辑EditPersonWindow.xaml
<Window x:Class="WpfApplication25_DataGrid.Views.EditPersonWindow"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:WpfApplication25_DataGrid.Views"mc:Ignorable="d"Title="EditPersonWindow" Height="200" Width="300"><Grid><StackPanel Orientation="Vertical" Margin="10"><Label Content="姓名:"/><TextBox Text="{Binding Person.Name}" Width="200"/><Label Content="年龄:"/><TextBox Text="{Binding Person.Age}" Width="200"/><StackPanel Orientation="Horizontal" HorizontalAlignment="Right" Margin="0,10,0,0"><Button Content="保存" Command="{Binding SaveCommand}" Width="80"/><Button Content="取消" Command="{Binding CancelCommand}" Width="80"/></StackPanel></StackPanel></Grid>
</Window>
5、编辑EditPersonWindow.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using WpfApplication25_DataGrid.ViewModels;namespace WpfApplication25_DataGrid.Views
{/// <summary>/// EditPersonWindow.xaml 的交互逻辑/// </summary>public partial class EditPersonWindow : Window{public EditPersonWindow(EditPersonViewModel viewModel){InitializeComponent();this.DataContext = viewModel;}}
}
6、EditPersonViewModel.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;
using WpfApplication25_DataGrid.Models;namespace WpfApplication25_DataGrid.ViewModels
{public class EditPersonViewModel : Notify{public Person Person { get; set; }public Action<bool?> CloseAction { get; set; }public MyCommand SaveCommand { get; set; }public MyCommand CancelCommand { get; set; }public EditPersonViewModel(Person person){Person = person;SaveCommand = new MyCommand(SavePerson);CancelCommand = new MyCommand(Cancel);}private void SavePerson(){CloseAction?.Invoke(true);}private void Cancel(){CloseAction?.Invoke(false);}}
}
7、MainWindow.xaml
<Window x:Class="WpfApplication25_DataGrid.MainWindow"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:WpfApplication25_DataGrid"xmlns:vm="clr-namespace:WpfApplication25_DataGrid.ViewModels"mc:Ignorable="d"Title="MainWindow" Height="350" Width="525"><Grid><DataGrid ItemsSource="{Binding Persons}"SelectedItem="{Binding SelectedPerson}"AutoGenerateColumns="False"HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top" Height="200" Width="507"><DataGrid.Columns><DataGridTextColumn Header="ID" Binding="{Binding Id}" /><DataGridTextColumn Header="姓名" Binding="{Binding Name}" /><DataGridTextColumn Header="年龄" Binding="{Binding Age}" /></DataGrid.Columns></DataGrid><StackPanel Orientation="Horizontal" HorizontalAlignment="Left" Margin="10,220,0,0" VerticalAlignment="Top"><Button Content="新增" Command="{Binding AddCommand}" Width="80"/><Button Content="删除" Command="{Binding DeleteCommand}" Width="80"/><Button Content="修改" Command="{Binding UpdateCommand}" Width="80"/><Button Content="搜索" Command="{Binding SearchCommand}" Width="80"/><TextBox Text="{Binding SelectTxt}" Width="100" Margin="10,0,0,0"HorizontalAlignment="Left" VerticalAlignment="Center"/></StackPanel></Grid>
</Window>
8.PersonViewModel.cs
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;using WpfApplication25_DataGrid.Models;
using WpfApplication25_DataGrid.Views;namespace WpfApplication25_DataGrid.ViewModels
{public class PersonViewModel : Notify{public ObservableCollection<Person> Persons { get; set; }public Person SelectedPerson { get; set; }public ICommand AddCommand { get; set; }public ICommand DeleteCommand { get; set; }public ICommand UpdateCommand { get; set; }public ICommand SearchCommand { get; set; }/// <summary>/// 查询字段/// </summary>private string selectTxt = "未登录";public string SelectTxt{get { return selectTxt; }set{selectTxt = value;OnPropertyChanged();}}public PersonViewModel(){Persons = new ObservableCollection<Person>{new Person { Id = 1, Name = "Alice", Age = 25 },new Person { Id = 2, Name = "Bob", Age = 30 },new Person { Id = 3, Name = "Charlie", Age = 35 }};AddCommand = new MyCommand(AddPerson);DeleteCommand = new MyCommand(DeletePerson);UpdateCommand = new MyCommand(UpdatePerson);SearchCommand = new MyCommand(SearchPerson);}/// <summary>/// 增/// </summary>/// <param name="parameter"></param>private void AddPerson(){var newPerson = new Person();var editViewModel = new EditPersonViewModel(newPerson);var editWindow = new EditPersonWindow(editViewModel);editViewModel.CloseAction = (result) =>{editWindow.DialogResult = result;editWindow.Close();};if (editWindow.ShowDialog() == true){newPerson.Id = Persons.Count + 1;Persons.Add(newPerson);}}/// <summary>/// 删/// </summary>/// <param name="parameter"></param>/// <returns></returns>private bool CanDeletePerson(){return SelectedPerson != null;}/// <summary>/// 删除/// </summary>/// <param name="parameter"></param>private void DeletePerson(){if (SelectedPerson != null){var result = MessageBox.Show($"确认要删除 {SelectedPerson.Name} 吗?", "删除确认", MessageBoxButton.YesNo);if (result == MessageBoxResult.Yes){Persons.Remove(SelectedPerson);}}}/// <summary>/// 更新/// </summary>/// <param name="parameter"></param>private void UpdatePerson(){if (SelectedPerson != null){var editViewModel = new EditPersonViewModel(SelectedPerson);var editWindow = new EditPersonWindow(editViewModel);editViewModel.CloseAction = (result) =>{editWindow.DialogResult = result;editWindow.Close();};if (editWindow.ShowDialog() == true){// 因为传递的是引用,修改已在窗口中完成}}}查询private void SearchPerson(){string sss = SelectTxt;if (sss!=""){var searchResult = new ObservableCollection<Person>();foreach (var person in Persons){if (person.Id==Convert.ToInt16(sss)){searchResult.Add(person);}}Persons = searchResult;OnPropertyChanged(nameof(Persons));}}}
}