I have a problem with binding a value in the Resource of a DataGrid. Outside of the resources-Tag it works perfectly, but inside it doesn't work. I think maybe the Datacontext changed or is null. I don't know what to do. I read something about freezables, but I didn't get them to work too. Is that the solution or is that, what I'm doing not possible. Here my code with the non-working and the working part - just for demonstration. I need the Contextmenu in the Resources-Section to get it only, if clicked on the header-row.
<UserControl x:Class="testapp.test.testManager.Window"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:testapp.test.testManager"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="600"
DataContext="{Binding RelativeSource={RelativeSource Mode=Self}}">
<Grid>
<DataGrid ItemsSource="{Binding Lst, UpdateSourceTrigger=PropertyChanged}"
AutoGeneratingColumn="dg_AutoGeneratingColumn">
<DataGrid.Resources>
<ContextMenu x:Key="DataGridColumnHeaderContextMenu">
<MenuItem Header="{StaticResource General}">
<!-- HERE the Binding cannot find "TestCheck" -->
<CheckBox Content="Testentry Header" IsChecked="{Binding TestCheck, UpdateSourceTrigger=PropertyChanged,Mode=OneWay}"/>
<!-- ... --->
</MenuItem>
</ContextMenu>
<Style TargetType="{x:Type DataGridColumnHeader}">
<Setter Property="ContextMenu" Value="{StaticResource DataGridColumnHeaderContextMenu}" />
</Style>
</DataGrid.Resources>
<DataGrid.ContextMenu>
<ContextMenu>
<MenuItem Header="{StaticResource General}">
<!-- Here the Binding can find "TestCheck" -->
<CheckBox Content="Testentry" IsChecked="{Binding TestCheck, UpdateSourceTrigger=PropertyChanged,Mode=OneWay}"/>
<!-- ... -->
</MenuItem>
</ContextMenu>
</DataGrid.ContextMenu>
</DataGrid>
</Grid>
Issue is ContextMenu
doesn't lie in same Visual tree as that of DataGrid and hence can't inherit DataContext of DataGrid.
You can use x:Reference
to get the DataGrid instance and bind with it's DataContext. (x:Reference is available from WPF 4.0)
Give x:Name
to dataGrid and bind with it:
<DataGrid ItemsSource="{Binding Lst, UpdateSourceTrigger=PropertyChanged}"
x:Name="dataGrid">
<DataGrid.Resources>
<ContextMenu x:Key="DataGridColumnHeaderContextMenu">
<MenuItem Header="{StaticResource General}">
<CheckBox Content="Testentry Header"
IsChecked="{Binding DataContext.TestCheck,
Source={x:Reference dataGrid}}"/>
....
</DataGrid>
Also you can achieve that using Freezable
class like you mentioned in question. Refer to my answer over here for the details to achieve that via Freezable.