今天在写自定义控件的时候,通过DependencyProperty注册了一个Page属性,同时在Main.page中使用ElementName绑定数据,代码如下:
<local:QuickJumpGrid x:Name="QuickJumpGrid" Grid.Row="1" Margin="24,0,0,0" Page="{Binding ElementName=Page}" ItemSelected="QuickJumpGrid_ItemSelected" />
但是在后台使用this.Page取值一直为Null,一直抛出异常,代码如下:
if (this.Page == null) throw new InvalidOperationException( "The Page property must be set to the host page.");
感觉好奇怪,我检查我注册代码如下:
public static readonly DependencyProperty PageProperty = DependencyProperty.Register("Page", // name typeof(PhoneApplicationPage), // property type typeof(QuickJumpGrid), // owner type new PropertyMetadata( null, // default value new PropertyChangedCallback(OnPageChanged) // callback ) );
可以检查几遍都是正确的,纠结了1个多小时,最后发现{Binding ElementName=Page}中的Page在页面中并没有,于是我MSDN,查了下发现,其实没有设定x:Name=“Page”,这真无语,下面引用MSDN的话:
Name 属性的值或要使用的元素的 x:Name 指令。 只有通过 RegisterName 将元素注册到适当的 NameScope 后,才能在代码中引用这些元素。 有关更多信息,请参见 WPF XAML 名称范围。 默认值为 null。
其实,这很好理解,可能是当时忘了,在这里,我想拓展下:
如果要绑定到应用程序的另一个元素的属性,此属性很有用。 例如,如果您希望使用 Slider 控制应用程序中另一个控件的高度,或者如果您希望将控件的 Content 绑定到 ListBox 控件的 SelectedValue 属性。
例如,很多应用程序都有设置页面,常常需要有一个精度条控制当前页面显示的条数,同时为了直观显示,进度条上面会有一个TextBlock显示,这时候就要用到这样属性。
如下图:
默认情况下,如果已设置了 DataContext 属性,则绑定会继承该属性所指定的数据上下文。 但是,ElementName 属性是一种可以显式设置 Binding 的源和重写继承的数据上下文的方式。 有关更多信息,请参见如何:指定绑定源。
此外,使用 Binding 类的 Source 和 RelativeSource 属性还可以显式设置绑定源。 但是,对于每个绑定,只能设置 ElementName、Source 和 RelativeSource 这三个属性中的一个,否则可能发生冲突。 如果存在绑定源冲突,则此属性将引发异常。以上主要以参考MSDN为主,同时结合我自己的例子说的!不足之处请指教。