Unplanned
Last Updated: 06 Jun 2025 13:22 by Adam
Martin Ivanov
Created on: 29 Oct 2024 17:24
Category: DataGrid
Type: Bug Report
1
DataGrid: The click actions stop working when the data grid is hosted in a TabControl

The click actions (like cell selection and sorting) stop working when RadDataGrid is hosted in a RadTabControl or TabView. To reproduce this, you should select the tab item with the data grid, then select another tab, and select back the tab with the data grid. This prevents the hit testing in the RadDataGrid element.

The issue occurs because the hit test service used in the RadDataGrid implementation. The hit test service relies on the IsLoaded property of RadDataGrid (inherited from RadControl). The property is set in the Loaded and Unloaded events. However, when switching tabs, the Unloaded event is invoked on deselection, but on second selection of the same tab, the Loaded event is never called again, thus IsLoaded is false.

To work this around, you can subscribe to the PreviewSelectionChanged event of RadTabControl and manually update the internal isLoaded field of the data grid.

 

 private void RadTabControl_PreviewSelectionChanged(object sender, Telerik.UI.Xaml.Controls.RadSelectionChangedEventArgs e)
 {
     if (e.AddedItems.Count > 0)
     {
         var gridView = ((RadTabItem)e.AddedItems[0]).Content as RadDataGrid;
         var isLoadedField = typeof(RadControl).GetField("isLoaded", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);
         isLoadedField.SetValue(gridView, true);
     }
 }

 

1 comment
Adam
Posted on: 06 Jun 2025 13:22

In version 4.0.0, this issue also occurs when RadDataGrid ItemsSource is changed. Here is an extension class that can be used with the proposed solution from Martin.

```

public static class RadDataGridExtensions
{
    public static readonly DependencyProperty FixIsLoadedOnItemsSourceChangeProperty =
        DependencyProperty.RegisterAttached(
            "FixIsLoadedOnItemsSourceChange",
            typeof(bool),
            typeof(RadDataGridExtensions),
            new PropertyMetadata(false, OnFixIsLoadedOnItemsSourceChangeChanged));

    public static void SetFixIsLoadedOnItemsSourceChange(DependencyObject element, bool value) =>
        element.SetValue(FixIsLoadedOnItemsSourceChangeProperty, value);

    public static bool GetFixIsLoadedOnItemsSourceChange(DependencyObject element) =>
        (bool)element.GetValue(FixIsLoadedOnItemsSourceChangeProperty);

    private static void OnFixIsLoadedOnItemsSourceChangeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        if (d is RadDataGrid dataGrid && (bool)e.NewValue)
        {
            dataGrid.RegisterPropertyChangedCallback(RadDataGrid.ItemsSourceProperty, (_, __) =>
            {
                ApplyIsLoadedFix(dataGrid);
            });

            // Also patch immediately in case ItemsSource is already set
            if (dataGrid.ItemsSource != null)
            {
                ApplyIsLoadedFix(dataGrid);
            }
        }
    }

    private static void ApplyIsLoadedFix(RadDataGrid dataGrid)
    {
        try
        {
            var isLoadedField = typeof(RadControl).GetField("isLoaded", BindingFlags.Instance | BindingFlags.NonPublic);
            if (isLoadedField != null)
            {
                isLoadedField.SetValue(dataGrid, true);
            }
        }
        catch (Exception ex)
        {
            System.Diagnostics.Debug.WriteLine($"[RadDataGridExtensions] Failed to set isLoaded: {ex.Message}");
        }
    }
}

```