Question

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>

Was it helpful?

Solution

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.

OTHER TIPS

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; }
    }
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top