【问题标题】:Get Binding Source object from binding using ElementName使用 ElementName 从绑定中获取绑定源对象
【发布时间】:2014-02-25 21:32:39
【问题描述】:

我需要将一些东西绑定到我的 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;
      } 
  }

在为绑定的 ElementName 值指定名称后,我不想在 ProvideValue 中找到 DataGrid(绑定的源对象),

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

【问题讨论】:

  • 你能展示一下你打算如何使用它以及你想绑定什么吗?
  • 了解绑定源的唯一方法是使用 BindingOperations.GetBindingExpression 方法从绑定中获取 BindingExpression。但是您只能使用指定的绑定目标来执行此操作,因此它不适用于您的情况。

标签: wpf binding visual-tree


【解决方案1】:

您可以在标记扩展提供值方法中获取 DataGrid 实例,但 FindMe Control 您将无法使用 VisualTree 扩展方法获得,因为当这方法被调用,当时没有创建 dataGrid 的可视化树

此外,逻辑树也没有任何帮助,因为 Control 是 Visual 子级,而不是 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。 (尚未创建视觉树)。

【讨论】:

  • 这是我没有想到数据网格尚未加载的问题,我的问题是我不想将命令目标传播到网格的模板部分,任何想法这是怎么做到的,我们可以开始讨论吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-07-14
  • 1970-01-01
  • 2012-02-25
  • 2012-10-12
  • 1970-01-01
  • 2011-01-11
  • 2013-02-23
相关资源
最近更新 更多