见智见仁 发表于 2023-6-18 11:53:04

WPF入门教程系列二十八 ——DataGrid使用示例MVVM模式(6)

WPF入门教程系列目录WPF入门教程系列二——Application介绍WPF入门教程系列三——Application介绍(续)WPF入门教程系列四——Dispatcher介绍WPF入门教程系列五——Window 介绍
WPF入门教程系列十一——依赖属性(一)WPF入门教程系列十五——WPF中的数据绑定(一)   八、在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(<br>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集合;
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}" <br>CommandParameter="{BindingElementName=cboProvince}"/>
                  </be:EventTrigger>
                </be:Interaction.Triggers>

            </ComboBox>
      </WrapPanel>

      <DataGrid x:Name="gridArea" Grid.Row="1" ItemsSource="{Binding GridAreaList}" <br>AutoGenerateColumns="False" HorizontalAlignment="Left" VerticalAlignment="Top" <br>SelectedItem="{Binding Path=AreaVM,
                                        Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}">

            <DataGrid.Columns>

                <DataGridComboBoxColumn Header="城市" Width="120" <br>ItemsSource="{Binding Path=DataContext.GridCityList, <br>RelativeSource={RelativeSource AncestorType={x:Type Window}}}"<br>x:Name="cboCity" ClipboardContentBinding="{x:Null}"<br> SelectedValuePath="Code" SelectedValueBinding="{Binding Path=CityCode,<br>UpdateSourceTrigger=PropertyChanged}"<br>DisplayMemberPath="Name" SelectedItemBinding="{x:Null}" />
                <DataGridTextColumn Header="县区镇" Width="*" Binding="{Binding Name}" <br>ClipboardContentBinding="{x:Null}"/>
                <DataGridTextColumn Header="邮编" Width="100"Binding="{Binding Code}" <br>ClipboardContentBinding="{x:Null}"/>
                <DataGridTextColumn Header="创建时间" Width="160" Binding="{Binding Created}" <br>ClipboardContentBinding="{x:Null}"/>
                <DataGridTextColumn Header="更新时间" Width="160" Binding="{Binding Updated}" <br>ClipboardContentBinding="{x:Null}"/>
            </DataGrid.Columns>
      </DataGrid>
      

      <WrapPanel Grid.Row="2">
      <Buttonx:Name="btnRefresh"Height="22" Width="120" Click="btnRefresh_Click">刷新</Button>
<Buttonx: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(<br>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://www.cnblogs.com/chillsrc/archive/2023/06/18/17488927.html
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!
页: [1]
查看完整版本: WPF入门教程系列二十八 ——DataGrid使用示例MVVM模式(6)