How can I remove those retentions?

Hello,

I've a WPF application that uses Catel as MVVM Framework. I've seen that a viewmodel doesn't get collected since it has 2 references to a CanExecuteChanged EventHandler I don't expose myself

 

Those commands are added via behavior to a grid in order to perform action on context menu and the code I use is

<pre>

protected virtual IEnumerable<RadMenuItem> GetRowMenuItems(RadContextMenu contextMenu)
{
var rowItems = new List<RadMenuItem>();

RadMenuItem saveSettings = new RadMenuItem
{
Tag = "force",
Header = CoreResources.LBL_SAVE_SETTINGS,
Command = DefaultRtViewContextMenuCommands.SaveLayoutDataCommand,
CommandParameter = AssociatedObject,

Icon = new Image { Source = new BitmapImage(new Uri("pack://application:,,,/IF.Tesoreria.Client.WPF.Core;component/Media/save.png")) }
};

rowItems.Add(saveSettings);

RadMenuItem loadSettings = new RadMenuItem
{
Tag = "force",
Header = CoreResources.LBL_LOAD_SETTINGS,
Command = DefaultRtViewContextMenuCommands.LoadLayoutDataCommand,
CommandParameter = AssociatedObject,
Icon = new Image { Source = new BitmapImage(new Uri("pack://application:,,,/IF.Tesoreria.Client.WPF.Core;component/Media/load.png")) }
};

rowItems.Add(loadSettings);

</pre>

Why this cause a leak?

Thanks in advance

 

 

0
6 comments

Hi Paolo,

There is not enough information to determine exactly why this issue occurs.

Probably it can be related to listener which are never unsubscribed from the event:

https://www.jetbrains.com/help/dotmemory/Inspections.html?Wave=7#event_handlers_leak

Also please read this answer, it can help in your case:

http://stackoverflow.com/a/12945325/7140949

Pay your attention on INotifyPropertyChanged implementation in your view model (it's also described in answer I mentioned above).

If these suggestions don't help you, could you please provide us solution sample? You can upload it to our FTP server: ftp://ftp.intellij.net/.uploads/ (anonymous login, .uploads directory has no permissions to list/download files, only for upload, so other users will not be able to download your files).

 

 

0

Hello,

I've created a sample project

 

https://drive.google.com/file/d/0B6nPFuIuKHG1eVBIa3pWRThPcUU/view?usp=sharing

 

just:

  • execute it
  • click on popup
  • right click on textblock
  • close the popup and search for  PopUpViewModel inside dotMemory
  • you'll see the holding reference.

If you comment inside the TextBoxBehavior.cs file 

 

private void OnMenuItemLoaded(object sender, RoutedEventArgs e)
{
try
{
var contextMenu2 = new RadContextMenu();

var items = GetRowMenuItems();

contextMenu2.ItemsSource = items; //<-------this (line #40)

RadContextMenu.SetContextMenu(AssociatedObject, contextMenu2);
}
catch (Exception exception)
{
Console.WriteLine(exception);

}
}

 

you'll get no more memory leak.

 

Thanks

0

Excuse me , I've got no feedback about this....any suggestion?

0

Paolo,

Sorry for delay. We need some time to explore your solution. We'll give you an answer as soon as possible.

0

Paolo,

The issue occurs in the Telerik's RadMenuItem control.
It doesn't unsubscribe from Command.CanExecuteChanged.
As the simplest workaround please try the following code:

    public class RadMenuItem2 : RadMenuItem
    {
        public RadMenuItem2()
        {
            Unloaded += delegate { SetValue(CommandProperty, null); };
        }
    }

But for production usage please contact Telerik for a better fix.

Besides that, change List<RadMenuItem> to ObservableCollection<RadMenuItem> in TextBoxBehavior.GetRowMenuItems() in your sample app. List doesn't implement INotifyPropertyChanged and it causes another leak.

0

Hello,

I've forwarded your analisys to Telerik , give you a feedback as soon as I'll have one,

Thanks!

0

Please sign in to leave a comment.