It was complicated. My idea would be to create an adorner that will be responsible for drawing the various lines you need. I do not like to create unnecessary string objects.
Here is an initial example (there are still some glitches and it needs to be set up, but I think this is a good start.)
Xaml
<Window x:Class="WpfApplication11.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:sys="clr-namespace:System;assembly=mscorlib" xmlns:local="clr-namespace:WpfApplication11" Title="MainWindow" Height="350" Width="525"> <local:MyDataGrid HeadersVisibility="Column"> <local:MyDataGrid.Columns> <DataGridTextColumn Header="Column 123" Binding="{Binding}" /> <DataGridTextColumn Header="Column 2" Binding="{Binding}" /> <DataGridTextColumn Header="Column 33333333333333333333333" Binding="{Binding}" /> </local:MyDataGrid.Columns> <sys:String>Row</sys:String> <sys:String>Row</sys:String> </local:MyDataGrid> </Window>
Control code
public static class Visual_ExtensionMethods { public static T FindDescendant<T>(this Visual @this, Predicate<T> predicate = null) where T : Visual { return @this.FindDescendant(v => v is T && (predicate == null || predicate((T)v))) as T; } public static Visual FindDescendant(this Visual @this, Predicate<Visual> predicate) { if (@this == null) return null; var frameworkElement = @this as FrameworkElement; if (frameworkElement != null) { frameworkElement.ApplyTemplate(); } Visual child = null; for (int i = 0, count = VisualTreeHelper.GetChildrenCount(@this); i < count; i++) { child = VisualTreeHelper.GetChild(@this, i) as Visual; if (predicate(child)) return child; child = child.FindDescendant(predicate); if (child != null) return child; } return child; } } public class GridAdorner : Adorner { public GridAdorner(MyDataGrid dataGrid) : base(dataGrid) { dataGrid.LayoutUpdated += new EventHandler(dataGrid_LayoutUpdated); } void dataGrid_LayoutUpdated(object sender, EventArgs e) { InvalidateVisual(); } protected override void OnRender(DrawingContext drawingContext) { base.OnRender(drawingContext); var myDataGrid = AdornedElement as MyDataGrid; if (myDataGrid == null) throw new InvalidOperationException();
This particular piece of code
void dataGrid_LayoutUpdated(object sender, EventArgs e) { InvalidateVisual(); }
you really don't want to. This is the easiest but ugliest way to get OnRender to be called when necessary. You must force OnRender to reorder the columns and resize the column. Good luck
source share