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


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

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

        13.通过Command指令,传递了下拉框所选择的省份,datagrid自动显示相应省份的城市信息,但是以上示例中有一个Bug,就是下拉框中绑定的数据无法显示。

    这是由于DataGridComboBoxColumn若要填充下拉列表,请先使用以下选项之一设置 ItemsSource 属性 ComboBox :

        1)静态资源。 使用StaticResource 标记扩展。

        2)x:Static 代码实体。 使用x:Static 标记扩展。

        3)类型的内联集合 ComboBoxItem 。

    14.比较适合的绑定方式是  2)x:Static 代码实体。 使用x:Static 标记扩展需要添加相应的命名空间。在Visual Studio 2022中打开MainWindows.xmal文件,并在文件的开头添加如下命名空间。           

      xmlns:v="clr-namespace:WpfGridDemo.NET7.ViewModel"

    15. 在Visual Studio 2022中打开MainWindows.xmal文件。对DataGridComboBoxColumn的ItemsSource进行了数据绑定。具体代码如下:

    复制代码
    <DataGridComboBoxColumn Header="城市" Width="120"  x:Name="cboCity" 
    ItemsSource
    ="{x:Static v:MainWindowVM.GridCityList}" ClipboardContentBinding="{x:Null}" SelectedValuePath="Code"
    SelectedValueBinding
    ="{Binding Path=CityCode,UpdateSourceTrigger=PropertyChanged}"
    DisplayMemberPath
    ="Name" SelectedItemBinding="{x:Null}" />
    复制代码
    16.在Visual Studio 2022的解决方案资源管理器中,找到MainWindowVM.cs文件,将GridCityList属性改为静态属性,用于绑定DataGridComboBoxColumn的ItemsSource。具体如下代码:
    复制代码
            private static ObservableCollection cityList;
            public static ObservableCollection GridCityList
            {
    
                get { return cityList; }
                set
                {
    
                    cityList = value;
                    new ViewModelBase().RaisePropertyChanged("GridCityList");
                }
    
            }
    复制代码
    17.在Visual Studio 2022中按F5键,启动WPF应用程序。然后使用鼠标点击省份下拉框,能够看到,界面中DataGrid中的数据,随着下拉框的变化而随之变化,但是城市下拉框中却没有任何数据。看来绑定失效了。如下图。

     

     

     

     

     

    18. 使用静态代码实体的方式,实现省市县联动失败了。又不想使用其他两种方式。在一阵猛于虎的搜索之后,发现一种实现方式。在Visual Studio 2022中打开MainWindows.xmal文件。对DataGridComboBoxColumn进行了数据绑定。具体代码如下:

    复制代码
    <DataGridComboBoxColumn Header="城市(Style)" SelectedValuePath="Code"
    SelectedValueBinding="{Binding Path=CityCode,UpdateSourceTrigger=PropertyChanged}"
    DisplayMemberPath
    ="Name" SelectedItemBinding="{x:Null}" Width="1*"> <DataGridComboBoxColumn.EditingElementStyle> <Style TargetType="ComboBox"> <Setter Property="ItemsSource"
    Value
    ="{Binding Path=DataContext.GridCity,ElementName=gridArea}" /> Style> DataGridComboBoxColumn.EditingElementStyle> <DataGridComboBoxColumn.ElementStyle> <Style TargetType="ComboBox"> <Setter Property="ItemsSource"
    Value
    ="{Binding Path=DataContext.GridCity,ElementName=gridArea}" /> Style> DataGridComboBoxColumn.ElementStyle> DataGridComboBoxColumn>
    复制代码
                  

    19.在Visual Studio 2022的解决方案资源管理器中,找到MainWindowVM.cs文件,添加一个GridCity属性,用于绑定DataGridComboBoxColumn的ItemsSource。以下是属性代码,更完整的代码,请参见下面类的完整代码。

    复制代码
    private ObservableCollection listCity;
    
            public ObservableCollection GridCity
            {
    
                get { return listCity; }
                set
                {
                    listCity = value;
                    RaisePropertyChanged("GridCity");
                }
            }
    复制代码
    20.MainWindow.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"
              xmlns:v="clr-namespace:WpfGridDemo.NET7.ViewModel"
            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" x:Name="cboCity"
    ItemsSource
    ="{x:Static v:MainWindowVM.GridCityList}" ClipboardContentBinding="{x:Null}" SelectedValuePath="Code"
    SelectedValueBinding
    ="{Binding Path=CityCode,UpdateSourceTrigger=PropertyChanged}"
    DisplayMemberPath
    ="Name" SelectedItemBinding="{x:Null}" /> <DataGridComboBoxColumn Header="城市(Style)" SelectedValuePath="Code"
    SelectedValueBinding="{Binding Path=CityCode,UpdateSourceTrigger=PropertyChanged}"
    DisplayMemberPath
    ="Name" SelectedItemBinding="{x:Null}" Width="1*"> <DataGridComboBoxColumn.EditingElementStyle> <Style TargetType="ComboBox"> <Setter Property="ItemsSource"
    Value
    ="{Binding Path=DataContext.GridCity,ElementName=gridArea}" /> Style> DataGridComboBoxColumn.EditingElementStyle> <DataGridComboBoxColumn.ElementStyle> <Style TargetType="ComboBox"> <Setter Property="ItemsSource"
    Value
    ="{Binding Path=DataContext.GridCity,ElementName=gridArea}" /> Style> DataGridComboBoxColumn.ElementStyle> DataGridComboBoxColumn> <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>
    复制代码

     

    21. MainWindowsVM类的完整代码,如下:
    复制代码
    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();
    
                areaList = new ObservableCollection();
    
                listCity = new ObservableCollection();   
    
            }
    
            private Area m_Area;
    
            /// 
            /// 县镇区数据
            /// 
            public Area AreaVM
    
            {
    
                get { return m_Area; }
    
                set { m_Area = value; }
    
            }
    
            private string m_Province_Code;
    
            /// 
            /// 省--代码
            /// 
    
            public string ProvinceCode { get => m_Province_Code; set => m_Province_Code = value; }
    
            private ObservableCollection areaList;
    
             public ObservableCollection GridAreaList
             {
                 get { return areaList; }
    
                 set
                 {
    
                    areaList = value;
                     RaisePropertyChanged("GridAreaList");
    
                 }
    
            }
    
            private static ObservableCollection cityList;
    
            public static ObservableCollection GridCityList
            {
    
                get { return cityList; }
    
                set
                {
                    cityList = value;
                    new ViewModelBase().RaisePropertyChanged("GridCityList");
                }
            } 
    
            private ObservableCollection listCity;
    
            public ObservableCollection GridCity
    
            {
                get { return listCity; }
                set
    
                {
                    listCity = value;
                    RaisePropertyChanged("GridCity");
                }
    
            }
    
            /// 
            /// 命令要执行的方法
            /// 
            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;
                }
            }
    
     
    
            /// 
            /// 命令是否可以执行
            /// 
            /// 
            bool CanSaveExecute()
            {
                return false;
            }
    
     
    
            /// 
            /// 创建新命令
            /// 
            public ICommand ClickSaveAction
            {
                get
                {
                    return new Command.SaveCommand(SaveExecute, CanSaveExecute);
                }
    
            }
    
            //combobox
            /// 
            /// 命令要执行的方法
            /// 
            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 citys = list.Where(x => x.ProvinceCode == ProvinceCode).ToList();
    
                        var cityCodes = from city in citys
    
                                        select city.Code;
    
                        List 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); } ); } listCity.Clear(); if (citys != null) { citys.ForEach((t) => { listCity.Add(t); } ); } } } catch (Exception ex) { throw ex; } } /// /// 命令是否可以执行 /// /// bool CanSelectionChangedExecute() { return true; } /// /// 创建新命令 /// public ICommand ProviceChangedAction { get { return new Command.ProvinceChangedCommand<object>(ProviceSelectionChangedExecute
    , CanSelectionChangedExecute); } } } }
    复制代码

    22.在Visual Studio 2022中按F5键,启动WPF应用程序。然后使用鼠标点击省份下拉框,能够看到,界面中DataGrid中的数据,随着下拉框的变化而随之变化,其中使用静态实体代码绑定的城市下拉框中却没有任何数据。使用使用非静态资源,在两个样式中绑定combobox的itemSource属性方式,效果有效。如下图。

     

  • 相关阅读:
    Linux eBPF介绍(一)
    HarmonyOS学习 -- ArkTS开发语言入门
    24深圳杯数学建模挑战赛A题6页初步思路+参考论文+保姆级答疑!!!
    Unity C# 网络学习(十)——UnityWebRequest(一)
    React18入门(第一篇)——JSX、TSX语法详解
    解决APP抓包问题【网络安全】
    Llama 3加入大模型“豪华套餐”,成了吴恩达最好的生日礼物
    Spring学习笔记11 GoF代理模式
    项目管理之知识管理
    Jmeter 链接MySQL测试
  • 原文地址:https://www.cnblogs.com/chillsrc/p/17502789.html