I've used @Bartłomiej Popielarz's 2nd approach to make it work.
In my case somehow control.Parent
always returned null
. Thats why I've changed the according line to
var parent = VisualTreeHelper.GetParent(control) as UIElement;
Also I've created a attached Property that does the forwarding (better suited for MVVM approaches).
public class FixScrollingBehaviorOn
{
public static readonly DependencyProperty ParentDataGridProperty = DependencyProperty.RegisterAttached("ParentDataGrid", typeof(DataGrid), typeof(FixScrollingBehaviorOn),
new FrameworkPropertyMetadata(default(DataGrid), OnParentDataGridPropertyChanged));
public static bool GetParentDataGrid(DependencyObject obj)
{
return (bool)obj.GetValue(ParentDataGridProperty);
}
public static void SetParentDataGrid(DependencyObject obj, bool value)
{
obj.SetValue(ParentDataGridProperty, value);
}
public static void OnParentDataGridPropertyChanged(object sender, DependencyPropertyChangedEventArgs e)
{
var dataGrid = sender as DataGrid;
if (dataGrid == null)
{
throw new ArgumentException("The dependency property can only be attached to a DataGrid", "sender");
}
if (e.NewValue is DataGrid parentGrid)
{
dataGrid.PreviewMouseWheel += HandlePreviewMouseWheel;
parentGrid.SetValue(ScrollViewer.CanContentScrollProperty, false);
}
else
{
dataGrid.PreviewMouseWheel -= HandlePreviewMouseWheel;
if (e.OldValue is DataGrid oldParentGrid)
{
oldParentGrid.SetValue(ScrollViewer.CanContentScrollProperty, ScrollViewer.CanContentScrollProperty.DefaultMetadata.DefaultValue);
}
}
}
private static void HandlePreviewMouseWheel(object sender, MouseWheelEventArgs e)
{
if (e.Handled)
{
return;
}
var control = sender as DataGrid;
if (control == null)
{
return;
}
e.Handled = true;
var wheelArgs = new MouseWheelEventArgs(e.MouseDevice, e.Timestamp, e.Delta)
{
RoutedEvent = UIElement.MouseWheelEvent,
Source = control
};
var parent = VisualTreeHelper.GetParent(control) as UIElement;
parent?.RaiseEvent(wheelArgs);
}
Feel free to use this as follows on your inner DataGrid
. Note that The ScrollViewer.CanContentScrollProperty
is being set from within the AttachedProperty, which may not be everyone's favourite approach.
<DataGrid>
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding Path=test}" />
</DataGrid.Columns>
<DataGrid.RowDetailsTemplate>
<DataTemplate>
<DataGrid
attachedProperties:FixScrollingBehaviorOn.ParentDataGrid="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGrid}}}"
Template="{DynamicResource TemplateDataGridPrintAndExport}" />
</DataTemplate>
</DataGrid.RowDetailsTemplate>
</DataGrid>