与上一篇区别在于,详情里面的模板通常是通用的,被定义在样式文件中,被重复使用,因此无法为其添加后台代码,如果能添加后台代码,请翻阅第一篇;所以需要用到命令的方式来辅助事件的抛出,当然还可以利用第三方库Prism,他可以把事件当命令传递,且能传递事件的默认参数,详情请参阅这篇文章;好了,下面开始介绍,扩展DataGrid类,通过自定义命令抛出事件,并传递事件参数...

先请大致看下运行效果:

下面是详情代码,尾部有完整demo,下载

 1 <ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
2 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
3 xmlns:local="clr-namespace:CustomCommand">
4
5 <Style TargetType="DataGrid">
6 <Setter Property="IsReadOnly" Value="True" />
7 <Setter Property="CanUserAddRows" Value="False" />
8 <Setter Property="CanUserDeleteRows" Value="False" />
9 <Setter Property="VirtualizingPanel.ScrollUnit" Value="Pixel" />
10 </Style>
11
12 <!--为了不影响已设置的最基础样式,所以下面这个集成样式很重要-->
13 <Style TargetType="local:CustomDataGrid" BasedOn="{StaticResource {x:Type DataGrid}}" />
14
15 <DataTemplate x:Key="RowDetails">
16 <local:CustomDataGrid ItemsSource="{Binding Infos}"
17 MouseWheelCommand="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=Window},Path=MouseWheelCommand}" />
18 </DataTemplate>
19 </ResourceDictionary>
特别标注下,需要继承默认样式,否则应用到项目中,会区别出异样的
<!--为了不影响已设置的最基础样式,所以下面这个集成样式很重要-->
<Style TargetType="local:CustomDataGrid" BasedOn="{StaticResource {x:Type DataGrid}}" />
 1 using Prism.Commands;
2 using System;
3 using System.Collections.Generic;
4 using System.Collections.ObjectModel;
5 using System.Linq;
6 using System.Text;
7 using System.Threading.Tasks;
8 using System.Windows;
9 using System.Windows.Controls;
10 using System.Windows.Data;
11 using System.Windows.Documents;
12 using System.Windows.Input;
13 using System.Windows.Media;
14 using System.Windows.Media.Imaging;
15 using System.Windows.Navigation;
16 using System.Windows.Shapes;
17
18 namespace CustomCommand
19 {
20 /// <summary>
21 /// MainWindow.xaml 的交互逻辑
22 /// </summary>
23 public partial class MainWindow : Window
24 {
25 /// <summary>
26 /// 鼠标滚动时发送
27 /// </summary>
28 public ICommand MouseWheelCommand { get; private set; }
29
30 public ObservableCollection<Info> Datas = new ObservableCollection<Info>();
31
32 public MainWindow()
33 {
34 MouseWheelCommand = new DelegateCommand<object>(CustomMouseWheel);
35
36 InitializeComponent();
37 datagrid.ItemsSource = Datas;
38
39 for (int i = 0; i < 50; i++)
40 {
41 var info = new Info();
42 info.name = "第一级" + i;
43 Datas.Add(info);
44
45 if (i % 2 == 0)
46 {
47 for (int j = 0; j < 20; j++)
48 {
49 info.Infos.Add(new Info()
50 {
51 name = "第二级" + j
52 });
53 }
54 }
55 }
56 }
57
58
59 /// <summary>
60 /// 当DataGrid的详情行里的DataGrid滚动时发生
61 /// </summary>
62 /// <param name="obj"></param>
63 void CustomMouseWheel(object p)
64 {
65 if (p is MouseWheelEventArgs e)
66 {
67 var sc = GetVisualChild<ScrollViewer>(datagrid);
68 if (sc != null)
69 {
70 sc.ScrollToVerticalOffset(sc.VerticalOffset - e.Delta);
71 }
72 }
73 }
74
75 T GetVisualChild<T>(Visual parent) where T : Visual
76 {
77 T child = default(T);
78 int numVisuals = VisualTreeHelper.GetChildrenCount(parent);
79 for (int i = 0; i < numVisuals; i++)
80 {
81 var v = (Visual)VisualTreeHelper.GetChild(parent, i);
82 child = v as T ?? GetVisualChild<T>(v);
83 if (child != null)
84 break;
85 }
86 return child;
87 }
88 }
89
90 public class Info
91 {
92 public string name { get; set; }
93
94 public ObservableCollection<Info> Infos { get; set; } = new ObservableCollection<Info>();
95 }
96 }
 1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5 using System.Threading.Tasks;
6 using System.Windows;
7 using System.Windows.Controls;
8 using System.Windows.Input;
9
10 namespace CustomCommand
11 {
12 /// <summary>
13 /// 自定义扩展DataGrid 主要是用于响应滚轮事件
14 /// </summary>
15 public class CustomDataGrid : DataGrid
16 {
17 public CustomDataGrid()
18 {
19 PreviewMouseWheel += CustomDataGrid_PreviewMouseWheel;
20 }
21
22 /// <summary>
23 /// 鼠标滚动滚动时
24 /// </summary>
25 /// <param name="sender"></param>
26 /// <param name="e"></param>
27 private void CustomDataGrid_PreviewMouseWheel(object sender, MouseWheelEventArgs e)
28 {
29 MouseWheelCommand?.Execute(e);//触发命令,并把MouseWheelEventArgs传递
30 }
31
32 /// <summary>
33 /// 声明一个用于滚动通知的命令
34 /// </summary>
35 public ICommand MouseWheelCommand
36 {
37 get { return (ICommand)GetValue(MouseWheelCommandProperty); }
38 set { SetValue(MouseWheelCommandProperty, value); }
39 }
40
41 public static readonly DependencyProperty MouseWheelCommandProperty =
42 DependencyProperty.Register("MouseWheelCommand", typeof(ICommand), typeof(CustomDataGrid), new PropertyMetadata(default(ICommand)));
43
44 }
45 }

下面是完整demo,有需要的可以下载

还有的时候,会遇到DataGrid里面嵌套DataGrid(重叠嵌套),然后里面的鼠标滚轮无法响应外面的滚动,为此记录下解决方案的更多相关文章

  1. mybatis的嵌套查询(嵌套查询nested select和嵌套结果nested results查询)区别

    (转自:http://blog.csdn.net/canot/article/details/51485955) Mybatis表现关联关系比hibernate简单,没有分那么细致one-to-man ...

  2. AJPFX实例集合嵌套之ArrayList嵌套ArrayList

    案例:import java.util.ArrayList;import java.util.Iterator;import com.heima.bean.Person;public class De ...

  3. 代码实现集合嵌套之ArrayList嵌套ArrayList

    package com.loaderman.list; import java.util.ArrayList; import com.loaderman.bean.Person; public cla ...

  4. Android ScrollView嵌套ViewPager,嵌套的ViewPager无法显示

    记录:ScrollView嵌套ViewPager,嵌套的ViewPager无法显示 项目中所需要布局:LinearLayout中包含(orientation="vertical") ...

  5. easyui datagrid detailview嵌套datagrid的问题

    解决问题办法来自 http://www.coding123.net/article/20141113/easyui-datagrid-datailview-use-sub-datagrid-not-a ...

  6. C# DataGrid嵌套DataGrid动态隐藏显示行

    前端代码: <Window x:Class="DataGridPractice.MainWindow" xmlns="http://schemas.microsof ...

  7. EasyUI Datagrid Datetime(EasyUI DataGrid 时间格式化)

    EasyUI DataGrid 时间格式化 方法一: var Common = { //EasyUI用DataGrid用日期格式化 TimeFormatter: function (value, re ...

  8. Flex4 中<s:Datagrid>、<mx:Datagrid>添加超链接的完整方法

    <s:Datagrid>的添加超链接方法(链接文字会重叠) <s:GridColumn dataField="_fileName" headerText=&quo ...

  9. extJS4.2.0 Json数据解析,嵌套及非嵌套(二)

    Ext.data.reader.Reader Readers通常用于翻译数据,使其被加载为 Model 实例或Store, 该数据一般是一个AJAX请求的响应数据. 一般情况下不需要直接创建一个Rea ...

  10. angularJs模块ui-router之状态嵌套和视图嵌套

    原文地址:http://bubkoo.com/2014/01/01/angular/ui-router/guide/nested-states%20&%20nested-views/ 状态嵌套 ...

随机推荐

  1. 使用SOUI4中的STreeView控件

    STreeView控件是一个基于虚表技术实现的高性能树形控件. 和STreeCtrl这种传统的树形控件将数据和控件固定在一起不同,STreeView数据和控件分离,使用一个adapter进行连接. 用 ...

  2. 数据存储“取经路”,HBlock轻松“渡”!

    近日,天翼云联合权威科技媒体InfoQ举办了以"新存储,更轻量"为主题的线上技术分享会.天翼云存储产品线总监武志民讲解了HBlock的创新设计和技术. 高性能·高可用·高可靠 自研 ...

  3. pg数据库性能优化(转)

    参数修改的方式 1.修改配置文件 在配置文件data目录下postgresql.conf 中直接修改,修改前记得备份一下原文件.修改完成之后,记得重启数据库哦. 2.命令行的修改方式 ALTER SY ...

  4. 最长不降子序列 n log n 方案输出与 Dilworth 定理 - 动态规划模板

    朴素算法 不必多说,\(O(n^2)\) 的暴力 dp 转移. 优化算法 时间为 \(O(n \log n)\) ,本质是贪心,不是 dp . 思路是维护一个单调栈(手写版),使这个栈单调不降. 当该 ...

  5. 最新demo版 | 如何0-1开发支付宝小程序之小程序页面功能介绍(三)

    前两期讲了小程序开发的准备工作以及前期需要如何调试,今天我们就来介绍下开发一个支付宝小程序页面需要了解哪些信息. 一个小程序页面的整体功能的构成离不开页面展示(AXML).页面样式(ACSS)以及页面 ...

  6. Vue 页面批量导入其他组件

    <template> <div> <template v-for="(item) in names"> <component :is=&q ...

  7. DW - 问题

    数据库三范式 1NF(First Normal Form):一个关系模式符合 1NF 的定义,则该关系模式是简单的.简单的意思就是不存在从属或重复的属性,即每个属性都是原子性的. 2NF(Second ...

  8. Python基础-模块和面向对象-shutil、re、bs4、requests模块

    概要: 模块 自定义模块(已经讲了) 内置模块 shutil re 正则表达式 第三方模块 requests 模块 bs4 模块 面向对象: 面向对象(Object-Oriented Programm ...

  9. c# 使用 Read 读取数据块

    class Program { static void Main(string[] args) { Stream s = new MemoryStream(); for (int i = 0; i & ...

  10. Windows编程----内核对象竟然如此简单?

    什么是内核对象 内核对象本质上就是内存中的一块内存 ,这块内存由操作系统进行管理和分配,任何应用程序都无法直接操作这块内存区域.至于内核对象的作用,我们暂且不说,这里只需要直到它是内存中的一块内存. ...