Datatemplate binding spam Output window with error: Cannot find governing FrameworkElemen
Datatemplate binding spam Output window with error: Cannot find governing FrameworkElemen
我有问题
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')
可以通过以下方式复制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>
和 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;
}
}
开始,按F1并勾选Output
window(绑定跟踪已启用,所以你会看到更多)。
问题:我该如何修复它们?
错误不会对功能造成问题,但它们出现在 Output
window 中(在实际项目中有很多),这已经是一些问题的迹象。哪个问题?
这里的关键是要有数据模板并应用它稍后,那么数据模板中的这种绑定会导致问题。在构造函数中设置 DataContext
不会导致问题。
这里有一些痕迹,如果有人能够理解它并可以给出一些提示:
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')
我理解当数据模板创建元素时,mentor 找不到用于绑定到源的内容(什么是 mentor?),因此绑定创建被推迟。然后它重复几次并因给定错误而失败。但是最后它起作用了,也许它会继续重复而不跟踪它?有什么想法吗?
遗憾的是,我无法向您详细说明绑定错误发生的原因以及绑定最终有效的原因,但也许我可以阐明它。
这似乎是正在发生的事情:
因为您使用的是未指定源的绑定,默认情况下框架会尝试在目标上使用 FrameworkElement.DataContext
或 FrameworkContentElement.DataContext
属性 作为绑定的源。这显然失败了,因为 SolidColorBrush
两者都不派生。此外,由于 SolidColorBrush
既不是可视化树的一部分,也不是逻辑树的一部分,因此无法将其绑定回 Border
,因此框架无法解析绑定的源。不确定在某些时候源已解析且绑定正常工作是如何发生的。
但是有一个解决这个问题的方法,它是专门为解决这种情况而引入的,它使用可视化或逻辑树以外的其他方法来解析绑定源。您需要做的就是将您的 SolidColorBrush
定义为资源:
<Border Width="20" Height="20">
<Border.Resources>
<SolidColorBrush x:Key="BackgroundBrush" Color="{Binding}" />
</Border.Background>
<Border.Background>
<StaticResource ResourceKey="BackgroundBrush" />
</Border.Background>
</Border>
通过这样做,您会在跟踪中发现一个主要差异,这似乎是不获取 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)
...
此解决方案不仅适用于 SolidColorBrush
,而且适用于派生自 Freezable
的任何类型的对象(画笔、变换等)
不过您必须小心,因为 它会有所不同 您将 Freezable
放在哪个资源字典中。如果您将它放在 Window.Resources
字典中,源将解析为 Window.DataContext
(在您的情况下是 ViewModel
实例)。
我的最终假设是,如果您使用此技术,Freezable
上设置的绑定将被解析 就好像 它们是在资源字典所有者(顺便说一下,我认为它被称为 mentor 或 governing 元素)。这也适用于使用 RelativeSource
或 ElementName
.
的绑定
我有问题
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')
可以通过以下方式复制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>
和 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;
}
}
开始,按F1并勾选Output
window(绑定跟踪已启用,所以你会看到更多)。
问题:我该如何修复它们?
错误不会对功能造成问题,但它们出现在 Output
window 中(在实际项目中有很多),这已经是一些问题的迹象。哪个问题?
这里的关键是要有数据模板并应用它稍后,那么数据模板中的这种绑定会导致问题。在构造函数中设置 DataContext
不会导致问题。
这里有一些痕迹,如果有人能够理解它并可以给出一些提示:
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')
我理解当数据模板创建元素时,mentor 找不到用于绑定到源的内容(什么是 mentor?),因此绑定创建被推迟。然后它重复几次并因给定错误而失败。但是最后它起作用了,也许它会继续重复而不跟踪它?有什么想法吗?
遗憾的是,我无法向您详细说明绑定错误发生的原因以及绑定最终有效的原因,但也许我可以阐明它。
这似乎是正在发生的事情:
因为您使用的是未指定源的绑定,默认情况下框架会尝试在目标上使用 FrameworkElement.DataContext
或 FrameworkContentElement.DataContext
属性 作为绑定的源。这显然失败了,因为 SolidColorBrush
两者都不派生。此外,由于 SolidColorBrush
既不是可视化树的一部分,也不是逻辑树的一部分,因此无法将其绑定回 Border
,因此框架无法解析绑定的源。不确定在某些时候源已解析且绑定正常工作是如何发生的。
但是有一个解决这个问题的方法,它是专门为解决这种情况而引入的,它使用可视化或逻辑树以外的其他方法来解析绑定源。您需要做的就是将您的 SolidColorBrush
定义为资源:
<Border Width="20" Height="20">
<Border.Resources>
<SolidColorBrush x:Key="BackgroundBrush" Color="{Binding}" />
</Border.Background>
<Border.Background>
<StaticResource ResourceKey="BackgroundBrush" />
</Border.Background>
</Border>
通过这样做,您会在跟踪中发现一个主要差异,这似乎是不获取 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)
...
此解决方案不仅适用于 SolidColorBrush
,而且适用于派生自 Freezable
的任何类型的对象(画笔、变换等)
不过您必须小心,因为 它会有所不同 您将 Freezable
放在哪个资源字典中。如果您将它放在 Window.Resources
字典中,源将解析为 Window.DataContext
(在您的情况下是 ViewModel
实例)。
我的最终假设是,如果您使用此技术,Freezable
上设置的绑定将被解析 就好像 它们是在资源字典所有者(顺便说一下,我认为它被称为 mentor 或 governing 元素)。这也适用于使用 RelativeSource
或 ElementName
.