我开发了一个具有数据网格的应用程序,它具有不同的列标题和行的上下文菜单。现在对于标题上下文菜单,我已经过滤了datagrid列。代码段如下所示。
<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>
现在,当未选中标题上下文菜单时,将隐藏特定列,反之亦然。它运行正常,但是当我想隐藏最后一列时,我花了大约5秒钟,它分配了大量的内存。当我在隐藏数据网格中的所有列之后创建可见的第一列时,会发生同样的事情。为什么会出现内存泄漏。
答案 0 :(得分:5)
使用上下文菜单时,内存泄漏是一种危险 - 特别是在将它们附加到网格时(我过去曾遇到过类似的问题)。在您提到的评论中,您将问题隔离到DataGridRow
样式:
<Setter Property="ContextMenu" Value="{StaticResource DataGridColumnHeaderContextMenu}" />
我不确切知道为什么上面会导致内存泄漏,但它看起来确实很危险。您将静态对象(&#34; DataGridColumnHeaderContextMenu&#34;) - 意味着它无法处理 - 附加到网格中的每一行。泄漏所需要的只是上下文菜单保存对行的引用,以及要回收的行。
无论如何,我认为你应该在这种情况下(在这种情况下)应该做的事情是在行加载时使用事件附加上下文菜单,并在卸载时分离它。对于DataGrid行,这意味着您应该在DataGrid.LoadingRow
事件中附加上下文菜单,并在UnloadingRow事件中将其删除。这应该确保不会发生菜单泄漏。