• Silverlight DataGrid 获取 Row 左键双击事件


    今天需要做 DataGrid 双击后弹出一个窗口的功能。突然发现 DataGrid 这东西很蛋疼,本身不支持也就罢了,还有更恶心的。比如 DataGrid 不能被继承,再比如 DataGridCell 中 Handle 了 MouseLeftButtonDown 事件。

    于是,只好走点弯路。自己创建了一个 DataGridHelper

    namespace SoftCat.Windows.Controls
    {
        using System.Windows;
        using System.Windows.Controls;
        using System.Windows.Input;
        using System.Windows.Media;
    
        public class DataGridHelper
        {
            // ===================================================================
            // 字段
    
            DataGrid _dg;
    
            // ===================================================================
            // 构造与析构
    
            public DataGridHelper(DataGrid dg)
            {
                _dg = dg;
    
                _dg.LoadingRow += _dg_LoadingRow;
            }
    
            // ===================================================================
            // 事件处理
    
            void _dg_LoadingRow(object sender, DataGridRowEventArgs e)
            {
                e.Row.Loaded += Row_Loaded;
            }
    
            private void Row_Loaded(object sender, RoutedEventArgs e)
            {
                DataGridRow row = sender as DataGridRow;
    
                foreach (DataGridCell cell in VisualTreeHelperEx.FindChildren<DataGridCell>(row))
                {
                    Grid cellGrid = VisualTreeHelper.GetChild(cell, 0) as Grid;
                    cellGrid.MouseLeftButtonDown += cellGrid_MouseLeftButtonDown;
                }
            }
    
            private void cellGrid_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
            {
                if (RowMouseLeftButtonDown == null && CellMouseLeftButtonDown == null) return;
    
                Grid cellGrid = sender as Grid;
                DataGridCell cell = VisualTreeHelper.GetParent(cellGrid) as DataGridCell;
    
                if (CellMouseLeftButtonDown != null)
                    CellMouseLeftButtonDown(cell, e);
    
                if (RowMouseLeftButtonDown != null)
                {
                    DataGridRow row = VisualTreeHelperEx.FindParent<DataGridRow>(cell);
                    RowMouseLeftButtonDown(row, e);
                }
            }
    
            // ===================================================================
            // 扩展事件
    
            public event MouseButtonEventHandler RowMouseLeftButtonDown;
    
            public event MouseButtonEventHandler CellMouseLeftButtonDown;
    
        }
    }

    上面的这段代码为了突出重点,省去了左键 Up 和右键事件,需要者可以自行添加。

    请注意,DataGridCell 的子节点是一个 Grid,我们通过这个 Grid 的 MouseLeftButtonDown 事件捕获到我们需要的行为,然后再转嫁给 DataGridCell 和 DataGridRow。

    这是一种投机取巧的行为,但不失为一种万不得已的方法。

    此外,上面的代码中使用了我自己写的 VisualTreeHelperEx,代码如下。

    namespace SoftCat.Windows
    {
        using System;
        using System.Collections.Generic;
        using System.Windows;
        using System.Windows.Media;
    
        public static class VisualTreeHelperEx
        {
            public static IEnumerable<T> FindChildren<T>(DependencyObject reference) where T : DependencyObject
            {
                if (reference == null) throw new ArgumentNullException();
    
                Queue<DependencyObject> q = new Queue<DependencyObject>();
    
                int c = VisualTreeHelper.GetChildrenCount(reference);
    
                for (int i = 0; i < c; i++)
                {
                    DependencyObject o = VisualTreeHelper.GetChild(reference, i);
                    q.Enqueue(o);
                }
    
                while (q.Count > 0)
                {
                    DependencyObject r = q.Dequeue();
    
                    if (r is T)
                    {
                        yield return r as T;
                    }
                    else
                    {
                        c = VisualTreeHelper.GetChildrenCount(r);
    
                        for (int i = 0; i < c; i++)
                        {
                            DependencyObject o = VisualTreeHelper.GetChild(r, i);
                            q.Enqueue(o);
                        }
                    }
                }
            }
    
            public static T FindParent<T>(DependencyObject reference) where T : DependencyObject
            {
                if (reference == null) throw new ArgumentNullException();
    
                DependencyObject p = reference;
    
                do
                {
                    p = VisualTreeHelper.GetParent(p);
    
                    if (p is T)
                    {
                        return p as T;
                    }
                }
                while (p != null);
    
                return null;
            }
    
        }
    }

    希望这篇文章能给您带来一些小小的启发。如果有更好的方法还请告知,谢谢!

  • 相关阅读:
    /etc/init.d/functions: No such file or directory报错问题
    在Linux上安装Python3.7.1
    python 使用openpyxl实现读写xlsx文件
    Git 撤销本地修改
    element的el-table表格自定义表头,slot="header"内,数据不更新的问题
    记录下本地修改文件名称大小写问题线上说找不到文件
    解决国内访问github慢的问题笔记
    vue项目中使用echarts实现疫情地图
    uni-app项目搭建
    uniapp引入uni-ui组件报错TypeError: this.getOptions is not a function
  • 原文地址:https://www.cnblogs.com/softcat/p/2788230.html
Copyright © 2020-2023  润新知