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

来源:https://www.cnblogs.com/chillsrc/archive/2023/06/18/17488927.html
-Advertisement-
Play Games

## 前言 使用 ABP vNext(下文簡稱 ABP)時,通常都是從 cli 開始新建模板,從一個空項目開始。對已經存續的項目來說,現有的數據,特別是用戶等核心數據需要進行遷移。 老的項目,隨著規模越來越大,每次修改都需要更改非常多地方,最重要的是,共用資料庫使得維護起來需要小心翼翼。為了後續維護 ...


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

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • # Go 語言之 Viper 的使用 ## Viper 介紹 [Viper](https://github.com/spf13/viper): ### 安裝 ```bash go get github.com/spf13/viper ``` ### Viper 是什麼? Viper 是一個針對 Go ...
  • 以WebMvcAutoConfiguration自動配置的原理為例,SpringBoot內部對大量的第三方庫或Spring內部庫進行了預設配置,這些配置是否生效,取決於我們是否引入了對應庫所需的依賴,如果有那麼預設配置就會生效。如果引入springboot-starter-web那麼對應的web配置 ...
  • `NumPy`(Numerical Python)是一個`Python`庫,主要用於高效地處理多維數組和矩陣計算。它是科學計算領域中使用最廣泛的一個庫。 在`NumPy`中,**數組**是最核心的概念,用於存儲和操作數據。 `NumPy`數組是一種多維數組對象,可以存儲相同類型的元素,它支持高效的數 ...
  • 一、簡介 官網: https://spring.io/projects/spring-framework#overview 官方下載工具: https://repo.spring.io/release/org/springframework/spring/ github下載: https://git ...
  • # 頁面預覽 ## 預約掛號 - 根據預約周期,展示可預約日期,根據有號、無號、約滿等狀態展示不同顏色,以示區分 - 可預約最後一個日期為即將放號日期 - 選擇一個日期展示當天可預約列表 ![image-20230227202834422](https://s2.loli.net/2023/06/1 ...
  • # 一、緒論 ## 1.1 基本概念 1. 加速比:表示加速效果。單個處理器運行花費時間 / P個處理器運行花費時間;$S=\frac{T(1)}{T(p)}$ 2. 效率:$E = \frac{S}{p} = \frac{T(1)}{T(p)\times p}$ 3. 開銷:$C=T(p)\tim ...
  • 1、簡介 SiftingAppender 可根據給定的運行時屬性將日誌分離或篩選。例如,SiftingAppender 可以根據用戶會話將日誌事件分開,以便不同用戶生成的日誌進入不同的日誌文件,每個用戶一個日誌文件。SiftingAppender 有兩個屬性: timeout SiftingAppe ...
  • 這一次咱們來探究一下怎麼用純代碼寫 WPF 模板。模板有個共同基類 FrameworkTemplate,數據模板、控制項模板等是從此類派生的,因此,該類已定義了一些通用成員。 用代碼構建模板,重要的成員是 VisualTree 屬性,它的類型是 FrameworkElementFactory。可見,模 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...