Reputation: 413
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>
Upvotes: 6
Views: 5314
Reputation: 413
I was too fast with my comment the post ahead (I deleted it). Both ways are working, but when I try to do it with a Dictionary BOTH are not working.
This works:
<CheckBox Content="Test" IsChecked="{Binding Path=Data.TestCheck, Source={StaticResource proxy}, UpdateSourceTrigger=PropertyChanged, Mode=OneWay}"/>
This not:
<CheckBox Content="Test" IsChecked="{Binding Path=Data.MyCheckState[MachineName], Source={StaticResource proxy}, UpdateSourceTrigger=PropertyChanged, Mode=OneWay}"/>
The two Properties are defined like this:
public Dictionary<string, bool> MyCheckState
{
get { return _MyCheckState; }
}
public bool TestCheck
{
get { return true; }
}
Upvotes: -1
Reputation: 81313
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.
Upvotes: 7