ElementName属性使用

今天在写自定义控件的时候,通过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 属性还可以显式设置绑定源。 但是,对于每个绑定,只能设置 ElementNameSource 和 RelativeSource 这三个属性中的一个,否则可能发生冲突。 如果存在绑定源冲突,则此属性将引发异常。以上主要以参考MSDN为主,同时结合我自己的例子说的!不足之处请指教。

原文地址:https://www.cnblogs.com/Yukang1989/p/2690689.html