- A+
所属分类:.NET技术
八、在Command中传递参数
7.上面Buttom的Command类就是纯命令,什么参数都不接收,这次的ProvinceChangedCommand类在执行命令的时候,能够传参数!采用泛型的形式,给Action添加泛型参数。
8. 在Visual Studio 2022的解决方案资源管理器中,使用鼠标右键单击“Command”文件夹,在弹出菜单中选择“添加--> 类”,在弹出的“添加新项”对话框中,选择添加 “ProvinceChangedCommand”类,这是一个我们要实现的保存操作指令,然后选择“添加”。ProvinceChangedCommand的具体代码如下:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Input; namespace WpfGridDemo.NET7.Command { public class ProvinceChangedCommand<T> : ICommand { /// <summary> /// 命令能否执行 /// </summary> readonly Func<bool> _canExecute; /// <summary> /// 命令执行的方法 /// </summary> readonly Action<T> _execute; /// <summary> /// 命令的构造函数 /// </summary> /// <param name="action">命令需执行的方法</param> /// <param name="canExecute">命令是否可以执行的方法</param> public ProvinceChangedCommand(Action<T> action, Func<bool> canExecute) { _execute = action; _canExecute = canExecute; } /// <summary> /// 判断命令是否可以执行 /// </summary> /// <param name="parameter"></param> /// <returns></returns> public bool CanExecute(Object parameter) { if (_canExecute == null) return true; return _canExecute(); } /// <summary> /// 执行命令 /// </summary> /// <param name="parameter"></param> public void Execute(Object parameter) { _execute((T)parameter); } /// <summary> /// 事件追加、移除 /// </summary> public event EventHandler CanExecuteChanged { add { if (_canExecute != null) CommandManager.RequerySuggested += value; } remove { if (_canExecute != null) CommandManager.RequerySuggested -= value; } } } } void ProviceSelectionChangedExecute(object sender) { try { if (sender is ComboBox) { ComboBox drp=sender as ComboBox; ProvinceCode=drp.SelectedValue.ToString(); GridDbContext db = new GridDbContext(); var list = db.City.AsTracking().ToList(); List<City> citys = list.Where(x => x.ProvinceCode == ProvinceCode).ToList(); cityList = new ObservableCollection<City>(); if (citys != null) { citys.ForEach((t) => { cityList.Add(t); } ); } var cityCodes = from city in citys select city.Code; List<Area> areas = db.Area.AsTracking().ToList().Where(
x => cityCodes.Contains(x.CityCode)).ToList(); areaList = new ObservableCollection<Area>(); if (areas!=null) { areas.ForEach((t) => { areaList.Add(t); } ); } } } catch (Exception ex) { throw ex; } }
结果如图:我们看到了省份下拉框中已经了省份信息。
9.通过绑定依赖属性,实现自动刷新需要实现以下三步:
1.Model继承并实现 INotifyPropertyChanged 接口;
2.数据集合使用ObservableCollection<T>集合;
3.View使用Binding数据对象属性;
如果不行再看看集合在赋值前需要实例化,不然就出不来(必须要同一个源才行)
10. 在Visual Studio 2022中打开MainWindows.xmal文件,并将文件中的代码修改成如下:
<Window x:Class="WpfGridDemo.NET7.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:be="http://schemas.microsoft.com/xaml/behaviors" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:WpfGridDemo.NET7" mc:Ignorable="d" Title="MainWindow" Height="600" Width="960" Loaded="Window_Loaded" > <Grid> <Grid.RowDefinitions> <RowDefinition Height="100"></RowDefinition> <RowDefinition Height="*"></RowDefinition> <RowDefinition Height="25"></RowDefinition> </Grid.RowDefinitions> <WrapPanel Grid.Row="0" HorizontalAlignment="Left"> <ComboBox x:Name="cboProvince" DisplayMemberPath="Name" SelectedValuePath="Code" > <be:Interaction.Triggers> <be:EventTrigger EventName="SelectionChanged"> <be:InvokeCommandAction Command="{Binding ProviceChangedAction}"
CommandParameter="{Binding ElementName=cboProvince}"/> </be:EventTrigger> </be:Interaction.Triggers> </ComboBox> </WrapPanel> <DataGrid x:Name="gridArea" Grid.Row="1" ItemsSource="{Binding GridAreaList}"
AutoGenerateColumns="False" HorizontalAlignment="Left" VerticalAlignment="Top"
SelectedItem="{Binding Path=AreaVM, Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"> <DataGrid.Columns> <DataGridComboBoxColumn Header="城市" Width="120"
ItemsSource="{Binding Path=DataContext.GridCityList,
RelativeSource={RelativeSource AncestorType={x:Type Window}}}"
x:Name="cboCity" ClipboardContentBinding="{x:Null}"
SelectedValuePath="Code" SelectedValueBinding="{Binding Path=CityCode,
UpdateSourceTrigger=PropertyChanged}"
DisplayMemberPath="Name" SelectedItemBinding="{x:Null}" /> <DataGridTextColumn Header="县区镇" Width="*" Binding="{Binding Name}"
ClipboardContentBinding="{x:Null}"/> <DataGridTextColumn Header="邮编" Width="100" Binding="{Binding Code}"
ClipboardContentBinding="{x:Null}"/> <DataGridTextColumn Header="创建时间" Width="160" Binding="{Binding Created}"
ClipboardContentBinding="{x:Null}"/> <DataGridTextColumn Header="更新时间" Width="160" Binding="{Binding Updated}"
ClipboardContentBinding="{x:Null}"/> </DataGrid.Columns> </DataGrid> <WrapPanel Grid.Row="2"> <Button x:Name="btnRefresh" Height="22" Width="120" Click="btnRefresh_Click">刷新</Button> <Button x:Name="btnSave" Height="22" Width="120" Command="{Binding ClickSaveAction}" >保存</Button> </WrapPanel> </Grid> </Window>
11. 在Visual Studio 2022中打开MainWindowsVM.cs文件,实现下拉框的选择事件的Command命令绑定,将通过Command参数传递过来的省份信息,用于数据查询,同时通知UI界面进行数据刷新。具体如下代码:
using Microsoft.EntityFrameworkCore; using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.ComponentModel; using System.DirectoryServices.ActiveDirectory; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Controls; using System.Windows.Input; using WpfGridDemo.NET7.Entitys; namespace WpfGridDemo.NET7.ViewModel { public class MainWindowVM: ViewModelBase { public MainWindowVM() { cityList = new ObservableCollection<City>(); areaList = new ObservableCollection<Area>(); } private Area m_Area; /// <summary> /// 县镇区数据 /// </summary> public Area AreaVM { get { return m_Area; } set { m_Area = value; } } private string m_Province_Code; /// <summary> /// 省--代码 /// </summary> public string ProvinceCode { get => m_Province_Code; set => m_Province_Code = value; } private ObservableCollection<Area> areaList; public ObservableCollection<Area> GridAreaList { get { return areaList; } set { areaList = value; RaisePropertyChanged("GridAreaList"); } } private ObservableCollection<City> cityList; public ObservableCollection<City> GridCityList { get { return cityList; } set { cityList = value; RaisePropertyChanged("GridCityList"); } } /// <summary> /// 命令要执行的方法 /// </summary> void SaveExecute() { try { GridDbContext db = new GridDbContext(); var list=db.Area.AsTracking().ToList(); Area modifyArea = list.Where(x=>x.Id==AreaVM.Id).FirstOrDefault(); if (modifyArea != null) { modifyArea.Name = AreaVM.Name; modifyArea.Updated = DateTime.Now; db.SaveChanges(); } } catch (Exception ex) { throw ex; } } /// <summary> /// 命令是否可以执行 /// </summary> /// <returns></returns> bool CanSaveExecute() { return false; } /// <summary> /// 创建新命令 /// </summary> public ICommand ClickSaveAction { get { return new Command.SaveCommand(SaveExecute, CanSaveExecute); } } //combobox /// <summary> /// 命令要执行的方法 /// </summary> void ProviceSelectionChangedExecute(object sender) { try { if (sender is ComboBox) { ComboBox drp=sender as ComboBox; ProvinceCode=drp.SelectedValue.ToString(); GridDbContext db = new GridDbContext(); var list = db.City.AsTracking().ToList(); List<City> citys = list.Where(x => x.ProvinceCode == ProvinceCode).ToList(); var cityCodes = from city in citys select city.Code; List<Area> areas = db.Area.AsTracking().ToList().Where(
x => cityCodes.Contains(x.CityCode)).ToList(); areaList.Clear(); if (areas!=null) { areas.ForEach((t) => { areaList.Add(t); } ); } cityList.Clear(); if (citys != null) { citys.ForEach((t) => { cityList.Add(t); } ); } } } catch (Exception ex) { throw ex; } } /// <summary> /// 命令是否可以执行 /// </summary> /// <returns></returns> bool CanSelectionChangedExecute() { return true; } /// <summary> /// 创建新命令 /// </summary> public ICommand ProviceChangedAction { get { return new Command.ProvinceChangedCommand<object>(ProviceSelectionChangedExecute, CanSelectionChangedExecute); } } }
12.在Visual Studio 2022中按F5键,启动WPF应用程序。然后使用鼠标点击省份下拉框,能够看到,界面中DataGrid中的数据,随着下拉框的变化而随之变化。如下图。