views:

95

answers:

1

I have a DataGrid (the official one) with SelectionUnit="Cell". When the user selects a cell, I'd like to show the row details for the corresponding row. This is apparently not the default behavior, and I can't seem to figure out how to accomplish this.

Here's my XAML:

<UserControl x:Class="View.Test"
            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" 
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300">
    <UserControl.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="../AppResources.xaml" />
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </UserControl.Resources>
    <Grid>
        <DataGrid AutoGenerateColumns="False" 
                ItemsSource="{Binding Path=Fields}" 
                BorderBrush="Transparent" 
                HeadersVisibility="Column"
                SelectionMode="Single"
                SelectionUnit="Cell"
                CanUserAddRows="False"
                CanUserDeleteRows="False"
                CanUserSortColumns="False"
                IsTextSearchEnabled="True"
                x:Name="EntryGrid"
                >
            <DataGrid.Columns>
                <DataGridTextColumn Header="Name" Binding="{Binding Path=Name}" Width="Auto" IsReadOnly="True"/>
                <DataGridTemplateColumn Header="Value" Width="Auto" x:Name="valueColumn" MinWidth="60" MaxWidth="90">
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <TextBlock Text="{Binding Path=DisplayValue}" TextTrimming="CharacterEllipsis" ToolTip="{Binding Path=Text, RelativeSource={RelativeSource Self}}"/>
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                    <DataGridTemplateColumn.CellEditingTemplate>
                        <DataTemplate>
                            <DockPanel>
                                <ComboBox TabIndex="1" HorizontalAlignment="Stretch" VerticalAlignment="Center" SelectedValue="{Binding Path=Value, UpdateSourceTrigger=PropertyChanged}" SelectedValuePath="Value" ItemsSource="{Binding Path=FieldOptions}" Visibility="{Binding Path=FieldOptions, Converter={StaticResource EmptyCollectionIsInvisibleConverter}}" />
                                <TextBox TabIndex="2" Text="{Binding Value, UpdateSourceTrigger=PropertyChanged}" VerticalAlignment="Center" HorizontalAlignment="Stretch" Visibility="{Binding Path=FieldOptions, Converter={StaticResource NonEmptyCollectionIsInvisibleConverter}}"/>
                            </DockPanel>
                        </DataTemplate>
                    </DataGridTemplateColumn.CellEditingTemplate>
                </DataGridTemplateColumn>
                <DataGridTemplateColumn Header="Description" IsReadOnly="True" Width="*" >
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <TextBlock Text="{Binding Description}" TextWrapping="Wrap" />
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>
            </DataGrid.Columns>
            <DataGrid.RowDetailsTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding Path=Help}" />
                </DataTemplate>
            </DataGrid.RowDetailsTemplate>
        </DataGrid>
    </Grid>
</UserControl>
A: 

You can set the SelectionUnit to FullRow

SelectionUnit="FullRow"

or you can handle the selection event and set the visibility on event handling.

    private void EntryGrid_SelectedCellsChanged(object sender, SelectedCellsChangedEventArgs e)
    {
        foreach (var cell in e.AddedCells)
        ((DataGridRow)EntryGrid.ItemContainerGenerator.ContainerFromItem(cell.Item)).DetailsVisibility = System.Windows.Visibility.Visible;
        foreach (var cell in e.RemovedCells)
            ((DataGridRow)EntryGrid.ItemContainerGenerator.ContainerFromItem(cell.Item)).DetailsVisibility = System.Windows.Visibility.Collapsed;
    }

Insert disparaging remarks about the WPF DataGrid here.

jrwren
Wow, how did you figure that out? It seems like there's very little information about the DataGrid out there. I'd appreciate links to any articles or samples you've found useful. It's such a simple piece of code, and I'd have never found it.
notJim
I've been working with the DataGrid a lot for the past 2 months. I've found exactly what you just said: there's very little information past the basics. Its VERY useful to just dive into the WPF Toolkit source.
jrwren