本文记录在 dotnet 7 下的 WPF 的一个破坏性改动。在 dotnet 7 下的 WPF 支持 DataGrid 在按下 F3 键的时候,自动按照当前所选列进行列自动排序。这将会让原本采用 F3 键进行其他业务逻辑的代码,工作起来有些非预期

此破坏改动是在此需求提出的: https://github.com/dotnet/wpf/issues/6737

在此代码提交里面更改的: https://github.com/dotnet/wpf/pull/6873

行为上就是在 DataGrid 获取选中和键盘焦点时,按下 F3 键,将会根据当前选中的列作为排序依据,进行排序。内核实现代码也非常简单,从 https://github.com/dotnet/wpf/pull/6873 更改里面可以看到只有几句代码

                else if(e.Key == Key.F3)
{
if (Column.CanUserSort)
{
Column.DataGridOwner.PerformSort(Column);
e.Handled = true;
return;
}
}

此行为是在 dotnet 7 引入的,可以写一点测试代码来确认。先创建一个 WPF 的 dotnet 7 项目,再编辑 csproj 项目文件,设置为支持 dotnet 6 和 dotnet 7 两个框架。多框架的设置详细请看 让一个 csproj 项目指定多个开发框架 - walterlv

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFrameworks>net6.0-windows;net7.0-windows</TargetFrameworks>
<Nullable>enable</Nullable>
<UseWPF>true</UseWPF>
</PropertyGroup> </Project>

接着写一点后台代码用来生成测试数据,代码如下

public partial class MainWindow : Window
{
public MainWindow()
{
for (int i = 0; i < 100; i++)
{
ModelList.Add(new Model());
} InitializeComponent();
} public ObservableCollection<Model> ModelList { get; } = new ObservableCollection<Model>();
} public class Model
{
public Model()
{
Name = "Name_" + _count;
Description = "Description_" + _count;
Number = _count; _count++;
} public string Name { get; set; }
public string Description { get; set; }
public int Number { get; set; } private static int _count;
}

接着在 XAML 上新建一个 DataGrid 使用数据

<Window x:Class="ChehicemkeNedearfabulemni.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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:ChehicemkeNedearfabulemni"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800"
x:Name="Root">
<Grid>
<DataGrid ItemsSource="{Binding ElementName=Root,Path=ModelList}"> </DataGrid>
</Grid>
</Window>

尝试切换到 dotnet 7 框架,然后运行项目,接着随意选中一项,按下 F3 键,可以看到 DataGrid 被自动排序

尝试切换到 dotnet 6 框架,执行以上步骤,可以看到按下 F3 键,啥都没有发生

这就是 dotnet 7 在 WPF 引入的一个破坏性变更

如果不想要此功能,可以自己通过路由事件吃掉 F3 键,从而不让 DataGrid 排序

    protected override void OnPreviewKeyDown(KeyEventArgs e)
{
if (e.Key == Key.F3)
{
// 自己的业务 e.Handled = true;
return;
} base.OnPreviewKeyDown(e);
}

值得一说的是,在 WPF 里面的这个改动本来是为了保持 Windows 的统一性行为。然而在此更改合入 dotnet 7 发布之后,不出意外,有大佬来开喷了

I understand the change, but why would you add such stuff that reworks the normal usage of F3. F3 is for search in windows platform, if you wanted to add something like this, you could have added a property to disable that behavior.

We also have tri-level multi-column sort on the grid implemented and of course we do not want a keyboard shortcut for it. We have a button and a UI for it.

How about you also apply CTRL + S to close the grid or print preview the grid? Will that make sense, when common use case on all windows applications for CTRL + S is to save?

Please tell me know can I trap this, but bubble it up the chain so main window's F3 will work correctly?

更多请看 Wpf DataGrid in .NET7 takes away F3 and automatically sorts. - Breaking change. · Issue #7288 · dotnet/wpf

我认为在 WPF 这么大的体量下,功能性改动,还是需要谨慎一些的,毕竟众口难调。能使用外部对接的,就尽量不要直接加在框架内。但也有一群人想着在框架内加入各种原本可以在第三方库简单就能实现的功能… 这些都是难以抉择的。因为很难有一些功能让大家都喜欢,特别是一些有选择性的变更,选了 A 一定就会让期望 B 的开发者伤心

现在的 WPF 开发团队还是很能听进话的,在经过了一场激烈的战斗之后,大家都同意这个功能在下个更改版本里面,使用开关控制打开。默认是打开,可以通过开关关闭,而不需要通过本文如此 Hack 的方法关闭

详细请看 https://github.com/dotnet/wpf/pull/7297

本文的代码放在githubgitee 欢迎访问

可以通过如下方式获取本文的源代码,先创建一个空文件夹,接着使用命令行 cd 命令进入此空文件夹,在命令行里面输入以下代码,即可获取到本文的代码

git init
git remote add origin https://gitee.com/lindexi/lindexi_gd.git
git pull origin 7324f2b12ce498736917f08c9301c31fec455d54

以上使用的是 gitee 的源,如果 gitee 不能访问,请替换为 github 的源。请在命令行继续输入以下代码

git remote remove origin
git remote add origin https://github.com/lindexi/lindexi_gd.git
git pull origin 7324f2b12ce498736917f08c9301c31fec455d54

获取代码之后,进入 ChehicemkeNedearfabulemni 文件夹

更多 WPF 相关博客,请参阅我的 博客导航

dotnet 7 WPF 破坏性改动 按下 F3 让 DataGrid 自动排序的更多相关文章

  1. 在EXCEL带有字母的数字下拉如何能自动排序

    在excel中0,1,2,3,4,5,6,7,8,9会自动排序,a,b,c,d,e,f,g.....会自动排序,所以可以分布来实现. 例如排序:fish1a.png,fish1b.png,fish1c ...

  2. WPF老矣,尚能饭否——且说说WPF今生未来(下):安心

    在前面的上.中篇中,我们已经可以看到园子里朋友的点评“后山见! WPF就比winform好! 激情对决”.看到大家热情洋溢的点评,做技术的我也很受感动.老实说,如何在本文收笔--WPF系列文章,我很紧 ...

  3. C# WPF Image控件下对于Base64的转化显示

    原文:C# WPF Image控件下对于Base64的转化显示 算作前言 本文对图片如何转化成base64不做描述,我们可以从很多途径了解到转化办法.却很少有博客提到怎么在WPF的Image控件中显示 ...

  4. [WPF]获取鼠标指针下的元素

    原文:[WPF]获取鼠标指针下的元素   [WPF]获取鼠标指针下的元素 周银辉 以前写过一些GetElementUnderMouse之类的函数,要用到坐标换算而显得有些麻烦(特别是当元素有XXXTr ...

  5. dotnet 读 WPF 源代码笔记 布局时 Arrange 如何影响元素渲染坐标

    大家是否好奇,在 WPF 里面,对 UIElement 重写 OnRender 方法进行渲染的内容,是如何受到上层容器控件的布局而进行坐标偏移.如有两个放入到 StackPanel 的自定义 UIEl ...

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

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

  7. WPF DataGrid自动生成行号

      在使用WPF进行应用程序的开发时,经常会为DataGrid生成行号,这里主要介绍一下生成行号的方法.通常有三种方法,这里主要介绍其中的两种,另一种简单提一下. 1. 直接在LoadingRow事件 ...

  8. Linux下Jenkins与GitHub自动构建NetCore与部署

    今天我们来谈谈NetCore在Linux底下的持续集成与部署.NetCore我就不多介绍了,持续集成用的是Jenkins,源代码管理器用的是GitHub.我们就跟着博文往下走吧. 1.Linux环境 ...

  9. # .NET Core下操作Git,自动提交代码到

    .NET Core下操作Git,自动提交代码到 转自博客园(阿星Plus) .NET Core 3.0 预览版发布已经好些时日了,博客园也已将其用于生产环境中,可见 .NET Core 日趋成熟 回归 ...

  10. Windows环境下Oracle数据库的自动备份脚本

    批处理文件(.bat) @echo off echo ================================================ echo  Windows环境下Oracle数据 ...

随机推荐

  1. FreeRTOS教程7 事件组

    1.准备材料 正点原子stm32f407探索者开发板V2.4 STM32CubeMX软件(Version 6.10.0) Keil µVision5 IDE(MDK-Arm) 野火DAP仿真器 XCO ...

  2. Java原生序列化与反序列化

    序列化与反序列化 Java序列化是指把Java对象转换为字节序列的过程;而Java反序列化是指把字节序列恢复为Java对象的过程. 为什么需要序列化? 序列化分为两大部分:序列化和反序列化.序列化是这 ...

  3. vue初学核心基础

    一.初识vue 1.vue的使用 导入vue之后创建vue模块,el属性表示控制区域的id名称,data表示该区域内的数据 在vue中我们都是用表中模板的标准语法来传递数据 <head> ...

  4. C#人脸对比服务(基于虹软人脸识别SDKV4.1封装)

    软件截图   项目截图 部分代码 using System; using System.Collections.Generic; using System.Linq; using System.Tex ...

  5. dotnet转换webservice返回的dataset

    string paras = "p1=test1&p2=test2";//参数 byte[] bytes = Encoding.UTF8.GetBytes(paras); ...

  6. KingbaseES V8R6 等待事件之DataFileRead

    等待事件含义 IO:DataFileRead等待事件发生在会话连接等待后端进程从存储中读取所需页面,原因是该页面在共享内存中不可用或无法找到. 所有查询和数据操作(DML)操作都访问缓冲池中的页面,语 ...

  7. KingbaseES 控制文件损坏的恢复

    sys_ control文件损坏: 需要手工指定一些参数完成sys_resetwal相关操作 当前数据库信息 test=# \d 关联列表 架构模式 | 名称 | 类型 | 拥有者 --------- ...

  8. Python爬虫爬取ECCV Conference Papers(一)

    爬取到2020年所有论文标题 代码: 1 import re 2 import requests 3 from bs4 import BeautifulSoup 4 import lxml 5 imp ...

  9. SQL 数据库语句- 创建和管理数据库

    SQL CREATE DATABASE 语句 SQL CREATE DATABASE 语句用于创建一个新的 SQL 数据库. 语法 CREATE DATABASE 数据库名称; 示例 以下 SQL 语 ...

  10. 灵活配置 Spring 集合:List、Set、Map、Properties 详解

    使用<property>标签的value属性配置原始数据类型和ref属性配置对象引用的方式来定义Bean配置文件.这两种情况都涉及将单一值传递给Bean 那么如果您想传递多个值,例如Jav ...