WPF入门教程系列五——Window 介绍

 
 
 

八、在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中的数据,随着下拉框的变化而随之变化。如下图。

WPF入门教程系列二十八 ——DataGrid使用示例MVVM模式(6)的更多相关文章

  1. WPF入门教程系列二十二——DataGrid示例(二)

    DataGrid示例的后台代码 1)  通过Entity Framework 6.1 从数据库(本地数据库(local)/Test中的S_City表中读取城市信息数据,从S_ Province表中读取 ...

  2. WPF入门教程系列二十——ListView示例(二)

    第四步.WPF后台逻辑代码编写 在后台用Entity Framework 6.1的Code First方式获取数据库中的数据.同时,在“刷新”按钮的方法中进行数据绑定.操作步骤如下: 1)  在“刷新 ...

  3. WPF入门教程系列二十三——DataGrid示例(三)

    DataGrid的选择模式 默认情况下,DataGrid 的选择模式为“全行选择”,并且可以同时选择多行(如下图所示),我们可以通过SelectionMode 和SelectionUnit 属性来修改 ...

  4. WPF入门教程系列(二) 深入剖析WPF Binding的使用方法

    WPF入门教程系列(二) 深入剖析WPF Binding的使用方法 同一个对象(特指System.Windows.DependencyObject的子类)的同一种属性(特指DependencyProp ...

  5. WPF入门教程系列二——Application介绍

    一.Application介绍 WPF和WinForm 很相似, WPF与WinForm一样有一个 Application对象来进行一些全局的行为和操作,并且每个 Domain (应用程序域)中仅且只 ...

  6. WPF入门教程系列二十一——DataGrid示例(一)

    前面我们学习了ListView控件的使用示例,今天我们来学习DataGrid的有关知识.提到DataGrid 不管是Asp.Net中的网页开发还是WinForm应用程序开发都会频繁使用.通过它我们可以 ...

  7. WPF入门教程系列二

    WPF控件和布局 一.  前言  公司项目基于WPF开发,最近项目上线有点空闲时间写一篇基于wpf的基础教材,WPF也是近期才接触,学习WPF也是在网上查资料与微软的MSDN进行学习,写本博客的目为了 ...

  8. WPF入门教程系列三——Application介绍(续)

    接上文WPF入门教程系列二——Application介绍,我们继续来学习Application 三.WPF应用程序的关闭 WPF应用程序的关闭只有在应用程序的 Shutdown 方法被调用时,应用程序 ...

  9. Web 前端开发人员和设计师必读文章推荐【系列二十八】

    <Web 前端开发精华文章推荐>2014年第7期(总第28期)和大家见面了.梦想天空博客关注 前端开发 技术,分享各类能够提升网站用户体验的优秀 jQuery 插件,展示前沿的 HTML5 ...

  10. WPF入门教程系列(一) 创建你的第一个WPF项目

    WPF入门教程系列(一) 创建你的第一个WPF项目 WPF基础知识 快速学习绝不是从零学起的,良好的基础是快速入手的关键,下面先为大家摞列以下自己总结的学习WPF的几点基础知识: 1) C#基础语法知 ...

随机推荐

  1. 使用Electron-builder将web项目封装客户端安装包 发布

    背景:之前用electron-packager将web项目打包成客户端时,exe文件只能在当前文件夹下运行,如果发送给别人使用 极不方便.所以我们可以用electron-builder将web项目封装 ...

  2. 这年头,谁的好友列表还没有躺一个ChatGPT啊?

    你要是说这个,我可不困了 大家好,我最近开始使用一款非常有趣的AI机器人,它叫做ChatGPT.ChatGPT是一款独特的聊天机器人,它可以进行智能对话,回答你的问题,还可以学习你的语言习惯,使得对话 ...

  3. GLM:通用语言模型

    ChatGPT已经火了一段时间了,国内也出现了一些平替,其中比较容易使用的是ChatGLM-6B:https://github.com/THUDM/ChatGLM-6B ,主要是能够让我们基于单卡自己 ...

  4. CentOS 9 开局配置

    CentOS 9 开局配置 CentOS 9 发布有几年了,一直没有尝试使用,CentOS 9 有一些变动. 查看系统基础信息 # 查看系统基础信息 [root@chenby ~]# neofetch ...

  5. pandas安装1

    Python 官方标准发行版并没有自带 Pandas 库,因此需要另行安装.除了标准发行版外,还有一些第三方机构发布的 Python 免费发行版, 它们在官方版本的基础上开发而来,并有针对性的提前安装 ...

  6. pythonz之time库常用方法

    ime.time() 获取当前时间戳.time.ctime() 当前时间的字符串形式.time.localtime() 当前时间的 struct_time 形式.time.strftime() 用来获 ...

  7. [Maven]Maven聚合工程

    一直对此问题好奇,正好有这兴致和时间,有必要了解一下. 所谓聚合项目,实际上就是对项目分模块. 互联网项目一般来说按照业务分(订单模块.VIP模块.支付模块.CMS模块-): 传统的软件项目,大多采用 ...

  8. Nordic芯片烧录指南

    本文讲介绍Nordic系列芯片的烧录方式 一.准备工作 1.硬件 首先需要准备一块Nordic的DK或者Jlink,但是需要注意的是x宝购买的盗版Jlink因为没有license,用一段时间可能会被锁 ...

  9. socket搭建web服务端

    import socket from threading import Thread import time def html(conn): time_tag = str(time.time()) p ...

  10. 用Abp实现两步验证(Two-Factor Authentication,2FA)登录(三):免登录验证

    @ 目录 原理 修改请求报文 配置JwtBearerOptions 生成Token 校验Token 修改认证EndPoint 修改前端 登录 登出 最终效果 项目地址 免登录验证是用户在首次两步验证通 ...