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<City> cityList;
public static ObservableCollection<City> 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<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>
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<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)的更多相关文章

  1. WPF入门教程系列二十二——DataGrid示例(二)

    DataGrid示例的后台代码 1)  通过Entity Framework 6.1 从数据库(本地数据库(local)/Test中的S_City表中读取城市信息数据,从S_ Province表中读取 ...

  2. WPF入门教程系列二十——ListView示例(二)

    第四步.WPF后台逻辑代码编写 在后台用Entity Framework 6.1的Code First方式获取数据库中的数据.同时,在“刷新”按钮的方法中进行数据绑定.操作步骤如下: 1)  在“刷新 ...

  3. WPF入门教程系列二十三——DataGrid示例(三)

    DataGrid的选择模式 默认情况下,DataGrid 的选择模式为“全行选择”,并且可以同时选择多行(如下图所示),我们可以通过SelectionMode 和SelectionUnit 属性来修改 ...

  4. WPF入门教程系列(二) 深入剖析WPF Binding的使用方法

    WPF入门教程系列(二) 深入剖析WPF Binding的使用方法 同一个对象(特指System.Windows.DependencyObject的子类)的同一种属性(特指DependencyProp ...

  5. WPF入门教程系列二——Application介绍

    一.Application介绍 WPF和WinForm 很相似, WPF与WinForm一样有一个 Application对象来进行一些全局的行为和操作,并且每个 Domain (应用程序域)中仅且只 ...

  6. WPF入门教程系列二十一——DataGrid示例(一)

    前面我们学习了ListView控件的使用示例,今天我们来学习DataGrid的有关知识.提到DataGrid 不管是Asp.Net中的网页开发还是WinForm应用程序开发都会频繁使用.通过它我们可以 ...

  7. WPF入门教程系列二

    WPF控件和布局 一.  前言  公司项目基于WPF开发,最近项目上线有点空闲时间写一篇基于wpf的基础教材,WPF也是近期才接触,学习WPF也是在网上查资料与微软的MSDN进行学习,写本博客的目为了 ...

  8. WPF入门教程系列三——Application介绍(续)

    接上文WPF入门教程系列二——Application介绍,我们继续来学习Application 三.WPF应用程序的关闭 WPF应用程序的关闭只有在应用程序的 Shutdown 方法被调用时,应用程序 ...

  9. Web 开发人员和设计师必读文章推荐【系列二十九】

    <Web 前端开发精华文章推荐>2014年第8期(总第29期)和大家见面了.梦想天空博客关注 前端开发 技术,分享各类能够提升网站用户体验的优秀 jQuery 插件,展示前沿的 HTML5 ...

  10. WPF入门教程系列(一) 创建你的第一个WPF项目

    WPF入门教程系列(一) 创建你的第一个WPF项目 WPF基础知识 快速学习绝不是从零学起的,良好的基础是快速入手的关键,下面先为大家摞列以下自己总结的学习WPF的几点基础知识: 1) C#基础语法知 ...

随机推荐

  1. R语言文本数据挖掘(一)

    文本挖掘可以视为NLP(Natural language processing,自然语言处理)的一个子领域,目标是在大量非结构化文本中整理析取出有价值的内容.由于人类语言具有很高的复杂性,例如不同语言 ...

  2. pandas之分组操作

    在数据分析中,经常会遇到这样的情况:根据某一列(或多列)标签把数据划分为不同的组别,然后再对其进行数据分析.比如,某网站对注册用户的性别或者年龄等进行分组,从而研究出网站用户的画像(特点).在 Pan ...

  3. 9.springSecurity整合OAuth2结合Jwt实现单点登录

    1.总结:昨天主要是继续完善OAuth2配合将问题完成单点登录,昨天也应证了一个认证服务,两个客户端服务在登陆一次后可以访问两个客户端的页面,也算是完成了单点登录   2.具体实现 首先是使用java ...

  4. group_concat_max_len设置过小致group_concat()排列不全

    问题描述:group_concat_max_len默认值1024导致group_concat函数排列显示不足 group_concat_max_len长度显示跟group_concat排列长度息息相关 ...

  5. openwrt开发使用-arping

    前言 IP冲突引起的网络异常,可以通过检查IP是否冲突,排除故障.我们可以用一些工具进行检查,例如arp-scan.arping软件进行查看. 这里使用arping进行检查设备的MAC地址,通过查查看 ...

  6. Go语言网络编程: 模拟实现DNS服务器

    环境: 两台虚拟机,不限系统 写在前面 DNS服务器是干什么的?DNS服务器(Domain Name Server,域名服务器)是进行域名和与之相对应的IP地址进行转换的服务器,保存了一张域名和与之相 ...

  7. 深度学习基础5:交叉熵损失函数、MSE、CTC损失适用于字识别语音等序列问题、Balanced L1 Loss适用于目标检测

    深度学习基础5:交叉熵损失函数.MSE.CTC损失适用于字识别语音等序列问题.Balanced L1 Loss适用于目标检测 1.交叉熵损失函数 在物理学中,"熵"被用来表示热力学 ...

  8. 快速上手Linux核心命令(一):核心命令简介

    前言 众所周知,Linux在服务器中占用不可替代的位置.大多数互联网公司,服务器都是采用的Linux操作系统.而Linux是一个主要通过命令行来进行管理的操作系统.只有熟练掌握Linux核心命令,在使 ...

  9. MKL稀疏矩阵运算示例及函数封装

    Intel MKL库提供了大量优化程度高.效率快的稀疏矩阵算法,使用MKL库的将大型矩阵进行稀疏表示后,利用稀疏矩阵运算可大量节省计算时间和空间,但由于MKL中的原生API接口繁杂,因此将常用函数封装 ...

  10. 响应式的 switchboard:让又大又慢的Vue/AIpine 页面爆快

    我的提示: AIpine 是一个js 库,官网口号是 "一个新的轻量极javascript框架",其实我之前也没接触过,翻译这篇文章时才注意到 官方地址: [AIpine.js]h ...