Datagrid Row Index Demo

该代码示例实现了一个名为`ConvertItemToIndex`的转换器,用于将DataGrid中的项目转换为其索引,并在行头显示。它使用`VisualTreeHelpers`静态类来查找DataGrid实例。转换器在绑定中使用,将行对象转换为显示的行号。此外,文章还展示了如何自定义DataGrid的行头样式来展示这些索引。
摘要由CSDN通过智能技术生成
namespace Demo
{
    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Media;

    public class ConvertItemToIndex : IValueConverter
    {
        /// <summary>
        /// Convert the Item to an Index
        /// </summary>
        /// <param name="value"></param>
        /// <param name="targetType"></param>
        /// <param name="parameter"></param>
        /// <param name="culture"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            try
            {
                // Get the CollectionView from the DataGrid that is using the converter
                var dg = VisualTreeHelpers.FindChild<DataGrid>(System.Windows.Application.Current.MainWindow, "DG1");
                if (dg is null)
                {
                    return 0;
                }

                // DataGrid dg = (DataGrid)System.Windows.Application.Current.MainWindow.FindName("DG1");
                CollectionView cv = dg.Items;

                // Get the index of the item from the CollectionView
                int rowindex = cv.IndexOf(value) + 1;

                return $"{rowindex}";
            }
            catch (Exception e)
            {
                throw new NotImplementedException(e.Message);
            }
        }

        /// <summary>
        /// One way binding, so ConvertBack is not implemented
        /// </summary>
        /// <param name="value"></param>
        /// <param name="targetType"></param>
        /// <param name="parameter"></param>
        /// <param name="culture"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
}
namespace Demo
{
    using System.Windows;
    using System.Windows.Media;

    public static class VisualTreeHelpers
    {
        /// <summary>
        /// Returns the first ancester of specified type
        /// </summary>
        public static T? FindAncestor<T>(DependencyObject current)
        where T : DependencyObject
        {
            current = VisualTreeHelper.GetParent(current);

            while (current != null)
            {
                if (current is T)
                {
                    return (T?)current;
                }

                current = VisualTreeHelper.GetParent(current);
            }

            return null;
        }

        /// <summary>
        /// Returns a specific ancester of an object
        /// </summary>
        public static T? FindAncestor<T>(DependencyObject current, T lookupItem)
        where T : DependencyObject
        {
            while (current != null)
            {
                if (current is T && current == lookupItem)
                {
                    return (T?)current;
                }

                current = VisualTreeHelper.GetParent(current);
            }

            return null;
        }

        /// <summary>
        /// Finds an ancestor object by name and type
        /// </summary>
        public static T? FindAncestor<T>(DependencyObject current, string parentName)
        where T : DependencyObject
        {
            while (current != null)
            {
                if (!string.IsNullOrEmpty(parentName))
                {
                    var frameworkElement = current as FrameworkElement;
                    if (current is T && frameworkElement != null && frameworkElement.Name == parentName)
                    {
                        return (T?)current;
                    }
                }
                else if (current is T t)
                {
                    return t;
                }

                current = VisualTreeHelper.GetParent(current);
            }

            return null;
        }

        /// <summary>
        /// Looks for a child control within a parent by name
        /// </summary>
        public static T? FindChild<T>(DependencyObject parent, string childName)
        where T : DependencyObject
        {
            // Confirm parent and childName are valid.
            if (parent is null)
            {
                return null;
            }

            T? foundChild = null;

            int childrenCount = VisualTreeHelper.GetChildrenCount(parent);
            for (int i = 0; i < childrenCount; i++)
            {
                var child = VisualTreeHelper.GetChild(parent, i);

                // If the child is not of the request child type child
                if (child is not T childType)
                {
                    // recursively drill down the tree
                    foundChild = FindChild<T>(child, childName);

                    // If the child is found, break so we do not overwrite the found child.
                    if (foundChild != null)
                    {
                        break;
                    }
                }
                else if (!string.IsNullOrEmpty(childName))
                {
                    // If the child's name is set for search
                    if (child is FrameworkElement frameworkElement && frameworkElement.Name == childName)
                    {
                        // if the child's name is of the request name
                        foundChild = (T)child;
                        break;
                    }
                    else
                    {
                        // recursively drill down the tree
                        foundChild = FindChild<T>(child, childName);

                        // If the child is found, break so we do not overwrite the found child.
                        if (foundChild != null)
                        {
                            break;
                        }
                    }
                }
                else
                {
                    // child element found.
                    foundChild = (T)child;
                    break;
                }
            }

            return foundChild;
        }

        /// <summary>
        /// Looks for a child control within a parent by type
        /// </summary>
        public static T? FindChild<T>(DependencyObject parent)
            where T : DependencyObject
        {
            // Confirm parent is valid.
            if (parent is null)
            {
                return null;
            }

            T? foundChild = null;

            int childrenCount = VisualTreeHelper.GetChildrenCount(parent);
            for (int i = 0; i < childrenCount; i++)
            {
                var child = VisualTreeHelper.GetChild(parent, i);

                // If the child is not of the request child type child
                if (child is not T childType)
                {
                    // recursively drill down the tree
                    foundChild = FindChild<T>(child);

                    // If the child is found, break so we do not overwrite the found child.
                    if (foundChild != null)
                    {
                        break;
                    }
                }
                else
                {
                    // child element found.
                    foundChild = (T?)child;
                    break;
                }
            }

            return foundChild;
        }
    }
}
<!--  ReSharper disable UnusedMember.Global  -->
<UserControl x:Class="Demo.RowNumbersView"
             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:dataGrid2D="http://gu.se/DataGrid2D"
             xmlns:local="clr-namespace:Demo"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             mc:Ignorable="d" Name="UserC">
    <UserControl.Resources>
        <local:ConvertItemToIndex x:Key="IndexConverter"/>
    </UserControl.Resources>
    <UserControl.DataContext>
        <local:RowNumbersVm />
        
    </UserControl.DataContext>
    <DataGrid x:Name="DG1" dataGrid2D:Index.StartAt="11" ItemsSource="{Binding Persons}" VirtualizingPanel.IsVirtualizing="True" VirtualizingPanel.VirtualizationMode="Recycling" VirtualizingPanel.IsContainerVirtualizable="True">
        <DataGrid.RowHeaderStyle>
            <Style TargetType="{x:Type DataGridRowHeader}">          
                <Setter Property="Content" Value="{Binding Converter={StaticResource IndexConverter}}" />
            </Style>
        </DataGrid.RowHeaderStyle>
    </DataGrid>
</UserControl>

DataGrid.RowHeaderStyle Property (System.Windows.Controls) | Microsoft LearnGets or sets the style applied to all row headers. icon-default.png?t=N3I4https://learn.microsoft.com/en-us/dotnet/api/system.windows.controls.datagrid.rowheaderstyle?view=windowsdesktop-8.0WPF DataGrid Custommization using Style and Template - CodeProject

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值