使用ElementName从绑定中获取绑定源对象

时间:2014-02-02 10:56:28

标签: wpf binding visual-tree

我需要将某些东西绑定到我的VisualTree中的元素的子元素。

用户控件中的

  <StackPanel>
      <DataGrid x:Name="dataGrid" />
      <Control Tag="{Binding ElementName=dataGrid}" />
  </StackPanel>

在DataGrid的模板中:

  <Template TargetType=DataGrid>
       ......
       <Control x:Name="FindMe" />
       ......
  </Template>

我想做的是遍历DataGrid的VisualTree,为此目的,我创建了一个 自定义标记扩展名:

 public class TemplatePartBinding : MarkupExtension
 {
      public override object ProvideValue(IServiceProvider serviceProvider)
      {
        Binding binding = new Binding();
        binding.ElementName = ElementName;

        // HOW DO I GET THE SOURCE OBJECT FROM THE BINDING ?
         DataGrid dataGrid = // Extract the DataGrid from the binding. 

         Control _findMe = VisualTreeHelperExtentions.FindVisualChild<Control>(dataGrid,"FindMe");

         binding.Target = _findMe;
         binding.Path = new PropertyPath("Tag");

       return binding;
      }

      [ConstructorArgument("ElementName")]
      public string ElementName
          {
           get;
           set;
      }

      [ConstructorArgument("TemplatePartName")]
      public string TemplatePartName
      {
           get;
           set;
      } 
  }

这里在ProvideValue中,在给出绑定的ElementName值后,我不想找到DataGrid(绑定的源对象),

如何从刚刚创建的绑定中提取DependencyObject(My DataGrid)?

1 个答案:

答案 0 :(得分:2)

您可以在标记扩展中提供DataGrid实例提供值方法但 FindMe Control将无法使用VisualTree扩展方法因为当调用此方法时, 当时不会创建用于dataGrid的Visual Tree

另外,逻辑树也没有任何帮助,因为Control是Visual child而不是dataGrid的逻辑子。


但是,对于查找dataGrid的问题,您可以这样:

public override object ProvideValue(IServiceProvider serviceProvider)
{
    IRootObjectProvider provider = (IRootObjectProvider)serviceProvider
                                   .GetService(typeof(IRootObjectProvider));

    DataGrid dataGrid = 
      LogicalTreeHelper.FindLogicalNode((DependencyObject)provider.RootObject,
                                        ElementName) as DataGrid;
    ....
}

IRootObjectProvider会得到RootObject which will be UserControl并最终通过遍历LogicalTree而不是VisualTree来获取DataGrid,因为它将返回null。 (Visual Tree尚未创建)。