WPF 因设置不期望的DataContext,导致的绑定异常

在MainWindow中,创建一个背景属性BrushTest,并将其绑定至界面上UserControl的BackgroundTest属性

1 <Window x:Class="WpfApp8.MainWindow" 2         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 3         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 4         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 5         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 6         xmlns:local="clr-namespace:WpfApp8" 7         mc:Ignorable="d" 8         Title="MainWindow" Height="450" Width="800" x:Name="TheMainWindow"> 9     <Grid>10         <local:UserControl1 BackgroundTest="{Binding BrushTest}"/>11     </Grid>12 </Window>
1     public partial class MainWindow : Window 2     { 3         public MainWindow() 4         { 5             InitializeComponent(); 6             BrushTest = Brushes.Red; 7             this.DataContext = this; 8         }10         public static readonly DependencyProperty BrushTestProperty = DependencyProperty.Register(11             "BrushTest", typeof(SolidColorBrush), typeof(MainWindow), new PropertyMetadata(default(SolidColorBrush)));13         public SolidColorBrush BrushTest14         {15             get { return (SolidColorBrush) GetValue(BrushTestProperty); }16             set { SetValue(BrushTestProperty, value); }17         }18     }

UserControl,同样添加一个BackgroundTest属性,并将其绑定至界面。

1 <UserControl x:Class="WpfApp8.UserControl1" 2              xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 3              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 4              xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"  5              xmlns:d="http://schemas.microsoft.com/expression/blend/2008"  6              xmlns:local="clr-namespace:WpfApp8" 7              mc:Ignorable="d"  8              d:DesignHeight="450" d:DesignWidth="800"> 9     <Grid Background="{Binding BackgroundTest}">10     </Grid>11 </UserControl>
1     public partial class UserControl1 : UserControl 2     { 3         public UserControl1() 4         { 5             InitializeComponent(); 6             this.DataContext = this; 7         } 8         public static readonly DependencyProperty BackgroundTestProperty = DependencyProperty.Register( 9             "BackgroundTest", typeof(SolidColorBrush), typeof(UserControl1), new PropertyMetadata(default(SolidColorBrush)));10         public SolidColorBrush BackgroundTest11         {12             get { return (SolidColorBrush) GetValue(BackgroundTestProperty); }13             set { SetValue(BackgroundTestProperty, value); }14         }15     }

运行后,控制台输出绑定异常,背景设置并没有生效。

System.Windows.Data Error: 40 : BindingExpression path error: 'BrushTest' property not found on 'object' ''UserControl1' (Name='')'.

BindingExpression:Path=BrushTest; DataItem='UserControl1' (Name=''); target element is 'UserControl1' (Name=''); target property is 'BackgroundTest' (type 'SolidColorBrush')

为何错了?

因为UserControl设置了俩次DataContext,UserControl1内部设置的上下文覆盖了主窗口设置的上下文。

窗口内<local:UserControl1 BackgroundTest="{Binding BrushTest}"/>绑定的值BrushTest,在UserControl下的上下文无法找到相关值,所以报错了

此类绑定异常,一不小心还是很容易出现的。

在窗口设置了DataContext时(自身或者ViewModel),子控件也设置DataContext。有趣的是,在Xaml编辑时,使用Reshaper链接到的是窗口所在的上下文属性。

所以,子控件设置DataContext时,需要关注下是否有属性被引用绑定外界数据。

建议子控件减少DataContext的使用,以上可以通过指定数据源进行绑定。比如:

1 <UserControl x:Class="WpfApp8.UserControl1" 2              xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 3              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 4              xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"  5              xmlns:d="http://schemas.microsoft.com/expression/blend/2008"  6              xmlns:local="clr-namespace:WpfApp8" 7              mc:Ignorable="d"  8              d:DesignHeight="450" d:DesignWidth="800" x:Name="TheUserControl"> 9     <Grid Background="{Binding ElementName=TheUserControl,Path=BackgroundTest}">10     </Grid>11 </UserControl>
(0)

相关推荐