我在WPF应用程序中使用DataContextProxy时遇到问题。当我在Grid的Resources部分放置DataContextProxy时,它永远不会被加载。如果我将DataContextProxy移出资源部分,一切正常。
我已经研究了一段时间,并尝试了许多方法来调试应用程序。
我在我正在尝试使用的控件上放置了一个DebugConverter 代理与。永远不会调用Debug转换器。
我使用WPFSnoop查看是否存在任何绑定错误。我明白了 跟随DataContextProxy上的绑定错误,
System.Windows.Data错误:3:找不到提供DataContext的元素。 BindingExpression :(没有路径);的DataItem = NULL;目标元素是'代理' (名称= ''); target属性是'DataContext'(类型'Object')
我在DataContextProxy的加载事件上放置了一个断点。 永远不会调用加载的事件,我在其中放置了一个断点 从未调用的DataContextChanged事件。
以下是一些示例代码来演示这一点。显然我知道我不需要在TextBox上使用DataContextProxy。
<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>
DataContextProxy类
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)
{
}
}
答案 0 :(得分:1)
当我尝试在WPF中使用DataContextProxy时,我也遇到了这个问题。我想出了一个灵感来自它的解决方案,似乎可以很好地处理这项工作。看看:
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"
);
}
}
您只需将其附加到父元素即可。子元素中的静态资源引用将保持不变。我发布了一个用法示例here。