I’m having trouble using a DataContextProxy in my WPF application. When I place a DataContextProxy in the Resources section of a Grid it is never loaded. If I move the DataContextProxy out of the resource section everything works correctly.
I’ve been investigating this for some time and have tried a number of methods to debug the application.
I’ve placed a DebugConverter on the control that I’m trying to use the Proxy with. The Debug converter is never called.
I’ve used WPFSnoop to see if there are any binding errors. I get the following binding error on the DataContextProxy,
System.Windows.Data Error: 3 : Cannot find element that provides DataContext. BindingExpression:(no path); DataItem=null; target element is 'Proxy' (Name=''); target property is 'DataContext' (type 'Object')
I’ve placed a breakpoint on the loaded event of my DataContextProxy. The loaded event is never called and I’ve placed a breakpoint in the DataContextChanged event which is never called.
Here is some sample code to demonstrate this. Obviously I know I do not really need to use a DataContextProxy on the TextBox.
<Window x:Class="WpfDataContextProxyBug.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfDataContextProxyBug"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<local:DebugConverter x:Key="DebugConverter"/>
</Window.Resources>
<Grid>
<Grid.Resources>
<local:Proxy x:Key="Proxy" DataContext="{Binding}" />
</Grid.Resources>
<TextBox DataContext="{Binding Path=Name, Source={StaticResource Proxy}, Converter={StaticResource DebugConverter}}"/>
</Grid>
</Window>
The DataContextProxy class
public class Proxy : FrameworkElement
{
public Proxy()
{
Loaded += DataContextProxy_Loaded;
DataContextChanged += Proxy_DataContextChanged;
}
void Proxy_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
{
}
void DataContextProxy_Loaded(object sender, RoutedEventArgs e)
{
}
}
I've also hit this problem when I tried to use the DataContextProxy in WPF. I've come up with a solution inspired by it which seems to handle the job pretty decently. Check it out:
public class DataContextProxyBehavior : Behavior<FrameworkElement>
{
public Object DataSource
{
get { return (Object)GetValue(DataSourceProperty); }
set { SetValue(DataSourceProperty, value); }
}
public static readonly DependencyProperty DataSourceProperty =
DependencyProperty.Register("DataSource", typeof(Object), typeof(DataContextProxy), null);
protected override void OnAttached()
{
base.OnAttached();
// Binds the target datacontext to the proxy,
// so whenever it changes the proxy will be updated
var binding = new Binding();
binding.Source = this.AssociatedObject;
binding.Path = new PropertyPath("DataContext");
binding.Mode = BindingMode.OneWay;
BindingOperations.SetBinding(this, DataContextProxyBehavior.DataSourceProperty, binding);
// Add the proxy to the resource collection of the target
// so it will be available to nested controls
this.AssociatedObject.Resources.Add(
"DataContextProxy",
this
);
}
protected override void OnDetaching()
{
base.OnDetaching();
// Removes the proxy from the Resources
this.AssociatedObject.Resources.Remove(
"DataContextProxy"
);
}
}
You just need to attach it to the parent element. The static resource reference in the child element will remain the same. I've posted an usage example here.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With