I have checkboxes that represent the modules in my program that a user can access.
You can see from the DataGrid that the modules in the fourth column are created from "DataContext.ModuleCollection", where as the rows for the DataGrid are created from UserCollection. I would like the User_ID to be the content for each checkbox. This will be set in the checkbox style which I have attempted at the bottom without much success.
My issue is, the checkbox is at Module level (in the data) and I need to figure a way to get back to the User level to get the User_ID.
User_ID is part of the row's dataset, e.g. a User record.
How do I get User_ID in the below style is the question?
Below is my datagrid:
<DataGrid ItemsSource="{Binding UserCollection}" >
<DataGrid.Columns>
<DataGridTextColumn Header="Name" Binding="{Binding Path=Name}"/>
<DataGridTextColumn Header="Job Title" Binding="{Binding Path=Job_Title}"/>
<DataGridTextColumn Header="Company" Binding="{Binding Path=Company}"/>
<DataGridTemplateColumn CanUserReorder="True">
<DataGridTemplateColumn.Header>
<ItemsControl ItemsSource="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}, Path=DataContext.ModuleCollection}" >
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" Background="Transparent" CanVerticallyScroll="False" CanHorizontallyScroll="False"></StackPanel>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock Style="{StaticResource ListViewItemRotatedText}" Text="{Binding ModuleName}" >
</TextBlock>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</DataGridTemplateColumn.Header>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ItemsControl ItemsSource="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}, Path=DataContext.ModuleCollection}" >
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" Background="Transparent" CanVerticallyScroll="False" CanHorizontallyScroll="False"></StackPanel>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<CheckBox Style="{StaticResource ListViewItemCheckbox}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
Below is my check style:
<Style x:Key="ListViewItemCheckbox" TargetType="CheckBox">
<Setter Property="Content" Value="{Binding Path=User_ID, RelativeSource={RelativeSource AncestorType={x:Type DataGridRow}}}"/>
</Style>
Your current Binding Path
won't work because you're trying to access the User_ID
property from the DataGridRow
, which of course, doesn't have one... you should have an error in your Output Window in Visual Studio... pay close attention to these errors, as they'll help you fix your problems.
So what Binding Path
can you use? Well, you're right as far as the fact that we have to use a RelativeSource Binding
... try this instead:
<Style x:Key="ListViewItemCheckbox" TargetType="CheckBox">
<Setter Property="Content" Value="{Binding Path=DataContext.User_ID,
RelativeSource={RelativeSource AncestorType={x:Type DataGridRow}}}" />
</Style>
What we're attempting to do here is to data bind to the User_ID
value that should be found in the object set as the DataContext
of the DataGridRow
.
UPDATE >>>
Ahhh yeah, what I was thinking wouldn't work anyway as I was trying to bind to the whole collection and you need to bind to the current item. You're only getting these horrible problems though because of the way that you've organised (or disorganised) your data model. Those CheckBox
es should be data bound from one or more properties that are actually in your User class
and not in this separate collection. I'd fix your model now before you get worse problems.
UPDATE 2 >>>
You now want to know how to bind to the whole data object rather than a property from that object. For future reference, please see the PropertyPath XAML Syntax page on MSDN for more information. However, you just need to think about this... if DataContext.User_ID
gets you the User_ID
property value of a User
object, what do you think would return the whole User
object? That's right... just remove the property:
<Style x:Key="ListViewItemCheckbox" TargetType="CheckBox">
<Setter Property="Content" Value="{Binding Path=DataContext,
RelativeSource={RelativeSource AncestorType={x:Type DataGridRow}}}" />
</Style>