Wednesday, February 29, 2012

Memory Leak with PagedCollectionView

Your silverlight application freeze when you filter or group a PagedCollectionView bind to a DataGrid ItemSource.
If you use Command in a DataGridTemplateColumn and you bind a property to the visibility of your button, you must be careful.
In fact, when you change the visibility of a button, the CanExecute method of the command is call. So if you change this visibility in the CanExecute method you make an infinite loop. The only solution is to set this value with an other method than the CanExecute.

Infinite Loop
private Boolean CanDelete(Object parameter) 
{
  YourViewModel vm = parameter as YourViewModel;
  if (vm != null)
  {
     if (vm.CanDelete)
     {
        vm.DeleteVisibility = Visibility.Visible;
        return true;
     }
     else
     {
        vm.DeleteVisibility = Visibility.Collapsed;
        return false;
      }
  }
 
  return false; 
}

Best Practice
private Boolean CanDelete(Object parameter) 
{
  YourViewModel vm = parameter as YourViewModel;
  if (vm != null)
  {
     return vm.CanDelete;
  }
 
  return false; 
}

private void Initialize()
{
  YourViewModel vm = new YourViewModel();
  vm.PropertyChanged += 
    new PropertyChangedEventHandler(
    vm_PropertyChanged);
}
 
void vm_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
  if (e.PropertyName == "CanDelete")
  {
    YourViewModel vm = sender as YourViewModel;
    if (vm != null)
    {
      vm.DeleteVisibility = vm.CanDelete ?
        Visibility.Visible : Visibility.Collapsed;
      //If you want call canExecute method to disbale button
      (DeleteCommand as DelegateCommand).OnCanExecuteChanged();
    }
  }
}

You also can use a BooleanToVisibility converter in your XAML and bind the property CanDelete. But you don't change the CanDelete value in the CanExecute method of your command.

I use the DelegateCommand for my command, you can find it to this url : http://spaeda.blogspot.com/2012/03/delegatecommand-in-silverlight.html

Saturday, February 11, 2012

Silverlight 4 ChildWindow leaves parent disabled after closing

A Silverlight 4 childWindow will close correctly at the first time, but in a second time it closes but leaves the UI parent disabled. Don’t be afraid, it’s a known issue.

While Microsoft don’t resolve it, you can enable the RootVisual in the OnClosed method of your childWindow.

protected override void OnClosed(EventArgs e)
{
     base.OnClosed(e);
     Application.Current.RootVisual.SetValue(Control.IsEnabledProperty, true);
}