Silverlight DataContextProxy no longer necessary

January 25, 2011

Prior to Silverlight 4, to get access to the Page/Control DataContext from within a grid, it required some trickery to be able to bind elements such as Combobox ItemsSource collections within a grid. Probably the most used idea was to create a DataContextProxy class, and bind to that when you wanted to access the DataContext within a page. Well, this is no longer necessary, so you can remove all references to DataContextProxy classes, and do the following instead.

Note here that I am assuming that you have bound your View Model to the current Page/Control.

Firstly, you need to name your root element. In my case, it’s a navigation page, so I have named it “ThisPage”

<navigation:Page x:Class="MyNamespace.MyClass"
           Title="My Title"
           d:DesignWidth="1085" d:DesignHeight="500"

Of course, I have the data context of this page is bound to my view model (you can do this various ways, even in the XAML)

public MyClass()

   if (viewModel == null)
         viewModel = new MyViewModel();
   this.DataContext = viewModel;

Within a grid, I can now bind directly to the DataContext property of ThisPage.

Here I have shown how to bind a ComboBox collection inside an sdk combo box column.

<sdk:DataGridTemplateColumn x:Name="MyListColumn" Header="My Type" Width="150">
         <ComboBox x:Name="MyListComboBox" DisplayMemberPath="Description" SelectedValuePath="Code" SelectedValue="{Binding Path=MyCode}" ItemsSource="{Binding Path=DataContext.MyObservableCollectionInViewModel, ElementName=ThisPage}" />

Note that the ItemsSource is bound to an element, and that element is ThisPage. ThisPage has a DataContext, which is bound to my View Model. So to bind the observable collection I created, called MyObservableCollectionInViewModel, to the ItemsSource of the ComboBox, I need to reference the collection off the DataContext property of ThisPage. Hence the following syntax for the bind itself:

ItemsSource="{Binding Path=DataContext.MyObservableCollectionInViewModel, ElementName=ThisPage}"