I'm trying to bind my usercontrol datacontext to the viewmodel object. For unknown reason setting the DataContext inside the Window.Resources as a result gives
System.Windows.Data Error: 3 : Cannot find element that provides DataContext. BindingExpression:Path=AreaFilter; DataItem=null;
setting the same datacontext outside of the window.resources works perfect. Piece of code should clear the things up:
<Window>
<Window.Resources>
<GridViewColumnCollection x:Key="eventColumns">
<GridViewColumn DisplayMemberBinding="{Binding Path=Area}">
<GridViewColumn.Header>
<v:FilterV DataContext="{Binding AreaFilter}"/> <!--here is the problem-->
</GridViewColumn.Header>
</GridViewColumn>
</GridViewColumnCollection>
</Window.Resources>
<Grid>
<v:FilterV DataContext="{Binding AreaFilter}"/> <!-- here it works OK -->
<GridViewHeaderRowPresenter Name="listHeader" Columns="{StaticResource eventColumns}"/>
</Grid>
FilterV is a UserControl that I simplified currently to show just a textblock. Inside a Grid it shows the AreaFilter.Name with no problem. What's the difference when setting the DataContext in these two situations and how to solve that?
I believe GridViewColumn is not actually part of the VisualTree, so bindings in it won't work because it doesn't have a DataContext or source to use when evaluating the bindings.
You can try setting the DataContext with a RelativeSource binding that references your GridView
<GridViewColumn.HeaderTemplate>
<DataTemplate>
<v:FilterV DataContext="{Binding DataContext.AreaFilter,
RelativeSource={RelativeSource AncestorType={x:Type GridView}}}"/>
</DataTemplate>
</GridViewColumn.HeaderTemplate>
Although if that doesn't work the only workaround I've found is to create a Freezeable object in your .Resources containing the binding you're looking for, then setting your v:FilterV.DataContext to the static resource
<GridView.Resources>
<local:BindingProxy x:Key="proxy"
Data="{Binding AreaFilter, ElementName=MyGridView}" />
</DataGrid.Resources>
...
<GridViewColumn.HeaderTemplate>
<DataTemplate>
<v:FilterV DataContext="{Binding Source={StaticResource proxy}}"/>
</DataTemplate>
</GridViewColumn.HeaderTemplate>
You can view an example of this here
Also, you should set the GridViewHeaderTemplate property to a DataTemplate containing your <v:FilterV /> control instead of setting it directly in the .Content property like you have it now. Setting the Content directly to an object means that any item that uses that style will try to use the same controls in the Content, so if you have more than one object that applies that Content property it will throw an exception because items can only belong to one parent control
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With