ToolTip Memory leak in WPF while binding a View to

2019-07-01 16:57发布

问题:

I have an application in WPF, MVVM. Shows a list of Images in a ListBox each image is associated to different session.

My ListBox ItemTemplate looks like this,

<ListBox.ItemTemplate>
   <DataTemplate>
      <Image 
          Source="{Binding IsClaims,Converter={StaticResource PolicyClaimsImageSelector}}" 
          ToolTipService.ShowDuration="7000">
             <Image.ToolTip>                                           
                <StackPanel>
                  <TextBlock Text="{Binding WorkingSessionName}" />
                  <Views:ToolTipView DataContext="{Binding ThisViewModel}"/>
                </StackPanel>
            </Image.ToolTip>
      </Image>
   </DataTemplate>
</ListBox.ItemTemplate>

My ViewModel

public class Session : BindableBase
{
    private MainViewModel _ThisViewModel;
    public MainViewModel ThisViewModel
    {
        get
        {
            return _ThisViewModel;
        }
        set
        {
            _ThisViewModel = value;
            NotifyPropertyChanged();
        }
    }
}

When ever the tool tip shows up there is a memory leak, not understanding why its happening, My question is that is there anything i have to do with ToolTip to dispose any memory after showing the ToolTip ?. if so how to do that ?

Edit

No Events are subscribed. Only binding the DataContext of different ViewModels of different Views

ToolTipView.XAML

 <DockPanel>
    <xcad:DockingManager  DockPanel.Dock="Left" Grid.Row="2" BorderBrush="Black" BorderThickness="1">
        <xcad:DockingManager.Theme>
            <xcad:MetroTheme />
        </xcad:DockingManager.Theme>
        <xcad:LayoutRoot >
            <xcad:LayoutPanel Orientation="Horizontal" >
                <xcad:LayoutAnchorablePaneGroup Orientation="Horizontal" DockMinWidth="150" >
                    <xcad:LayoutAnchorablePane >
                        <xcad:LayoutAnchorable Title="Folder" x:Name="ExplorerView" AutoHideWidth="300">
                            <Views:ExplorerView DataContext="{Binding ExplorerViewModel}"/>
                        </xcad:LayoutAnchorable>
                    </xcad:LayoutAnchorablePane>
                </xcad:LayoutAnchorablePaneGroup>
                <xcad:LayoutAnchorablePaneGroup Orientation="Horizontal" DockMinWidth="450" >
                    <xcad:LayoutAnchorablePane >
                        <xcad:LayoutAnchorable Title="Documents"  x:Name="TOC">
                            <Views:TableOfContentView  DataContext="{Binding TableOfContentViewModel}"/>
                        </xcad:LayoutAnchorable>
                    </xcad:LayoutAnchorablePane>
                </xcad:LayoutAnchorablePaneGroup>
                <xcad:LayoutAnchorablePaneGroup Orientation="Vertical" DockMinWidth="320">
                    <xcad:LayoutAnchorablePane DockMinHeight="400" >
                        <xcad:LayoutAnchorable Title="Properties"  x:Name="Property">
                            <Views:PropertyView DataContext="{Binding PropertyViewModel}"/>
                        </xcad:LayoutAnchorable>
                    </xcad:LayoutAnchorablePane>
                    <xcad:LayoutAnchorablePane >
                        <xcad:LayoutAnchorable Title="Search"  x:Name="Search">
                            <Views:SearchPanel DataContext="{Binding SearchViewModel}"/>
                        </xcad:LayoutAnchorable>
                    </xcad:LayoutAnchorablePane>
                </xcad:LayoutAnchorablePaneGroup>                    
            </xcad:LayoutPanel>
        </xcad:LayoutRoot>
    </xcad:DockingManager>
</DockPanel>

EDIT

I have tried removing all the Views from the ToolTipView.XAML like below and show the tool tip with out any View in the ToolTip gives me the same memory leak.

Here is what now my ToolTipView.XAML looks like,

<UserControl x:Class="ecclient.viewer.Views.ToolTipView"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         xmlns:Views="clr-namespace:ecclient.viewer.Views">
</UserControl>

回答1:

This is a bit of a stab in the dark, but might be something to try. I've had an issue where certain graphics drivers would somehow trigger a leak in WPF. We ended up WPF disabling hardware acceleration and re-testing. It's not an ideal answer, but was enough for us to work around the problem for customers running clients for long periods of time.

In the registry (system wide)

[HKEY_CURRENT_USER\Software\Microsoft\Avalon.Graphics]
"DisableHWAcceleration"=dword:00000001

Or via code for the application itself:

   RenderOptions.ProcessRenderMode = RenderMode.SoftwareOnly;

You can test what is rendered via software or hardware by using the "WPF Performance Suite" and enable the purple tint for software rendered elements.

I hope this helps.



回答2:

I have fixed it by creating an Interface to mimic the actual bindings. see below.

 public IExplorer ToolTipExplorerViewModel
    {
        get { return ExplorerViewModel; }            
    }

    public ITableOfContents ToolTipTableOFContents
    {
        get { return TableOfContentViewModel; }
    }

now i bind this properties with ToolTipView ie:

<Views:ExplorerView DataContext="{Binding ToolTipExplorerViewModel}" Grid.Column="0"/>
<Views:TableOfContentView  DataContext="{Binding ToolTipTableOFContents}" Grid.Column="1" />      

Now Memory is not growing as we change the tooltip.