问题
I have problem
System.Windows.Data Error: 2 : Cannot find governing FrameworkElement or FrameworkContentElement for target element. BindingExpression:(no path); DataItem=null; target element is 'SolidColorBrush' (HashCode=48519443); target property is 'Color' (type 'Color')
It can be reproduced with following xaml:
<Window PreviewKeyDown="Window_PreviewKeyDown"
xmlns:diag="clr-namespace:System.Diagnostics;assembly=WindowsBase"
... >
<Window.Resources>
<DataTemplate DataType="{x:Type local:ViewModel}">
<ListBox ItemsSource="{Binding List}">
<ListBox.ItemTemplate>
<DataTemplate>
<Border Width="20" Height="20">
<Border.Background>
<SolidColorBrush Color="{Binding diag:PresentationTraceSources.TraceLevel=High}" />
</Border.Background>
</Border>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</DataTemplate>
</Window.Resources>
<ContentControl Content="{Binding}" />
</Window>
and cs:
public class ViewModel
{
public List<Color> List { get; } = new List<Color> { Colors.Red, Colors.Blue, Colors.Green, Colors.Black, Colors.Yellow };
}
public partial class MainWindow : Window
{
readonly ViewModel _vm = new ViewModel();
public MainWindow()
{
InitializeComponent();
}
void Window_PreviewKeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.F1)
DataContext = _vm;
if (e.Key == Key.F2)
DataContext = null;
}
}
Start, press F1 and check Output
window (binding tracing is enabled, so you will see more).
Question: how can I fix them?
Errors doesn't cause problem to functionality, but they appears in Output
window (and in real project there are lots of them), which already a sign of some problem. Which problem?
Key here is to have datatemplate and apply it some time later, then this binding in datatemplate will cause problems. Setting DataContext
in constructor doesn't cause problems.
Here is some trace, if someone is able to understand it and can give some hints regarding:
System.Windows.Data Warning: 56 : Created BindingExpression (hash=45377043) for Binding (hash=28932383)
System.Windows.Data Warning: 58 : Path: ''
System.Windows.Data Warning: 60 : BindingExpression (hash=45377043): Default mode resolved to OneWay
System.Windows.Data Warning: 61 : BindingExpression (hash=45377043): Default update trigger resolved to PropertyChanged
System.Windows.Data Warning: 62 : BindingExpression (hash=45377043): Attach to System.Windows.Media.SolidColorBrush.Color (hash=48519443)
System.Windows.Data Warning: 64 : BindingExpression (hash=45377043): Use Framework mentor <null>
System.Windows.Data Warning: 67 : BindingExpression (hash=45377043): Resolving source
System.Windows.Data Warning: 69 : BindingExpression (hash=45377043): Framework mentor not found
System.Windows.Data Warning: 65 : BindingExpression (hash=45377043): Resolve source deferred
...
System.Windows.Data Warning: 67 : BindingExpression (hash=45377043): Resolving source
System.Windows.Data Warning: 69 : BindingExpression (hash=45377043): Framework mentor not found
System.Windows.Data Warning: 67 : BindingExpression (hash=45377043): Resolving source
System.Windows.Data Warning: 69 : BindingExpression (hash=45377043): Framework mentor not found
System.Windows.Data Warning: 67 : BindingExpression (hash=45377043): Resolving source (last chance)
System.Windows.Data Warning: 69 : BindingExpression (hash=45377043): Framework mentor not found
System.Windows.Data Error: 2 : Cannot find governing FrameworkElement or FrameworkContentElement for target element. BindingExpression:(no path); DataItem=null; target element is 'SolidColorBrush' (HashCode=48519443); target property is 'Color' (type 'Color')
I understand it what when datatemplate creates elements, mentor for binding to source is not found (what is mentor?), so binding creating is deffered. Then it repeats few times and fails with given error. But then it works at the end, perhaps it continues repeating without tracing it? Any ideas?
回答1:
Unfortunately I cannot give you exact specifics on why the binding error occurs and why the binding ultimately works, but perhaps I'll be able to shed some light on it.
This is what seems to be happening:
Because you're using a binding without specifying a source, by default the framework tries to use FrameworkElement.DataContext
or FrameworkContentElement.DataContext
property on the target as the source for the binding. That obviously fails because SolidColorBrush
derives from neither. Moreover, since SolidColorBrush
is not part of the visual tree nor the logical tree, it cannot be tied back to the Border
, hence the framework cannot resolve the source for the binding. Not sure though how it happens that at some point the source is resolved and the binding is working correctly.
There is however a solution to this problem, which was introduced specifically to address this kind of situations, and which uses other means than visual or logical tree to resolve binding sources. All you need to do is to define your SolidColorBrush
as a resource:
<Border Width="20" Height="20">
<Border.Resources>
<SolidColorBrush x:Key="BackgroundBrush" Color="{Binding}" />
</Border.Background>
<Border.Background>
<StaticResource ResourceKey="BackgroundBrush" />
</Border.Background>
</Border>
By doing so you get one major difference in the trace which seems to be the key to not getting the Error: 2
:
...
System.Windows.Data Warning: 65 : BindingExpression (hash=38517915): Resolve source deferred
System.Windows.Data Warning: 95 : BindingExpression (hash=38517915): Got InheritanceContextChanged event from SolidColorBrush (hash=55584612)
...
This solution is applicable not only to SolidColorBrush
, but to any object of type deriving from Freezable
(brushes, transforms, etc.)
You have to be careful though because it makes a difference in which resource dictionary you place your Freezable
. If you were to place it in the Window.Resources
dictionary the source would resolve to Window.DataContext
(a ViewModel
instance in your case).
My final hypothesis is that if you use this technique, the bindings set on your Freezable
are resolved as if they were set on the resource dictionary owner (which by the way I believe is referred to as mentor or governing element). That also applies to bindings using RelativeSource
or ElementName
.
来源:https://stackoverflow.com/questions/40507978/datatemplate-binding-spam-output-window-with-error-cannot-find-governing-framew