如何从ResourceDictionary引用BindingProxy实例 [英] How to reference BindingProxy instance from ResourceDictionary
问题描述
迟早任何WPF程序员都开始使用
您真的需要 BindingProxy
吗?
上面的建议破坏了 BindingProxy
的目的,因为它不再需要了.请注意,您可以按照以下方式更改 ResourceDictionary
,它的工作原理完全相同,而无需 BindingProxy
:
< ResourceDictionary ...>< ControlTemplate x:Key ="test">< TextBlock Text =< {Binding Test}"/></ControlTemplate></ResourceDictionary>
Sooner or later any wpf programmer begin to use BindingProxy.
I am trying to split xaml by moving some of resources into separate resource dictionary. My problem is that resources contain reference to BindingProxy
.
How can I handle this situation?
As an example, lets say there is a resource with BindingProxy
which is used somewhere
<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}" />
and code behind
public partial class MainWindow : Window
{
public string Test { get; set; } = "Test 123";
public MainWindow()
{
InitializeComponent();
DataContext = this;
}
}
It may not be the best example, using BindingProxy
is not really justified, but it serve demonstration purpose well. During run-time window with text "Test 123"
will be shown.
Now lets try move resource to resource dictionary Dictionary1.xaml
<ResourceDictionary ... >
<ControlTemplate x:Key="test">
<TextBlock Text="{Binding Test, Source={StaticResource proxy}}" /> <!-- error here -->
</ControlTemplate>
</ResourceDictionary>
and change main window resource to
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Dictionary1.xaml" />
</ResourceDictionary.MergedDictionaries>
<local:BindingProxy x:Key="proxy" />
</ResourceDictionary>
</Window.Resources>
<Control Template="{StaticResource test}" />
will lead to desinger and run-time exception
System.Windows.Markup.XamlParseException: ''Provide value on 'System.Windows.Markup.StaticResourceHolder' threw an exception.' Line number '5' and line position '20'.'
Inner Exception
Exception: Cannot find resource named 'proxy'. Resource names are case sensitive.
How can I reference proxy
? Is there another technique exist to reference somethining from resource dictionary? Maybe some kind of RelativeResource
approach but for things which are not in visual tree? I can't move proxy
into ResourceDictionary1.xaml
for obvious reasons: it will not capture DataContext
of window.
Even though I don't recommend the BindingProxy
in MVVM, this is how I think your problem is resolved:
- Bear in mind when you include a
ResourceDictionary
in your view XAML, it automatically inherits theDataContext
of the view hence you can keep theBindingProxy
in theResourceDictionary
but you need to specify the binding explicitly. - Remember to also remove the proxy declaration from the View XAML as it is now in the dictionary.
- You lose the ability to change the
DataContext
of theBindingProxy
, it will use theDataContext
of the consumer view.
ResourceDictionary:
<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>
Window:
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Dictionary1.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
Snapshot:
Do you really need the BindingProxy
?
The suggestion above defeats the purpose of the BindingProxy
as it is not needed anymore; note you could just change the ResourceDictionary
as follows and it works exactly the same without any need of the BindingProxy
:
<ResourceDictionary ...>
<ControlTemplate x:Key="test">
<TextBlock Text="{Binding Test}" />
</ControlTemplate>
</ResourceDictionary>
这篇关于如何从ResourceDictionary引用BindingProxy实例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!