Memory leak error in WPat datagrid

I had an app developed that has a datagrid and it has a different context menu for column headers and rows. Now there are datagrid columns for the header context menu in my filter. Below is a code snippet.

<DataGrid   Padding="3" BorderBrush="SkyBlue" BorderThickness="1"  ItemsSource="{Binding Source={StaticResource cvsCoreData}}"   SelectionUnit="FullRow" IsReadOnly="True"  AutoGenerateColumns="False" x:Name="Data"  Margin="0,5,0,28">
    <DataGrid.Resources>
        <ContextMenu  x:Key="DataGridColumnHeaderContextMenu" >
            <MenuItem Header="ABC" Click="ABC_Click" />
            <MenuItem Header="EFG" Click="EFG_Click" />
            <MenuItem Header="HIJ" Click="HIJ_Click" />
            <MenuItem Header="KLM" Click="KLM_Click" />
        </ContextMenu>
    </DataGrid.Resources>
    <DataGrid.RowStyle>
        <Style TargetType="{x:Type DataGridRow}">
            <Style.Triggers>
                <Trigger Property="IsSelected" Value="True" >
                    <Setter Property="Background" Value="SkyBlue" />
                    <Setter Property="Foreground" Value="Black"/>
                </Trigger>
            </Style.Triggers>
            <Setter Property="ContextMenu"
            Value="{StaticResource DataGridColumnHeaderContextMenu}" />
        </Style>
    </DataGrid.RowStyle>
    <DataGrid.Columns>
        <DataGridTemplateColumn SortMemberPath="Key" Width="*" Header="Key ">
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <TextBlock x:Name="block"  TextWrapping="Wrap" Text="{Binding Key}">

                    </TextBlock>
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>
        <DataGridTextColumn Width="*" Header="Lerm Description" Binding="{Binding KeyDescription}" />
        <DataGridTextColumn Width="*" Header="Short " Binding="{Binding Short}" />
        <DataGridTextColumn Width="*" Header="Rule" Binding="{Binding Rules}" />
    </DataGrid.Columns>
    <DataGrid.ContextMenu>
        <ContextMenu>
            <MenuItem x:Name="ContextKey" IsCheckable="True" IsChecked="True" Header="Key" Unchecked="ContextMenu_Unchecked" Checked="ContextMenu_Checked" Tag="0" />
            <MenuItem x:Name="ContextLermDescription" IsCheckable="True" IsChecked="True" Header="Key" Unchecked="ContextMenu_Unchecked" Checked="ContextMenu_Checked" Tag="1"  />
            <MenuItem x:Name="ContextShor" IsCheckable="True" IsChecked="True" Header="Short" Unchecked="ContextMenu_Unchecked" Checked="ContextMenu_Checked" Tag="2"  />
            <MenuItem x:Name="ContextRule" IsCheckable="True" IsChecked="True" Header="Rules" Unchecked="ContextMenu_Unchecked" Checked="ContextMenu_Checked" Tag="3"  />
        </ContextMenu>
    </DataGrid.ContextMenu>
</DataGrid>  

      

Now that the header context menu is unchecked, the specific column will be hidden and vice versa. It works great, but when I wanted to hide the last column it took me about 5 seconds and it allocates a lot of memory. The same happens when I make the first column visible, hiding all columns in the datagrid. Why is this "severe" memory leak happening.

+3


source to share


1 answer


Memory leaks are dangerous when working with context menus - especially when attaching them to grids (I've had a similar problem in the past). In the comments, you mentioned that you isolated the problem down to style DataGridRow

:

<Setter Property="ContextMenu" Value="{StaticResource DataGridColumnHeaderContextMenu}" />

      



I don't know exactly why the above is causing a memory leak, but it seems like a risky thing to do. You attach a static object ("DataGridColumnHeaderContextMenu"), which means it cannot be deleted - for every row in the Grid. All it takes to leak is that the context menu contains a link to the string, and for the string to be recycled.

Anyway, I think what you should do in this case (and in this scenario in general) is to use events to attach the context menu when the row is loaded and detach when it is unloaded. For DataGrid rows, this means you have DataGrid.LoadingRow

to dock the context menu on the event and remove it in the UnloadingRow . This is to ensure that no menu leak occurs.

+5


source







All Articles