如何绑定到最后一个父母

时间:2011-06-18 12:25:53

标签: c# wpf xaml binding

{RelativeSource FindAncestor, AncestorType={x:Type TypeName}, AncestorLevel=???}我应该设置AncestorLevel到达最后一位父母的值是多少?

e.g。我想要StackPanel类型的最后一个父。

编辑:如果不可能,我该怎么办?

2 个答案:

答案 0 :(得分:2)

据我所知,无法指定。

答案 1 :(得分:1)

不,不可能使用FindAncestor绑定到最后一个祖先,但是可以编写一个MarkupExtension来完成此任务。

这是一个简单的例子,您可以根据需要进行扩展

  class BindLastAncestor : MarkupExtension
  {
    public BindLastAncestor()
    {
    }

    public BindLastAncestor( Type ancestorType )
    {
    }

    public Type AncestorType
    {
      get;
      set;
    }

    public PropertyPath Path
    {
      get;
      set;
    }

    public override object ProvideValue( IServiceProvider serviceProvider )
    {
      var targetProvider = (IProvideValueTarget)serviceProvider.GetService(typeof(IProvideValueTarget));

      var target = targetProvider.TargetObject as DependencyObject;
      var targetProperty = targetProvider.TargetProperty as DependencyProperty;
      if (target == null || targetProvider == null)
        throw new NotSupportedException();

      var ancestor = target;
      DependencyObject lastAncestor = null;

      while (ancestor != null)
      {
        if (ancestor.GetType() == this.AncestorType)
          lastAncestor = ancestor;

        ancestor = VisualTreeHelper.GetParent(ancestor);
      }

      BindingOperations.SetBinding(target, targetProperty, new Binding { Path = this.Path, Source = lastAncestor });

      return target.GetValue(targetProperty);
    }
  }

现在可以这样使用,例如:

  <Grid x:Name="Grid1">
    <Grid x:Name="Grid2">
      <Grid x:Name="Grid3">
        <Grid x:Name="Grid4">
          <Grid x:Name="Grid5">
            <TextBox Text="{my:BindLastAncestor Path=Name, AncestorType=Grid}" />
          </Grid>
        </Grid>
      </Grid>
    </Grid>
  </Grid>

获取'Grid1'

的TextBox中的结果