WPF入门教程系列二十八 ——DataGrid使用示例MVVM模式
Posted DotNet菜园
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了WPF入门教程系列二十八 ——DataGrid使用示例MVVM模式相关的知识,希望对你有一定的参考价值。
八、在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>
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中的数据,随着下拉框的变化而随之变化。如下图。
![](https://image.cha138.com/20230618/553989e7b9684ab18b9dc34f241be3e1.jpg)
以上是关于WPF入门教程系列二十八 ——DataGrid使用示例MVVM模式的主要内容,如果未能解决你的问题,请参考以下文章
ROS从入门到精通系列(二十八)-- ROS控制器图形化界面开发