Sin*_*atr 2 c# data-binding wpf
任何 wpf 程序员迟早都会开始使用BindingProxy。
我试图通过将一些资源移动到单独的资源字典中来拆分 xaml。我的问题是资源包含对BindingProxy.
我该如何处理这种情况?
举个例子,假设有一个资源在BindingProxy某处使用
<Window.Resources>
<local:BindingProxy x:Key="proxy" />
<ControlTemplate x:Key="test">
<TextBlock Text="{Binding DataContext.Test, Source={StaticResource proxy}}" />
</ControlTemplate>
</Window.Resources>
<Control Template="{StaticResource test}" />
Run Code Online (Sandbox Code Playgroud)
和后面的代码
public partial class MainWindow : Window
{
public string Test { get; set; } = "Test 123";
public MainWindow()
{
InitializeComponent();
DataContext = this;
}
}
Run Code Online (Sandbox Code Playgroud)
它可能不是最好的例子,使用BindingProxy并不合理,但它很好地达到了演示目的。在运行时窗口中将"Test 123"显示文本。
现在让我们尝试将资源移动到资源字典中Dictionary1.xaml
<ResourceDictionary ... >
<ControlTemplate x:Key="test">
<TextBlock Text="{Binding Test, Source={StaticResource proxy}}" /> <!-- error here -->
</ControlTemplate>
</ResourceDictionary>
Run Code Online (Sandbox Code Playgroud)
并将主窗口资源更改为
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Dictionary1.xaml" />
</ResourceDictionary.MergedDictionaries>
<local:BindingProxy x:Key="proxy" />
</ResourceDictionary>
</Window.Resources>
<Control Template="{StaticResource test}" />
Run Code Online (Sandbox Code Playgroud)
会导致设计和运行时异常
System.Windows.Markup.XamlParseException:“为‘System.Windows.Markup.StaticResourceHolder’提供值引发了异常。” 行号“5”和行位置“20”。
内部异常
异常:找不到名为“proxy”的资源。资源名称区分大小写。
我该如何参考proxy?是否存在另一种技术来引用资源字典中的某些内容?也许有某种RelativeResource方法,但对于不在视觉树中的东西?由于明显的原因,我无法proxy进入ResourceDictionary1.xaml:它不会捕获DataContext窗口。
尽管我不推荐BindingProxy在 MVVM 中使用,但我认为您的问题是这样解决的:
ResourceDictionary在视图 XAML 中包含 时,它会自动继承视图的DataContext,因此您可以将 保留BindingProxy在 中ResourceDictionary,但需要显式指定绑定。DataContext您失去了更改的能力BindingProxy,它将使用DataContext消费者视图。资源字典:
<ResourceDictionary ...>
<!-- NOTE: Data property grabs the DataContext of the consumer view -->
<local:BindingProxy x:Key="proxy" Data="{Binding}" />
<ControlTemplate x:Key="text">
<TextBlock Text="{Binding Data.Test, Source={StaticResource proxy}}" />
</ControlTemplate>
</ResourceDictionary>
Run Code Online (Sandbox Code Playgroud)
窗户:
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Dictionary1.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
Run Code Online (Sandbox Code Playgroud)
快照:
BindingProxy?上面的建议违背了它的目的,BindingProxy因为它不再需要了;请注意,您可以ResourceDictionary按如下方式更改,它的工作原理完全相同,不需要任何BindingProxy:
<ResourceDictionary ...>
<ControlTemplate x:Key="test">
<TextBlock Text="{Binding Test}" />
</ControlTemplate>
</ResourceDictionary>
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
750 次 |
| 最近记录: |