views:

3278

answers:

1

I've got a datagrid with one button in each row (xaml shown below). I'm trying to get rid of the blue highlighting functionality where it highlights the selected row, and the row with the mouse over it. I'm trying to seit it up so you just click on the button without getting the row selection and mouseover highlight functionality. I tried setting IsHitTestVisible to false, but then the button is not clickable. How can I do this?

<data:DataGrid x:Name="grdClinics"
               HorizontalAlignment="Left" 
               VerticalAlignment="Bottom" 
               AutoGenerateColumns="False"
               HeadersVisibility="None"
               RowHeight="55"
               Background="Transparent"
               AlternatingRowBackground="Transparent"
               RowBackground="Transparent"
               BorderBrush="Transparent"
               Foreground="Transparent" 
               GridLinesVisibility="None" 
               SelectionMode="Single">                         

    <data:DataGrid.Columns>
        <data:DataGridTemplateColumn Header="Clinic">
            <data:DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <Button x:Name="btnClinic" 
                            Height="46" 
                            Width="580" 
                            Content="{Binding Path=Description}" 
                            Style="{StaticResource ShinyButton}" 
                            Click="btnClinic_OnClick"
                            FontSize="24"
                            FontFamily="Tahoma"
                            FontWeight="Bold">
                        <Button.Background>
                            <LinearGradientBrush EndPoint="0.528,1.144" StartPoint="1.066,1.221">
                                <GradientStop Color="#FF000000"/>
                                <GradientStop Color="#FFEDC88F" Offset="1"/>
                            </LinearGradientBrush>
                        </Button.Background>
                    </Button>
                </DataTemplate>
            </data:DataGridTemplateColumn.CellTemplate>
        </data:DataGridTemplateColumn>
    </data:DataGrid.Columns>
</data:DataGrid>
+4  A: 

Hey Jeremy,

The short answer is to use styles. The long answer is the following:

There are two style properties in the Silverlight 2.0 datagrid that should solve your problem. The first is CellStyle and the second is RowStyle. The CellStyle property is the one which will remove the light blue highlight around the currently selected cell. The RowStyle property is the one where you will be able to remove the light blue shade indicating the selected row. The CellStyle that I used is as follows:

 <Style x:Key="CellStyle" TargetType="local:DataGridCell">
  <Setter Property="Background" Value="Transparent" />
  <Setter Property="HorizontalContentAlignment" Value="Stretch" />
  <Setter Property="VerticalContentAlignment" Value="Stretch" />
  <Setter Property="Cursor" Value="Arrow" />
  <Setter Property="IsTabStop" Value="False" />
  <Setter Property="Template">
   <Setter.Value>
    <ControlTemplate TargetType="local:DataGridCell">
     <Grid Name="Root" Background="Transparent">
      <vsm:VisualStateManager.VisualStateGroups>
       <vsm:VisualStateGroup x:Name="CurrentStates" >
        <vsm:VisualStateGroup.Transitions>
         <vsm:VisualTransition GeneratedDuration="0" />
        </vsm:VisualStateGroup.Transitions>

        <vsm:VisualState x:Name="Regular" />
        <vsm:VisualState x:Name="Current" />
         <!--<Storyboard>
          <DoubleAnimation Storyboard.TargetName="FocusVisual" Storyboard.TargetProperty="Opacity" To="1" Duration="0" />
         </Storyboard>
        </vsm:VisualState>-->
       </vsm:VisualStateGroup>
      </vsm:VisualStateManager.VisualStateGroups>
      <Grid.ColumnDefinitions>
       <ColumnDefinition Width="*" />
       <ColumnDefinition Width="Auto" />
      </Grid.ColumnDefinitions>
      <Rectangle Name="FocusVisual" Stroke="#FF6DBDD1" StrokeThickness="1" Fill="#66FFFFFF" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" IsHitTestVisible="false" Opacity="0" />
      <ContentPresenter Content="{TemplateBinding Content}" ContentTemplate="{TemplateBinding ContentTemplate}" Cursor="{TemplateBinding Cursor}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" Margin="{TemplateBinding Padding}" />
      <Rectangle Name="RightGridLine" Grid.Column="1" VerticalAlignment="Stretch" Width="1" />
     </Grid>
    </ControlTemplate>
   </Setter.Value>
  </Setter>
 </Style>

If you will notice, I commented out the storyboard that changed the FocusVisual rectangle's opacity value. What this was doing was to set the FocusVisual rectangle to be shown on cell selection. (Please Note: You cannot remove the FocusVisual Element as the CellPresenter is expecting this element, and not finding the element will cause an error.)

The RowStyle I used is as follows:

 <Style TargetType="local:DataGridRow" x:Key="MyCustomRow">
  <Setter Property="IsTabStop" Value="False" />
  <Setter Property="Template">
   <Setter.Value>
    <ControlTemplate TargetType="local:DataGridRow">
     <localprimitives:DataGridFrozenGrid x:Name="Root">
      <localprimitives:DataGridFrozenGrid.Resources>
       <Storyboard x:Key="DetailsVisibleTransition" >
        <DoubleAnimation Storyboard.TargetName="DetailsPresenter" Storyboard.TargetProperty="ContentHeight" Duration="00:00:0.1" />
       </Storyboard>
      </localprimitives:DataGridFrozenGrid.Resources>
      <vsm:VisualStateManager.VisualStateGroups>
       <vsm:VisualStateGroup x:Name="CommonStates" >
        <vsm:VisualState x:Name="Normal" />
        <vsm:VisualState x:Name="Normal AlternatingRow">
         <Storyboard>
          <DoubleAnimation Storyboard.TargetName="BackgroundRectangle" Storyboard.TargetProperty="Opacity" Duration="0" To="0" />
         </Storyboard>
        </vsm:VisualState>
        <vsm:VisualState x:Name="MouseOver" />
        <!--<Storyboard>
                                        <DoubleAnimation Storyboard.TargetName="BackgroundRectangle" Storyboard.TargetProperty="Opacity" Duration="0" To=".5" />
                                    </Storyboard>
                                </vsm:VisualState>-->
        <vsm:VisualState x:Name="Normal Selected"/>
        <!--<Storyboard>
                                        <DoubleAnimation Storyboard.TargetName="BackgroundRectangle" Storyboard.TargetProperty="Opacity" Duration="0" To="1" />
                                    </Storyboard>
                                </vsm:VisualState>-->
        <vsm:VisualState x:Name="MouseOver Selected"/>
        <!--<Storyboard>
                                        <DoubleAnimation Storyboard.TargetName="BackgroundRectangle" Storyboard.TargetProperty="Opacity" Duration="0" To="1" />
                                    </Storyboard>
                                </vsm:VisualState>-->
        <vsm:VisualState x:Name="Unfocused Selected"/>
        <!--<Storyboard>
                                        <DoubleAnimation Storyboard.TargetName="BackgroundRectangle" Storyboard.TargetProperty="Opacity" Duration="0" To="1" />
                                        <ColorAnimationUsingKeyFrames BeginTime="0" Duration="0" Storyboard.TargetName="BackgroundRectangle" Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)">
                                            <SplineColorKeyFrame KeyTime="0" Value="#FFE1E7EC" />
                                        </ColorAnimationUsingKeyFrames>
                                    </Storyboard>
                                </vsm:VisualState>-->
       </vsm:VisualStateGroup>
      </vsm:VisualStateManager.VisualStateGroups>
      <localprimitives:DataGridFrozenGrid.RowDefinitions>
       <RowDefinition Height="*" />
       <RowDefinition Height="Auto" />
       <RowDefinition Height="Auto" />
      </localprimitives:DataGridFrozenGrid.RowDefinitions>
      <localprimitives:DataGridFrozenGrid.ColumnDefinitions>
       <ColumnDefinition Width="Auto" />
       <ColumnDefinition Width="*" />
      </localprimitives:DataGridFrozenGrid.ColumnDefinitions>
      <Rectangle x:Name="BackgroundRectangle" Grid.RowSpan="2" Grid.ColumnSpan="2" Opacity="0" Fill="#FFBADDE9"  />
      <localprimitives:DataGridRowHeader Grid.RowSpan="3" x:Name="RowHeader" localprimitives:DataGridFrozenGrid.IsFrozen="True" />

      <localprimitives:DataGridCellsPresenter x:Name="CellsPresenter" localprimitives:DataGridFrozenGrid.IsFrozen="True"/>

      <localprimitives:DataGridDetailsPresenter Grid.Row="1" Grid.Column="1" x:Name="DetailsPresenter" />
      <Rectangle Grid.Row="2" Grid.Column="1" x:Name="BottomGridLine" HorizontalAlignment="Stretch" Height="1" />
     </localprimitives:DataGridFrozenGrid>
    </ControlTemplate>
   </Setter.Value>
  </Setter>
 </Style>

As you can see, I commented out some more visual states. You will want to comment out the MouseOver VisualState storyboard, the Normal Selected storyboard, the MouseOver Selected storyboard, and the Unfocused Selected storyboard.

(Please Note: I did not remove these visual states, I only commented out what they used to do.)

This is my code in its entirety for reference: (XAML first, then VB)

XAML:

<UserControl x:Class="DataGrid_Mouseover.Page"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:data="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data"  
    xmlns:local="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data"
    xmlns:controls="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data"
    xmlns:primitives="clr-namespace:System.Windows.Controls.Primitives;assembly=System.Windows"
    xmlns:localprimitives="clr-namespace:System.Windows.Controls.Primitives;assembly=System.Windows.Controls.Data"
    xmlns:vsm="clr-namespace:System.Windows;assembly=System.Windows">
<UserControl.Resources>

 <Style x:Key="CellStyle" TargetType="local:DataGridCell">

  <!-- TODO: Remove this workaround to force MouseLeftButtonDown event to be raised when root element is clicked. -->
  <Setter Property="Background" Value="Transparent" />
  <Setter Property="HorizontalContentAlignment" Value="Stretch" />
  <Setter Property="VerticalContentAlignment" Value="Stretch" />
  <Setter Property="Cursor" Value="Arrow" />
  <Setter Property="IsTabStop" Value="False" />
  <Setter Property="Template">
   <Setter.Value>
    <ControlTemplate TargetType="local:DataGridCell">
     <Grid Name="Root" Background="Transparent">
      <vsm:VisualStateManager.VisualStateGroups>
       <vsm:VisualStateGroup x:Name="CurrentStates" >
        <vsm:VisualStateGroup.Transitions>
         <vsm:VisualTransition GeneratedDuration="0" />
        </vsm:VisualStateGroup.Transitions>

        <vsm:VisualState x:Name="Regular" />
        <vsm:VisualState x:Name="Current" />
         <!--<Storyboard>
          <DoubleAnimation Storyboard.TargetName="FocusVisual" Storyboard.TargetProperty="Opacity" To="1" Duration="0" />
         </Storyboard>
        </vsm:VisualState>-->
       </vsm:VisualStateGroup>
      </vsm:VisualStateManager.VisualStateGroups>
      <Grid.ColumnDefinitions>
       <ColumnDefinition Width="*" />
       <ColumnDefinition Width="Auto" />
      </Grid.ColumnDefinitions>
      <!-- TODO Refactor this if SL ever gets a FocusVisualStyle on FrameworkElement -->
      <Rectangle Name="FocusVisual" Stroke="#FF6DBDD1" StrokeThickness="1" Fill="#66FFFFFF" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" IsHitTestVisible="false" Opacity="0" />
      <ContentPresenter Content="{TemplateBinding Content}" ContentTemplate="{TemplateBinding ContentTemplate}" Cursor="{TemplateBinding Cursor}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" Margin="{TemplateBinding Padding}" />
      <Rectangle Name="RightGridLine" Grid.Column="1" VerticalAlignment="Stretch" Width="1" />
     </Grid>
    </ControlTemplate>
   </Setter.Value>
  </Setter>
 </Style>

 <Style TargetType="local:DataGridRow" x:Key="MyCustomRow">
  <Setter Property="IsTabStop" Value="False" />
  <Setter Property="Template">
   <Setter.Value>
    <ControlTemplate TargetType="local:DataGridRow">
     <localprimitives:DataGridFrozenGrid x:Name="Root">
      <localprimitives:DataGridFrozenGrid.Resources>
       <Storyboard x:Key="DetailsVisibleTransition" >
        <DoubleAnimation Storyboard.TargetName="DetailsPresenter" Storyboard.TargetProperty="ContentHeight" Duration="00:00:0.1" />
       </Storyboard>
      </localprimitives:DataGridFrozenGrid.Resources>
      <vsm:VisualStateManager.VisualStateGroups>
       <vsm:VisualStateGroup x:Name="CommonStates" >
        <vsm:VisualState x:Name="Normal" />
        <vsm:VisualState x:Name="Normal AlternatingRow">
         <Storyboard>
          <DoubleAnimation Storyboard.TargetName="BackgroundRectangle" Storyboard.TargetProperty="Opacity" Duration="0" To="0" />
         </Storyboard>
        </vsm:VisualState>
        <vsm:VisualState x:Name="MouseOver" />
        <!--<Storyboard>
                                        <DoubleAnimation Storyboard.TargetName="BackgroundRectangle" Storyboard.TargetProperty="Opacity" Duration="0" To=".5" />
                                    </Storyboard>
                                </vsm:VisualState>-->
        <vsm:VisualState x:Name="Normal Selected"/>
        <!--<Storyboard>
                                        <DoubleAnimation Storyboard.TargetName="BackgroundRectangle" Storyboard.TargetProperty="Opacity" Duration="0" To="1" />
                                    </Storyboard>
                                </vsm:VisualState>-->
        <vsm:VisualState x:Name="MouseOver Selected"/>
        <!--<Storyboard>
                                        <DoubleAnimation Storyboard.TargetName="BackgroundRectangle" Storyboard.TargetProperty="Opacity" Duration="0" To="1" />
                                    </Storyboard>
                                </vsm:VisualState>-->
        <vsm:VisualState x:Name="Unfocused Selected"/>
        <!--<Storyboard>
                                        <DoubleAnimation Storyboard.TargetName="BackgroundRectangle" Storyboard.TargetProperty="Opacity" Duration="0" To="1" />
                                        <ColorAnimationUsingKeyFrames BeginTime="0" Duration="0" Storyboard.TargetName="BackgroundRectangle" Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)">
                                            <SplineColorKeyFrame KeyTime="0" Value="#FFE1E7EC" />
                                        </ColorAnimationUsingKeyFrames>
                                    </Storyboard>
                                </vsm:VisualState>-->
       </vsm:VisualStateGroup>
      </vsm:VisualStateManager.VisualStateGroups>
      <localprimitives:DataGridFrozenGrid.RowDefinitions>
       <RowDefinition Height="*" />
       <RowDefinition Height="Auto" />
       <RowDefinition Height="Auto" />
      </localprimitives:DataGridFrozenGrid.RowDefinitions>
      <localprimitives:DataGridFrozenGrid.ColumnDefinitions>
       <ColumnDefinition Width="Auto" />
       <ColumnDefinition Width="*" />
      </localprimitives:DataGridFrozenGrid.ColumnDefinitions>
      <Rectangle x:Name="BackgroundRectangle" Grid.RowSpan="2" Grid.ColumnSpan="2" Opacity="0" Fill="#FFBADDE9"  />
      <localprimitives:DataGridRowHeader Grid.RowSpan="3" x:Name="RowHeader" localprimitives:DataGridFrozenGrid.IsFrozen="True" />

      <localprimitives:DataGridCellsPresenter x:Name="CellsPresenter" localprimitives:DataGridFrozenGrid.IsFrozen="True"/>

      <localprimitives:DataGridDetailsPresenter Grid.Row="1" Grid.Column="1" x:Name="DetailsPresenter" />
      <Rectangle Grid.Row="2" Grid.Column="1" x:Name="BottomGridLine" HorizontalAlignment="Stretch" Height="1" />
     </localprimitives:DataGridFrozenGrid>
    </ControlTemplate>
   </Setter.Value>
  </Setter>
 </Style>
</UserControl.Resources>

<Grid x:Name="LayoutRoot" Background="White">
 <local:DataGrid x:Name="TestGrid"
           HorizontalAlignment="Left" 
           VerticalAlignment="Bottom" 
           AutoGenerateColumns="False"
           HeadersVisibility="None"
           RowHeight="55"
           Background="Transparent"
           AlternatingRowBackground="Transparent"
           RowBackground="Transparent"
           BorderBrush="Transparent"
           Foreground="Transparent" 
           GridLinesVisibility="None" 
           SelectionMode="Single"
     CellStyle="{StaticResource CellStyle}" 
     RowStyle="{StaticResource MyCustomRow}">

  <local:DataGrid.Columns>
   <local:DataGridTemplateColumn Header="Clinic">
    <local:DataGridTemplateColumn.CellTemplate>
     <DataTemplate>
      <Button x:Name="btnClinic" 
                        Height="46" 
                        Width="580" 
                        Content="{Binding Path=Description}" 
                        Click="btnClinic_Click"
                        FontSize="24"
                        FontFamily="Tahoma"
                        FontWeight="Bold">
       <Button.Background>
        <LinearGradientBrush EndPoint="0.528,1.144" StartPoint="1.066,1.221">
         <GradientStop Color="#FF000000"/>
         <GradientStop Color="#FFEDC88F" Offset="1"/>
        </LinearGradientBrush>
       </Button.Background>
      </Button>
     </DataTemplate>
    </local:DataGridTemplateColumn.CellTemplate>
   </local:DataGridTemplateColumn>
  </local:DataGrid.Columns>
 </local:DataGrid>
</Grid>
</UserControl>

VB:

Partial Public Class Page
Inherits UserControl

Public Sub New()
 InitializeComponent()
 Dim test As IList(Of String) = New List(Of String)
 test.Add("test1")
 test.Add("test1")
 test.Add("test1")
 test.Add("test1")
 test.Add("test1")
 test.Add("test1")
 test.Add("test1")
 test.Add("test1")
 test.Add("test1")
 test.Add("test1")

 TestGrid.ItemsSource = test

End Sub

Private Sub btnClinic_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs)

End Sub
End Class

Hope this helps.

Thanks, Scott

Scott
Ah genius! Thanks. I had no idea the solution would require so much xaml.
Jeremy
Awesome, you saved me having to dig through the DataGrid templates >8)
Ireney Berezniak