WPF入门教程系列二十九 ——DataGrid使用示例MVVM模式(7)
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}" />
private static ObservableCollection<City> cityList;
public static ObservableCollection<City> GridCityList
{ get { return cityList; }
set
{ cityList = value;
new ViewModelBase().RaisePropertyChanged("GridCityList");
} }

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<City> listCity;
public ObservableCollection<City> 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>
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>(); listCity = new ObservableCollection<City>(); } 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 static ObservableCollection<City> cityList; public static ObservableCollection<City> GridCityList
{ get { return cityList; } set
{
cityList = value;
new ViewModelBase().RaisePropertyChanged("GridCityList");
}
} private ObservableCollection<City> listCity; public ObservableCollection<City> GridCity {
get { return listCity; }
set {
listCity = value;
RaisePropertyChanged("GridCity");
} } /// <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); } );
}
listCity.Clear(); if (citys != null) { citys.ForEach((t) => { listCity.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); }
}
}
}
22.在Visual Studio 2022中按F5键,启动WPF应用程序。然后使用鼠标点击省份下拉框,能够看到,界面中DataGrid中的数据,随着下拉框的变化而随之变化,其中使用静态实体代码绑定的城市下拉框中却没有任何数据。使用使用非静态资源,在<DataGridComboBoxColumn.EditingElementStyle>与 <DataGridComboBoxColumn.ElementStyle>两个样式中绑定combobox的itemSource属性方式,效果有效。如下图。

WPF入门教程系列二十九 ——DataGrid使用示例MVVM模式(7)的更多相关文章
- WPF入门教程系列二十二——DataGrid示例(二)
DataGrid示例的后台代码 1) 通过Entity Framework 6.1 从数据库(本地数据库(local)/Test中的S_City表中读取城市信息数据,从S_ Province表中读取 ...
- WPF入门教程系列二十——ListView示例(二)
第四步.WPF后台逻辑代码编写 在后台用Entity Framework 6.1的Code First方式获取数据库中的数据.同时,在“刷新”按钮的方法中进行数据绑定.操作步骤如下: 1) 在“刷新 ...
- WPF入门教程系列二十三——DataGrid示例(三)
DataGrid的选择模式 默认情况下,DataGrid 的选择模式为“全行选择”,并且可以同时选择多行(如下图所示),我们可以通过SelectionMode 和SelectionUnit 属性来修改 ...
- WPF入门教程系列(二) 深入剖析WPF Binding的使用方法
WPF入门教程系列(二) 深入剖析WPF Binding的使用方法 同一个对象(特指System.Windows.DependencyObject的子类)的同一种属性(特指DependencyProp ...
- WPF入门教程系列二——Application介绍
一.Application介绍 WPF和WinForm 很相似, WPF与WinForm一样有一个 Application对象来进行一些全局的行为和操作,并且每个 Domain (应用程序域)中仅且只 ...
- WPF入门教程系列二十一——DataGrid示例(一)
前面我们学习了ListView控件的使用示例,今天我们来学习DataGrid的有关知识.提到DataGrid 不管是Asp.Net中的网页开发还是WinForm应用程序开发都会频繁使用.通过它我们可以 ...
- WPF入门教程系列二
WPF控件和布局 一. 前言 公司项目基于WPF开发,最近项目上线有点空闲时间写一篇基于wpf的基础教材,WPF也是近期才接触,学习WPF也是在网上查资料与微软的MSDN进行学习,写本博客的目为了 ...
- WPF入门教程系列三——Application介绍(续)
接上文WPF入门教程系列二——Application介绍,我们继续来学习Application 三.WPF应用程序的关闭 WPF应用程序的关闭只有在应用程序的 Shutdown 方法被调用时,应用程序 ...
- Web 开发人员和设计师必读文章推荐【系列二十九】
<Web 前端开发精华文章推荐>2014年第8期(总第29期)和大家见面了.梦想天空博客关注 前端开发 技术,分享各类能够提升网站用户体验的优秀 jQuery 插件,展示前沿的 HTML5 ...
- WPF入门教程系列(一) 创建你的第一个WPF项目
WPF入门教程系列(一) 创建你的第一个WPF项目 WPF基础知识 快速学习绝不是从零学起的,良好的基础是快速入手的关键,下面先为大家摞列以下自己总结的学习WPF的几点基础知识: 1) C#基础语法知 ...
随机推荐
- list Api
类型 名称 void add(String item)将指定的项目添加到滚动列表的末尾. void add(String item, int index)将指定的项目添加到由索引指示的位置的滚动列表中 ...
- data.frame数据框操作——R语言
统计分析中最常见的原始数据形式是类似于数据库表或Excel数据表的形式. 这样形式的数据在R中叫做数据框(data.frame). 数据框类似于一个矩阵,但各列允许有不同类型:数值型向量.因子.字符型 ...
- CentOS&RHEL内核升级
在安装部署一些环境的时候,会要求内核版本的要求,可以通过YUM工具进行安装配置更高版本的内核,当然更新内核有风险,在操作之前慎重,严谨在生产环境操作! 安装源 # 为 RHEL-8或 CentOS-8 ...
- python入门教程之二环境搭建
环境搭建 1python解释器 当我们编写Python代码时,我们得到的是一个包含Python代码的以.py为扩展名的文本文件.要运行代码,就需要Python解释器去执行.py文件. 由于整个Pyth ...
- 五月十五日java基础知识点
1.匿名内部类适用于编写事件程序 interface Ishape{ void shape(); } class MyType{ public void outShape(Ishape s){//接口 ...
- day06-SpringCloud Ribbon
SpringCloud Ribbon 1.Ribbon介绍 1.1Ribbon是什么? 官网地址:Netflix/ribbon: Ribbon(github.com) SpringCloud Ribb ...
- Sphinx 配置文件说明
一. 创建sphinx.conf文件 其结构组成主要如下: Source 源名称1{ //指定数据源 一些配置 } Index 索引名称1{ Source=源名称1 ...
- Vulnhub Joy Walkthrough
Recon 这台靶机对枚举的要求较高,如果枚举不出有用的信息可能无法进一步展开,我们首先进行普通的扫描. ┌──(kali㉿kali)-[~/Labs/Joy/80] └─$ sudo nmap -s ...
- 【Java Se】JDBC
启停服务 net start mysql net stop mysql 登录 mysql -u -p 访问指定IP的mysql mysql -u root -P 3306 -h localhost - ...
- 【必知必会的MySQL知识】⑤DQL语言
目录 一.前言 二.基础查询 2.1 语法 2.2 实践操作 三.条件查询 3.1 语法 3.2 where 语句操作符 3.3 实践操作 四.排序查询 4.1 语法格式 4.2 实践操作 五.分组查 ...