2014-08-27 31 views
3

我開發了一個具有數據網格的應用程序,它具有不同的列標題和行的上下文菜單。現在在頭文件上下文菜單中有一個我有過濾數據網格列。代碼片段如下。WPF數據網格中的內存泄漏問題

<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

你使用什麼.net框架? 3.5或4.0或... – blindmeis 2014-08-27 09:20:48

+0

我使用.NET 4.5框架。 – 2014-08-27 09:22:35

+0

以及我有一個與DataGridTemplateColumn類似的問題。 (http://wpf.codeplex.com/discussions/400881),但這是用4.5解決的 – blindmeis 2014-08-27 09:24:14

回答

5

使用上下文菜單時內存泄漏是一種危險 - 特別是將它們附加到網格時(我過去曾遇到過類似問題)。在評論你提到你找出問題的DataGridRow風格:

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

我不知道到底爲什麼上面的會導致內存泄漏,但它看起來像一個冒險的事。您將靜態對象(「DataGridColumnHeaderContextMenu」)附加到網格中的每一行上,這意味着它無法處理。泄漏所需要的只是上下文菜單保存對行的引用,並對行進行回收。

無論如何,我認爲你應該在這種情況下(在這種情況下一般情況下)應該做的事情是在行加載時使用事件附加上下文菜單,並在卸載時將其分離。對於DataGrid行,這意味着您應該在DataGrid.LoadingRow事件中附加上下文菜單,並在UnloadingRow事件中將其刪除。這應該確保不會發生菜單泄漏。