Here are 2 generic classes (DataContextProxy and DataContextProxyBehavior) that help to pass data context from one control to resource so that other visual/or not visual can bind to.
DataContextProxy: Just a simple VM that hold DataContext object.
DataContextProxyBehavior: Simple behavior that can be attached to any FrameworkElement. Once attached, it tracks that FrameworkElement's DataContext. Any change of DataContext, it will pass the change to DataContextProxy. The goal is to have DataContextProxy be in resource that other visual/non visual can bind to.
Usage: See an example of declaration and usage at the bottom.
Hope it helps someone :)
01.
public
class
DataContextProxy : SomeImplementationOfINotifyPropertyChanged
02.
{
03.
#region private data
04.
private
object
_dataContext;
05.
#endregion
06.
07.
#region public properties
08.
public
object
DataContext
09.
{
10.
get
{
return
_dataContext; }
11.
set
{ _dataContext = value; FirePropertyChanged(() => DataContext); }
12.
}
13.
#endregion
14.
15.
#region constructors
16.
public
DataContextProxy()
17.
{
18.
_dataContext =
null
;
19.
}
20.
#endregion
21.
}
01.
public
class
DataContextProxyBehavior : Behavior<FrameworkElement>
02.
{
03.
#region DataContextProxy Dependency
04.
public
DataContextProxy DataContextProxy
05.
{
06.
get
{
return
(DataContextProxy)GetValue(DataContextProxyProperty); }
07.
set
{ SetValue(DataContextProxyProperty, value); }
08.
}
09.
10.
public
static
readonly
DependencyProperty DataContextProxyProperty =
11.
DependencyProperty.Register(
"DataContextProxy"
,
typeof
(DataContextProxy),
typeof
(DataContextProxyBehavior));
12.
#endregion
13.
14.
#region overrides
15.
protected
override
void
OnAttached()
16.
{
17.
base
.OnAttached();
18.
19.
UpdateDataContext();
20.
AssociatedObject.DataContextChanged += AssociatedObjectOnDataContextChanged;
21.
}
22.
23.
protected
override
void
OnDetaching()
24.
{
25.
base
.OnDetaching();
26.
AssociatedObject.DataContextChanged -= AssociatedObjectOnDataContextChanged;
27.
}
28.
#endregion
29.
30.
#region private functions
31.
private
void
AssociatedObjectOnDataContextChanged(
object
sender, DependencyPropertyChangedEventArgs args)
32.
{
33.
UpdateDataContext();
34.
}
35.
36.
private
void
UpdateDataContext()
37.
{
38.
if
(AssociatedObject !=
null
&& DataContextProxy !=
null
)
39.
{
40.
DataContextProxy.DataContext = AssociatedObject.DataContext;
41.
}
42.
}
43.
#endregion
44.
}
Sample Usage of DataContextProxy and DataContextProxyBehavior classes:
Create an instance of DataContextProxy in resource dictionary
<
UserControl.Resources
>
<
DataContextProxy
x:Key
=
"DataContextProxy"
/>
</
UserControl.Resources
>
Use DataContextProxyBehavior to pass an element framework's DataContext to DataContextProxy
<
Grid
DataContext
=
"{Binding SomeViewModel}"
>
<
i:Interaction.Behaviors
>
<
DataContextProxyBehavior
DataContextProxy
=
"{StaticResource DataContextProxy}"
/>
</
i:Interaction.Behaviors
>
</
Grid
>
In a non-visual or visual element, bind to DataContextProxy using StaticResource.
<
telerik:GridViewDataColumn.Header
>
<
TextBlock
Text
=
"{Binding DataContext.SomeTextPropertyOnSomeViewModel, Source={StaticResource DataContextProxy}}"
/>
</
telerik:GridViewDataColumn.Header
>