First a brief "abstracted" short version of my problem. Probably not needed to discuss a solution, but below some further "optional" infos of the real underlying problem I'm having, just to understand the context.
So: I have a ContentPresenter using a DataTemplate to generate its layout for bound items. Now, outside of this contentpresenter, I'm trying to bind within an Element by name within that content presenter.
Assume the following Pseudo-XAML (MainTextBlock's binding won't work in practice):
<TextBlock Text="{Binding Text, ElementName=MyTextblock, Source = ???}" DataContext="{x:Reference TheContentPresenter}" x:Name="MainTextblock"/>
<ContentPresenter Content="{Binding SomeItem}" x:Name="TheContentPresenter">
<ContentPresenter.ContentTemplate>
<DataTemplate>
<TextBlock x:Name="MyTextblock" Text="Test"/>
</DataTemplate>
</ContentPresenter.ContentTemplate>
</ContentPresenter>
!! Please assume that the DataContext of MainTextblock MUST be (a reference to) TheContentPresenter !!
Given that assumption, how can I make the binding on MainTextblock work?
I can't bind to the ContentPresenter's Content property, because that contains the bound element (e.g. SomeItem), not its visual representation. Unfortunately, ContentPresenter doesn't seem to have any property representing its Visual Tree / Visual Children.
Is there any way to do this?
Now what do I really need this for? Feel free to skip reading this, it shouldn't be needed to discuss a solution of above's problem I believe.
I'm writing a behavior that adds customizable filters to a DataGrid:
<DataGrid AutoGenerateColumns="False">
<i:Interaction.Behaviors>
<filter:FilterBehavior>
<filter:StringFilter Column="{x:Reference FirstCol}" Binding="{Binding DataContext.Value1}"/>
<filter:StringFilter Column="{x:Reference SecondCol}" Binding="{??????? bind to Content -> Visual Children -> Element With Name "MyTextBlock" -> Property "Text"}"/>
</filter:FilterBehavior>
</i:Interaction.Behaviors>
<DataGrid.Columns>
<DataGridTextColumn x:Name="FirstCol" Header="Test" Binding="{Binding Value1}"/>
<DataGridTemplateColumn x:Name="SecondCol" Header="Test 2">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock x:Name="MyTextblock" Text="{Binding Value2}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
"FilterBehavior" contains individual filters for each column, e.g. the first of them would be a filter that allows to search text within whatever column its bound to (FirstCol in this case), and hides columns where that text doesn't appear.
Now, Binding is the interesting part. The Binding property is of type BindingBase (so the binding is "deferred"). It's intended to define the value which is used for filtering. When filtering is supposed to occur, each filter loops through all DataGridCells of the column its bound to. For each DataGridCell, it sets the Binding's DataContext to the respective DataGridCell, and evaluates the binding.
So, the StringFilter would loop through each DataGridCell in FirstCol. For Each of them, it would retreive BindingBase "Binding" (i.e. {Binding DataContext.Value1}), set its DataContext to the DataGridCell, and evaluate this. So in that case, it would bind to WpfGridCell.DataContext.Value1, or in other words to the Value1 property of the item the DataGridCell contains. Later on, it will check if these evaluated items match the String that the user entered for filtering.
This works just fine.
However, I'm having trouble when trying to bind to the DataGridCell's visual content, as in the case of the second StringFilter with Column="{x:Reference SecondCol}". SecondCol is a DataGridTemplateColumn. It's cells content will be a ContentPresenter, whose template is DataGridTemplateColumn.CellTemplate, and whose Content is the element that the cell contains.
And this is where we get back to my simplified version from above. I now need to evaluate "Binding" with DataContext = DataGridCell, and somehow come up with a binding that let's me bind to the visual elements of the ContentPresenter that is given in DataGridCell.Content.
Thanks!
DataTemplate
outside theContentPresenter
and use it as StaticResource. Make sure, you declare the DT before using it – lokusking