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中的資料,隨著下拉框的變化而隨之變化。如下圖。