chr*_*233 5 c# silverlight wpf datacontext mvvm
我\xe2\x80\x99m 在我的 WPF 应用程序中使用 DataContextProxy 时遇到问题。当我将 DataContextProxy 放置在网格的资源部分时,它永远不会加载。如果我将 DataContextProxy 移出资源部分,一切都会正常工作。
\n\n我\xe2\x80\x99已经对此进行了一段时间的研究,并尝试了多种方法来调试应用程序。
\n\n我\xe2\x80\x99已在我\xe2\x80\x99m尝试使用代理的控件上放置了一个DebugConverter。调试转换器永远不会被调用。
我\xe2\x80\x99ve使用WPFSnoop来查看是否有任何绑定错误。我在 DataContextProxy 上遇到\n以下绑定错误,
\n\nSystem.Windows.Data 错误:3:找不到提供 DataContext 的元素。\nBindingExpression:(无路径);数据项=空;目标元素是\'Proxy\'\n(Name=\'\'); 目标属性是“DataContext”(类型“Object”)
我\xe2\x80\x99在我的DataContextProxy的加载事件上放置了一个断点。\n加载的事件从未被调用,而我\xe2\x80\x99在\nDataContextChanged事件中放置了一个断点,该事件从未被调用。
这是一些示例代码来演示这一点。显然我知道我并不真正需要在 TextBox 上使用 DataContextProxy。
\n\n<Window x:Class="WpfDataContextProxyBug.MainWindow"\n xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"\n xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"\n xmlns:local="clr-namespace:WpfDataContextProxyBug"\n Title="MainWindow" Height="350" Width="525">\n <Window.Resources>\n <local:DebugConverter x:Key="DebugConverter"/>\n </Window.Resources>\n <Grid>\n <Grid.Resources>\n <local:Proxy x:Key="Proxy" DataContext="{Binding}" />\n </Grid.Resources>\n\n <TextBox DataContext="{Binding Path=Name, Source={StaticResource Proxy}, Converter={StaticResource DebugConverter}}"/>\n </Grid>\n</Window>\nRun Code Online (Sandbox Code Playgroud)\n\nDataContextProxy 类
\n\npublic class Proxy : FrameworkElement\n{\n public Proxy()\n {\n Loaded += DataContextProxy_Loaded;\n DataContextChanged += Proxy_DataContextChanged;\n }\n\n void Proxy_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e)\n {\n\n }\n\n void DataContextProxy_Loaded(object sender, RoutedEventArgs e)\n {\n\n }\n\n}\nRun Code Online (Sandbox Code Playgroud)\n
当我尝试在 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"
);
}
}
Run Code Online (Sandbox Code Playgroud)
您只需将其附加到父元素即可。子元素中的静态资源引用将保持不变。我在这里发布了一个用法示例。