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. https://learn.microsoft.com/en-us/dotnet/api/system.windows.controls.datagrid.rowheaderstyle?view=windowsdesktop-8.0WPF DataGrid Custommization using Style and Template - CodeProject