views:

1147

answers:

2

I have a DataGrid which I am binding to a PagedCollectionView which is Grouped and Sorted. The contents of the DataGrid are not editable although one column contains a clickable link.
I have restricted the SelectionMode of the DataGrid to DataGridSelectionMode.Single which stops multiple Row selection which is good. But the selected row also has a selected Cell which draws in a slightly lighter colour than the rest of the selected row and has a border.

Basically I'd like to have a SelectedRow but not a SelectedCell (from a UI/Display perspective).

It feels like it should be simple matter of setting a property, but I get the feeling maybe I have to edit the DataGrids template and/or mess with the VisualStateManager.

I'm happy to switch to another control other than DataGrid but I do need to be able to display Grouping.

A: 

I found 'a' way of making the individual cells appear to be not selected, although I'm not sure if its the best way.
Edit the CellStyle for the DataGrid, Find the Rectangle named FocusVisual. This is the Rectangle thats used to indicate a selected Cell. Set its Fill & Stroke to Transparent, I also set its StrokeThickness to 0. Don't delete the Rectangle entirely because other things are expecting it to be there. The xaml looked something like this:

    <Style x:Key="NonSelectableDataGridCellStyle" TargetType="data:DataGridCell">
  <Setter Property="Background" Value="Transparent"/>
  <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
  <Setter Property="VerticalContentAlignment" Value="Stretch"/>
  <Setter Property="IsTabStop" Value="False"/>
  <Setter Property="Template">
   <Setter.Value>
    <ControlTemplate TargetType="data:DataGridCell">
     <Grid x:Name="Root" Background="{TemplateBinding Background}">
      <Grid.ColumnDefinitions>
       <ColumnDefinition/>
       <ColumnDefinition Width="Auto"/>
      </Grid.ColumnDefinitions>
      <VisualStateManager.VisualStateGroups>
       <VisualStateGroup x:Name="CurrentStates">
        <VisualState x:Name="Regular"/>
        <VisualState x:Name="Current">
         <Storyboard>
          <DoubleAnimation Duration="0" 
           Storyboard.TargetName="FocusVisual" 
           Storyboard.TargetProperty="Opacity" To="1"/>
         </Storyboard>
        </VisualState>
       </VisualStateGroup>
       <VisualStateGroup x:Name="ValidationStates">
        <VisualState x:Name="Valid"/>
        <VisualState x:Name="Invalid">
         <Storyboard>
          <DoubleAnimation Duration="0" Storyboard.TargetName="InvalidVisualElement" Storyboard.TargetProperty="Opacity" To="1"/>
          <ColorAnimation Duration="0" Storyboard.TargetName="FocusVisual" Storyboard.TargetProperty="(Fill).Color" To="#FFFFFFFF"/>
         </Storyboard>
        </VisualState>
       </VisualStateGroup>
      </VisualStateManager.VisualStateGroups>
      <Rectangle x:Name="FocusVisual" 
       Fill="Transparent"
       Stroke="Transparent"
       StrokeThickness="0" 
       HorizontalAlignment="Stretch" 
       VerticalAlignment="Stretch" 
       IsHitTestVisible="false" 
       Opacity="0"
                                   />
      <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" Content="{TemplateBinding Content}" ContentTemplate="{TemplateBinding ContentTemplate}"/>
      <Rectangle x:Name="InvalidVisualElement" Stroke="#FFDC000C" StrokeThickness="1" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" IsHitTestVisible="False" Opacity="0"/>
      <Rectangle x:Name="RightGridLine" VerticalAlignment="Stretch" Width="1" Grid.Column="1"/>
     </Grid>
    </ControlTemplate>
   </Setter.Value>
  </Setter>
 </Style>

and you add the CellStyle to the DataGrid

<data:DataGrid x:Name="uiDataGrid" 
           CellStyle="{StaticResource NonSelectableDataGridCellStyle}"
           >
     ...
</data:DataGrid>
Scott
A: 

You can also add "invisible" column:

    <sdk:DataGrid.Columns>
    <sdk:DataGridTextColumn Binding="{Binding Path=Nothing}" MinWidth="0" MaxWidth="0" />

And make it current whenever current cell is changed:

Private Sub _CurrentCellChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.CurrentCellChanged
    If Me.CurrentColumn IsNot Nothing Then Me.CurrentColumn = Me.Columns(0)
End Sub

This was suitable for me.