WPF 因设置不期望的DataContext,导致的绑定异常
在mainwindow中,创建一个背景属性brushtest,并将其绑定至界面
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 brushtest 14 { 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 backgroundtest 11 { 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>
下一篇: Angular实战记录--创建工程