1

I need to bind something to a child of an element in my VisualTree .

in a UserControl:

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

in DataGrid's Template :

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

What i thought of doing is traversing the VisualTree of the DataGrid , for this purpose iv'e created a custom markup extension :

 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;
      } 
  }

Here in ProvideValue i wan't to locate the DataGrid (Source Object for the binding ) after giving the binding's ElementName value it's name ,

How do i extract the DependencyObject (My DataGrid) from the binding iv'e just created ?

eran otzap
  • 12,293
  • 20
  • 84
  • 139
  • Can you show sample how you intend to use it and what you want to bind to? – Rohit Vats Feb 02 '14 at 11:02
  • The only way to know the binding source is get the BindingExpression from the binding using BindingOperations.GetBindingExpression method. But you can do it only with specified binding target so it doesn't work in your case. – neptunao Feb 02 '14 at 12:07

1 Answers1

2

You can get the DataGrid instance in markup extension provide value method but FindMe Control you won't be able to get with VisualTree extension methods because when this method gets called, Visual Tree for dataGrid is not created at that time.

Morever, logical tree won't be of any help either since Control is Visual child and not logical child of dataGrid.


However, for your question to find dataGrid, you can get like this:

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

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

IRootObjectProvider will get you RootObject which will be UserControl and eventually can get you DataGrid by traversing LogicalTree and not VisualTree since it will return null. (Visual Tree not created yet).

Rohit Vats
  • 79,502
  • 12
  • 161
  • 185
  • that is a problem i hadn't thought about that the data grid was not loaded yet , my problem is that i wan't to propagate a Command target to a template part of the grid , any ideas how this could be done , can we start a discussion ? – eran otzap Feb 02 '14 at 14:06