开发者

Silverlight: Alternative to using a DataContextProxy?

We have been using the DataContextProxy concept based on (or exactly) as described in Dan Wahlin's Blog. Functionally This has worked fine for our purposes. However, aft开发者_运维问答er doing extensive memory profiling, and after discovering similar reports online (link below), it seems that this approach leaks memory as a result of a problem/bug with UserControl.Resources.

Has anyone found a decent alternative to the DataContextProxy approach?

Connect Report, which says the problem has been fixed in SL 5. I am going to try to post a repro solution for SL4.


I've come up with something very close to the DataContextProxy but instead of the binding being created in the Loaded event of the class, the declaration in the XAML binds back to the class. Seems to work exactly the same except it doesn't leak. Would love someone else to verify this.

<UserControl.Resources>
    <local:DataContextProxy x:Key="DataContextProxy" ViewModel="{Binding Path=DataContext, ElementName=LayoutRoot, Mode=TwoWay}" />
</UserControl.Resources>

The class

namespace Silverlight.Infrastructure
{
   /// <summary>
   /// Refactored to not leak. Set binding on ViewModel propery to DataContext of page, in Resources of page
   /// Binding in XAML on declaration of DataContextProxy
   /// Usage: <shared:DataContextProxy x:Key="DataContextProxy" ViewModel="{Binding Path=DataContext, RelativeSource={RelativeSource Self}, Mode=TwoWay}" />
   /// </summary>
   /// <remarks></remarks>
   public class DataContextProxy : DependencyObject
   {
      public static DependencyProperty ViewModelProperty =  DependencyProperty.Register("ViewModel", typeof (object), typeof (DataContextProxy), new PropertyMetadata(default(object)));

      public object ViewModel
      {
         get { return (object)GetValue(ViewModelProperty); }
         set { SetValue(ViewModelProperty, value); }
      }
   }
}

usage:

DataToBindTo="{Binding ViewModel.DataToBindTo, Source={StaticResource DataContextProxy}}"

Changed the binding to ElementName as it seemed to work better on child views that didn't get a viewmodel until after the binding had been initially resolved.


You can look at this SL implementation of a relative source binding. Caliburn Micro also has a way to solve this problem by Action bubbling.


I'm not aware of memory leaks problems, but as Silverlight 4 introduced ElementName in bindings, it mostly eliminates the need for a DataContextProxy:

<ListBox ItemsSource="{Binding DataContext.Languages, ElementName=LayoutRoot}">

More explanations here.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜