Domanda

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 ?

È stato utile?

Soluzione

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).

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top