Silverlight ScrollViewer - fade in\out the scrollbar - silverlight

I have a scrollviewer and I want to animate the way the vertical scrollbar appears. The scrollbar is set to AUTO , so I want it to fade in when needed and fade out when not needed.
I know how to drill into templates and change colors and appearance, but can I make a change like this ?

This was a fun question. Since Scrollbar and ScrollViewer are sealed this was a bit of a challenge. (I thought of making a copy of ScrollViewer using Reflector, but here is a XAML-only solution).
When I heard animation, I thought states. It would have been nice if ScrollViewer was implemented using states, but unfortunately, it was not. By using DataStateBehavior, we can create states out of a property -- in this case, states for the ComputedVerticalScrollBarVisibility property. For some reason, it didn't work to bind the DataStateBehavior to the ScrollViewer's ComputedVerticalScrollBarVisibility using TemplateBinding. (Anyone know why?) I was able to bind it to the VerticalScrollbar Visibility property, but I decided not to:
In order for the Fade out to work, I didn't want the VerticalScrollbar.Visibility to still be bound to ComputedVerticalScrollBarVisibility because if it was, the scrollbar would immediately disapper when the property changed. Instead, I used the VerticalScrollbar Tag property to hold the ComputedVerticalScrollBarVisibility and bound the DataStateBehavior to the VerticalScrollbar Tag.
Now that states are in place, it was an easy matter to set the Opacity for each state and the state transition duration and, voila!, you have a fade in ScrollViewer.
<UserControl
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions" x:Class="SilverlightApplication5.MainPage"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="400">
<UserControl.Resources>
<Style x:Key="ScrollViewerStyle1" TargetType="ScrollViewer">
<Setter Property="HorizontalContentAlignment" Value="Left"/>
<Setter Property="VerticalContentAlignment" Value="Top"/>
<Setter Property="VerticalScrollBarVisibility" Value="Visible"/>
<Setter Property="Padding" Value="4"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="BorderBrush">
<Setter.Value>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#FFA3AEB9" Offset="0"/>
<GradientStop Color="#FF8399A9" Offset="0.375"/>
<GradientStop Color="#FF718597" Offset="0.375"/>
<GradientStop Color="#FF617584" Offset="1"/>
</LinearGradientBrush>
</Setter.Value>
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ScrollViewer">
<Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="2">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="VisualStateGroup">
<VisualStateGroup.Transitions>
<VisualTransition GeneratedDuration="0:0:0.5"/>
</VisualStateGroup.Transitions>
<VisualState x:Name="VerticalVisible">
<Storyboard>
<DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="VerticalScrollBar" d:IsOptimized="True"/>
</Storyboard>
</VisualState>
<VisualState x:Name="VerticleHidden">
<Storyboard>
<DoubleAnimation Duration="0" To="0" Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="VerticalScrollBar" d:IsOptimized="True"/>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Grid Background="{TemplateBinding Background}">
<i:Interaction.Behaviors>
<ei:DataStateBehavior Binding="{Binding Tag, ElementName=VerticalScrollBar}" Value="Visible" TrueState="VerticalVisible" FalseState="VerticleHidden"/>
</i:Interaction.Behaviors>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<ScrollContentPresenter x:Name="ScrollContentPresenter" Cursor="{TemplateBinding Cursor}" ContentTemplate="{TemplateBinding ContentTemplate}" Margin="{TemplateBinding Padding}"/>
<Rectangle Grid.Column="1" Fill="#FFE9EEF4" Grid.Row="1"/>
<ScrollBar x:Name="VerticalScrollBar" Grid.Column="1" IsTabStop="False" Maximum="{TemplateBinding ScrollableHeight}" Margin="0,-1,-1,-1" Minimum="0" Orientation="Vertical" Grid.Row="0" Tag="{TemplateBinding ComputedVerticalScrollBarVisibility}" Value="{TemplateBinding VerticalOffset}" ViewportSize="{TemplateBinding ViewportHeight}" Width="18"/>
<ScrollBar x:Name="HorizontalScrollBar" Grid.Column="0" Height="18" IsTabStop="False" Maximum="{TemplateBinding ScrollableWidth}" Margin="-1,0,-1,-1" Minimum="0" Orientation="Horizontal" Grid.Row="1" Visibility="{TemplateBinding ComputedHorizontalScrollBarVisibility}" Value="{TemplateBinding HorizontalOffset}" ViewportSize="{TemplateBinding ViewportWidth}"/>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</UserControl.Resources>
<Grid x:Name="LayoutRoot" Background="Beige">
<ScrollViewer VerticalScrollBarVisibility="Auto" Style="{StaticResource ScrollViewerStyle1}">
<Rectangle Margin="10" Fill="LightBlue" MinHeight="300" />
</ScrollViewer>
</Grid>
</UserControl>
To see this in action, run this code and shrink the browser window. The scrollbar will fade into view.

Related

WPF Something overriding tab content alignment of TabControl

I used this as a starting point to make a style for a TabControl, mine only works with TabStripPlacement="Bottom". I expect that the content I put in the TabItem would fill the entire area, designated for it, like it does with the default style and the style from microsoft I used as a starting point. But it does not, It starts with its minimal sizes, buttons don't get stretched at all and RichTextBoxes seem stretched only horizontally, if I add text to the RichTextBox it expands. Here is what it looks like:
The orange is the area I expect the content to take (with some margins), the blue is the background of the RichTextBox. The green is the global background. The selected tab has its header's border thickened (red). Don't mind the space between the tab headers and the content area, it is intentional.
I've been poking around a lot, but can't seem to find the cause, however I have found that I don't have this problem if I don't apply the style for the TabItem. And when I inspect the elements with the xaml debugging tools in visual studio I find that PART_SelectedContentHost has its horizontal alignment set to Left and vertical alignment set to Top, happens even if I have explicitly set them to Stretch in the style. I also tried applying "Stretch" to the RichTextBox, it didn't work. Here is the style:
<Style TargetType="{x:Type TabControl}">
<Setter Property="OverridesDefaultStyle" Value="True" />
<Setter Property="SnapsToDevicePixels" Value="True" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TabControl}">
<Grid KeyboardNavigation.TabNavigation="Local" VerticalAlignment="Stretch">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="30" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Disabled">
<Storyboard>
<ColorAnimationUsingKeyFrames Storyboard.TargetName="Border"
Storyboard.TargetProperty="(Border.BorderBrush).(SolidColorBrush.Color)">
<EasingColorKeyFrame KeyTime="0" Value="#FFAAAAAA" />
</ColorAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<TabPanel x:Name="HeaderPanel"
Grid.Row="2"
Panel.ZIndex="1"
Margin="0"
IsItemsHost="True"
KeyboardNavigation.TabIndex="1"
Background="Transparent" />
<Border x:Name="Border"
Grid.Row="0"
Panel.ZIndex="0"
BorderThickness="0"
CornerRadius="0"
KeyboardNavigation.TabNavigation="Local"
KeyboardNavigation.DirectionalNavigation="Contained"
KeyboardNavigation.TabIndex="2"
VerticalAlignment="Stretch"
HorizontalAlignment="Stretch">
<Border.Background>
<SolidColorBrush Color="Orange"/>
</Border.Background>
<ContentPresenter
x:Name="PART_SelectedContentHost"
Margin="4,4,4,4"
ContentSource="SelectedContent"
VerticalAlignment="Stretch"
HorizontalAlignment="Stretch"/>
</Border>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="{x:Type TabItem}">
<Setter Property="OverridesDefaultStyle" Value="True"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TabItem}">
<Grid x:Name="Root">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="SelectionStates">
<VisualState x:Name="Unselected" />
<VisualState x:Name="Selected">
<Storyboard>
<ColorAnimation Storyboard.TargetName="ContentSite"
Storyboard.TargetProperty="(TextBlock.Foreground).(SolidColorBrush.Color)"
From="White" To="Blue"
Duration="0:0:0.0" AutoReverse="True"/>
<ThicknessAnimationUsingKeyFrames
Storyboard.TargetProperty="(Border.BorderThickness)"
Storyboard.TargetName="Border">
<EasingThicknessKeyFrame KeyTime="0"
Value="1,5,1,5" />
</ThicknessAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="MouseOver" />
<VisualState x:Name="Disabled"/>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Border x:Name="Border"
Margin="0,0,0,0"
BorderThickness="1,1,1,1"
CornerRadius="0,0,0,0"
BorderBrush="Red">
<Border.Background>
<SolidColorBrush Color="Black"/>
</Border.Background>
<ContentPresenter x:Name="ContentSite"
VerticalAlignment="Center"
HorizontalAlignment="Center"
ContentSource="Header"
Margin="12,2,12,2"
RecognizesAccessKey="True"
TextBlock.Foreground="White"/>
</Border>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Panel.ZIndex" Value="100"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
EDIT: For the sake clarity, the style is saved in a xaml file - "TabControlStyleDictionary.xaml" and this is the code of the main window:
<Window x:Class="TabControlStylingTest2.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:TabControlStylingTest2"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="TabControlStyleDictionary.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
<Grid Background="Green">
<TabControl TabStripPlacement="Bottom">
<TabItem Header="tab1">
<RichTextBox
Foreground="White"
Background="Blue"
AcceptsReturn="True"
VerticalAlignment="Stretch"
HorizontalAlignment="Stretch"/>
</TabItem>
<TabItem Header="tab2">
<Button
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch">
some text 123456789
</Button>
</TabItem>
</TabControl>
</Grid>
I had the same issue with overwriting the style. For some reason the HorizontalAlignment and VerticalAlignment properties of the ContentPresenter are set locally on each LayoutUpdate of the PART_SelectedContentHost in the codebehind. In my solution I implement an Attached Behavior for UIElements which calls the ClearValue method on a LayoutUpdate event. This will delete the local value on each occurance of the event. A refrence to System.Windows.Interactivity is required for this.
public class ClearValueOnLayoutUpdateBehavior : Behavior<UIElement>
{
public static readonly DependencyProperty PropertyProperty =
DependencyProperty.Register(nameof(Property), typeof(DependencyProperty), typeof(ClearValueOnLayoutUpdateBehavior), new PropertyMetadata());
public DependencyProperty Property
{
get { return (DependencyProperty)GetValue(PropertyProperty); }
set { SetValue(PropertyProperty, value); }
}
protected override void OnAttached()
{
base.OnAttached();
if(Property != null)
AssociatedObject.LayoutUpdated += AssociatedObject_LayoutUpdated;
}
private void AssociatedObject_LayoutUpdated(object sender, EventArgs e)
{
AssociatedObject.ClearValue(Property);
}
}
In your XAML file you have to add the xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity" reference as well. Your ContentPresenter should be changed as following:
<ContentPresenter
x:Name="PART_SelectedContentHost"
ContentSource="SelectedContent"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}">
<i:Interaction.Behaviors>
<behavior:ClearValueOnLayoutUpdateBehavior Property="{x:Static FrameworkElement.HorizontalAlignmentProperty}" />
<behavior:ClearValueOnLayoutUpdateBehavior Property="{x:Static FrameworkElement.VerticalAlignmentProperty}" />
</i:Interaction.Behaviors>
</ContentPresenter>

Silverlight DataGrid control customizing column headers

I want to improve default datagrid control by some needs like filtering, easy adding-editing etc... I'm trying to customize column headers but couldn't get it. I need to add some other controls to headers and reach them in code side. Is there a way to do this?
Thanks.
<sdk:DataGrid
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk"
xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"
mc:Ignorable="d"
x:Class="DataGridTest.SLDataGrid"
d:DesignWidth="640" d:DesignHeight="480">
<sdk:DataGrid.Resources>
<Style x:Key="SLDataGridStyle" TargetType="sdk:DataGrid">
<Setter Property="RowBackground" Value="#AAEAEFF4"/>
<Setter Property="AlternatingRowBackground" Value="#00FFFFFF"/>
<Setter Property="Background" Value="#FFFFFFFF"/>
<Setter Property="HeadersVisibility" Value="Column"/>
<Setter Property="HorizontalScrollBarVisibility" Value="Auto"/>
<Setter Property="VerticalScrollBarVisibility" Value="Auto"/>
<Setter Property="SelectionMode" Value="Extended"/>
<Setter Property="CanUserReorderColumns" Value="True"/>
<Setter Property="CanUserResizeColumns" Value="True"/>
<Setter Property="CanUserSortColumns" Value="True"/>
<Setter Property="AutoGenerateColumns" Value="True"/>
<Setter Property="RowDetailsVisibilityMode" Value="VisibleWhenSelected"/>
<Setter Property="BorderBrush">
<Setter.Value>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#FFA3AEB9" Offset="0"/>
<GradientStop Color="#FF8399A9" Offset="0.375"/>
<GradientStop Color="#FF718597" Offset="0.375"/>
<GradientStop Color="#FF617584" Offset="1"/>
</LinearGradientBrush>
</Setter.Value>
</Setter>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="DragIndicatorStyle">
<Setter.Value>
<Style TargetType="ContentControl">
<Setter Property="Foreground" Value="#7FFFFFFF"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ContentControl">
<Grid>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="SortStates">
<VisualState x:Name="Unsorted"/>
<VisualState x:Name="SortAscending">
<Storyboard>
<DoubleAnimation Duration="0" To="1.0" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="SortIcon"/>
</Storyboard>
</VisualState>
<VisualState x:Name="SortDescending">
<Storyboard>
<DoubleAnimation Duration="0" To="1.0" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="SortIcon"/>
<DoubleAnimation Duration="0" To="-.9" Storyboard.TargetProperty="(RenderTransform).ScaleY" Storyboard.TargetName="SortIcon"/>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Rectangle x:Name="BackgroundRectangle" Grid.ColumnSpan="2" Fill="#66808080" Stretch="Fill"/>
<Rectangle x:Name="BackgroundGradient" Grid.ColumnSpan="2" Opacity="0" Stretch="Fill">
<Rectangle.Fill>
<LinearGradientBrush EndPoint=".7,1" StartPoint=".7,0">
<GradientStop Color="#FFFFFFFF" Offset="0.015"/>
<GradientStop Color="#F9FFFFFF" Offset="0.375"/>
<GradientStop Color="#E5FFFFFF" Offset="0.6"/>
<GradientStop Color="#C6FFFFFF" Offset="1"/>
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
<Grid HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<ContentPresenter Content="{TemplateBinding Content}"/>
<Path x:Name="SortIcon" Grid.Column="1" Data="F1 M -5.215,6.099L 5.215,6.099L 0,0L -5.215,6.099 Z " Fill="#7FFFFFFF" HorizontalAlignment="Left" Margin="4,0,0,0" Opacity="0" RenderTransformOrigin=".5,.5" Stretch="Uniform" VerticalAlignment="Center" Width="8">
<Path.RenderTransform>
<ScaleTransform ScaleY=".9" ScaleX=".9"/>
</Path.RenderTransform>
</Path>
</Grid>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Setter.Value>
</Setter>
<Setter Property="DropLocationIndicatorStyle">
<Setter.Value>
<Style TargetType="ContentControl">
<Setter Property="Background" Value="#FF3F4346"/>
<Setter Property="Width" Value="2"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ContentControl">
<Rectangle Fill="{TemplateBinding Background}" Height="{TemplateBinding Height}" Width="{TemplateBinding Width}"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Setter.Value>
</Setter>
<Setter Property="GridLinesVisibility" Value="Vertical"/>
<Setter Property="HorizontalGridLinesBrush" Value="#FFC9CACA"/>
<Setter Property="IsTabStop" Value="True"/>
<Setter Property="VerticalGridLinesBrush" Value="#FFC9CACA"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="sdk:DataGrid">
<Grid>
<VisualStateManager.CustomVisualStateManager>
<ei:ExtendedVisualStateManager/>
</VisualStateManager.CustomVisualStateManager>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates" ei:ExtendedVisualStateManager.UseFluidLayout="True">
<VisualStateGroup.Transitions>
<VisualTransition GeneratedDuration="0:0:0.3"/>
</VisualStateGroup.Transitions>
<VisualState x:Name="Normal"/>
<VisualState x:Name="Disabled">
<Storyboard>
<DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="DisabledVisualElement"/>
</Storyboard>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="ValidationStates" ei:ExtendedVisualStateManager.UseFluidLayout="True">
<VisualStateGroup.Transitions>
<VisualTransition GeneratedDuration="0:0:0.3"/>
</VisualStateGroup.Transitions>
<VisualState x:Name="Invalid"/>
<VisualState x:Name="Valid"/>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="2">
<Grid x:Name="Root" Background="{TemplateBinding Background}">
<Grid.Resources>
<ControlTemplate x:Key="TopLeftHeaderTemplate" TargetType="sdk:DataGridColumnHeader">
<Grid x:Name="Root">
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Border BorderBrush="#FFC9CACA" BorderThickness="0,0,1,0" Background="#FF1F3B53" Grid.RowSpan="2">
<Rectangle Stretch="Fill" StrokeThickness="1">
<Rectangle.Fill>
<LinearGradientBrush EndPoint=".7,1" StartPoint=".7,0">
<GradientStop Color="#FCFFFFFF" Offset="0.015"/>
<GradientStop Color="#F7FFFFFF" Offset="0.375"/>
<GradientStop Color="#E5FFFFFF" Offset="0.6"/>
<GradientStop Color="#D1FFFFFF" Offset="1"/>
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
</Border>
<Rectangle Fill="#FFDBDCDC" Height="1" Grid.RowSpan="2" StrokeThickness="1" VerticalAlignment="Bottom" Width="Auto"/>
</Grid>
</ControlTemplate>
<ControlTemplate x:Key="TopRightHeaderTemplate" TargetType="sdk:DataGridColumnHeader">
<Grid x:Name="RootElement">
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Border BorderBrush="#FFC9CACA" BorderThickness="1,0,0,0" Background="#FF1F3B53" Grid.RowSpan="2">
<Rectangle Stretch="Fill">
<Rectangle.Fill>
<LinearGradientBrush EndPoint=".7,1" StartPoint=".7,0">
<GradientStop Color="#FCFFFFFF" Offset="0.015"/>
<GradientStop Color="#F7FFFFFF" Offset="0.375"/>
<GradientStop Color="#E5FFFFFF" Offset="0.6"/>
<GradientStop Color="#D1FFFFFF" Offset="1"/>
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
</Border>
</Grid>
</ControlTemplate>
</Grid.Resources>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<sdk:DataGridColumnHeader x:Name="TopLeftCornerHeader" Template="{StaticResource TopLeftHeaderTemplate}" Width="22"/>
<sdk:DataGridColumnHeadersPresenter x:Name="ColumnHeadersPresenter" Grid.Column="1"/>
<sdk:DataGridColumnHeader x:Name="TopRightCornerHeader" Grid.Column="2" Template="{StaticResource TopRightHeaderTemplate}"/>
<Rectangle x:Name="ColumnHeadersAndRowsSeparator" Grid.ColumnSpan="3" Fill="#FFC9CACA" Height="1" StrokeThickness="1" VerticalAlignment="Bottom" Width="Auto"/>
<sdk:DataGridRowsPresenter x:Name="RowsPresenter" Grid.ColumnSpan="2" Grid.Row="1"/>
<Rectangle x:Name="BottomRightCorner" Grid.Column="2" Fill="#FFE9EEF4" Grid.Row="2"/>
<Rectangle x:Name="BottomLeftCorner" Grid.ColumnSpan="2" Fill="#FFE9EEF4" Grid.Row="2"/>
<ScrollBar x:Name="VerticalScrollbar" Grid.Column="2" Margin="0,-1,-1,-1" Orientation="Vertical" Grid.Row="1" Width="18"/>
<Grid Grid.Column="1" Grid.Row="2">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Rectangle x:Name="FrozenColumnScrollBarSpacer"/>
<ScrollBar x:Name="HorizontalScrollbar" Grid.Column="1" Height="18" Margin="-1,0,-1,-1" Orientation="Horizontal"/>
</Grid>
<sdk:ValidationSummary x:Name="ValidationSummary" Grid.ColumnSpan="3" MaxHeight="90" Grid.Row="3"/>
</Grid>
</Border>
<Border x:Name="DisabledVisualElement" Background="#8CFFFFFF" CornerRadius="2" HorizontalAlignment="Stretch" Height="Auto" IsHitTestVisible="False" Opacity="0" VerticalAlignment="Stretch" Width="Auto"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="SLDataGridColumnHeaderStyle" TargetType="sdk:DataGridColumnHeader">
<Setter Property="Foreground" Value="#FF000000"/>
<Setter Property="HorizontalContentAlignment" Value="Left"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="IsTabStop" Value="False"/>
<Setter Property="SeparatorBrush" Value="#FFC9CACA"/>
<Setter Property="Padding" Value="4"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="sdk:DataGridColumnHeader">
<StackPanel x:Name="Root">
<VisualStateManager.CustomVisualStateManager>
<ei:ExtendedVisualStateManager/>
</VisualStateManager.CustomVisualStateManager>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates" ei:ExtendedVisualStateManager.UseFluidLayout="True">
<VisualStateGroup.Transitions>
<VisualTransition GeneratedDuration="0:0:0.3"/>
</VisualStateGroup.Transitions>
<VisualState x:Name="Normal"/>
<VisualState x:Name="MouseOver">
<Storyboard>
<ColorAnimation Duration="0" To="#FF448DCA" Storyboard.TargetProperty="(Fill).Color" Storyboard.TargetName="BackgroundRectangle"/>
<ColorAnimation Duration="0" To="#7FFFFFFF" Storyboard.TargetProperty="(Fill).(GradientStops)[3].Color" Storyboard.TargetName="BackgroundGradient"/>
<ColorAnimation Duration="0" To="#CCFFFFFF" Storyboard.TargetProperty="(Fill).(GradientStops)[2].Color" Storyboard.TargetName="BackgroundGradient"/>
<ColorAnimation Duration="0" To="#F2FFFFFF" Storyboard.TargetProperty="(Fill).(GradientStops)[1].Color" Storyboard.TargetName="BackgroundGradient"/>
</Storyboard>
</VisualState>
<VisualState x:Name="Pressed">
<Storyboard>
<ColorAnimation Duration="0" To="#FF448DCA" Storyboard.TargetProperty="(Fill).Color" Storyboard.TargetName="BackgroundRectangle"/>
<ColorAnimation Duration="0" To="#D8FFFFFF" Storyboard.TargetProperty="(Fill).(GradientStops)[0].Color" Storyboard.TargetName="BackgroundGradient"/>
<ColorAnimation Duration="0" To="#C6FFFFFF" Storyboard.TargetProperty="(Fill).(GradientStops)[1].Color" Storyboard.TargetName="BackgroundGradient"/>
<ColorAnimation Duration="0" To="#8CFFFFFF" Storyboard.TargetProperty="(Fill).(GradientStops)[2].Color" Storyboard.TargetName="BackgroundGradient"/>
<ColorAnimation Duration="0" To="#3FFFFFFF" Storyboard.TargetProperty="(Fill).(GradientStops)[3].Color" Storyboard.TargetName="BackgroundGradient"/>
</Storyboard>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="SortStates" ei:ExtendedVisualStateManager.UseFluidLayout="True">
<VisualStateGroup.Transitions>
<VisualTransition GeneratedDuration="0:0:0.3"/>
</VisualStateGroup.Transitions>
<VisualState x:Name="Unsorted"/>
<VisualState x:Name="SortAscending">
<Storyboard>
<DoubleAnimation Duration="0" To="1.0" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="SortIcon"/>
</Storyboard>
</VisualState>
<VisualState x:Name="SortDescending">
<Storyboard>
<DoubleAnimation Duration="0" To="1.0" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="SortIcon"/>
<DoubleAnimation Duration="0" To="-.9" Storyboard.TargetProperty="(RenderTransform).ScaleY" Storyboard.TargetName="SortIcon"/>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Grid Height="24" Width="147">
<Rectangle x:Name="BackgroundRectangle" Fill="#FF1F3B53" Stretch="Fill" Margin="0,0,-1,0"/>
<Rectangle x:Name="BackgroundGradient" Stretch="Fill" Margin="0,0,-1,0">
<Rectangle.Fill>
<LinearGradientBrush EndPoint=".7,1" StartPoint=".7,0">
<GradientStop Color="#FCFFFFFF" Offset="0.015"/>
<GradientStop Color="#F7FFFFFF" Offset="0.375"/>
<GradientStop Color="#E5FFFFFF" Offset="0.6"/>
<GradientStop Color="#D1FFFFFF" Offset="1"/>
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
<Grid HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="4,4,0,4" VerticalAlignment="{TemplateBinding VerticalContentAlignment}">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<ContentPresenter Content="{TemplateBinding Content}"/>
<Path x:Name="SortIcon" Grid.Column="1" Data="F1 M -5.215,6.099L 5.215,6.099L 0,0L -5.215,6.099 Z " Fill="#FF444444" HorizontalAlignment="Left" Margin="4,0,0,0" Opacity="0" RenderTransformOrigin=".5,.5" Stretch="Uniform" VerticalAlignment="Center" Width="8">
<Path.RenderTransform>
<ScaleTransform ScaleY=".9" ScaleX=".9"/>
</Path.RenderTransform>
</Path>
</Grid>
<Rectangle x:Name="VerticalSeparator" Fill="{TemplateBinding SeparatorBrush}" Visibility="{TemplateBinding SeparatorVisibility}" VerticalAlignment="Stretch" Width="1" HorizontalAlignment="Right" Margin="0,0,-1,0" d:LayoutOverrides="Width"/>
</Grid>
<Grid Height="24" Background="#FFE4E4E4">
<TextBox TextWrapping="Wrap" Text="TextBox" d:LayoutOverrides="Width"/>
</Grid>
</StackPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</sdk:DataGrid.Resources>
<sdk:DataGrid.Style>
<StaticResource ResourceKey="SLDataGridStyle"/>
</sdk:DataGrid.Style>
<sdk:DataGrid.ColumnHeaderStyle>
<StaticResource ResourceKey="SLDataGridColumnHeaderStyle"/>
</sdk:DataGrid.ColumnHeaderStyle>
It is possible to add custom controls to the headers of a Silverlight DataGrid, but it's not obvious how to do so, and it is a bit of a pain.
There are two things you need to do:
Specify the controls you want to add to the column header by applying a ContentTemplate to the HeaderStyle of the column header. For this to work, you'll need the following two XAML namespace declarations:
xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk"
xmlns:dataprimitives="clr-namespace:System.Windows.Controls.Primitives;assembly=System.Windows.Controls.Data"
<sdk:DataGridTemplateColumn Binding="...">
<sdk:DataGridTemplateColumn.HeaderStyle>
<Style TargetType="dataprimitives:DataGridColumnHeader">
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<CheckBox IsChecked="{Binding Path=SomeFlag, Mode=TwoWay}" />
<TextBlock Text="Header text" />
</StackPanel>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
</sdk:DataGridTemplateColumn.HeaderStyle>
<!-- other DataGridTemplateColumn stuff -->
<sdk:DataGridTemplateColumn>
In this example, I've used a CheckBox with an IsChecked property bound to a view-model property SomeFlag, and a TextBlock. I used a DataGridTemplateColumn in this example, but this approach should also work with DataGridTextColumn and DataGridCheckBoxColumn provided you replace sdk:DataGridTemplateColumn.HeaderStyle with sdk:DataGridTextColumn.HeaderStyle and similarly for DataGridCheckBoxColumn.
If you only want to add static content to the column header, there's nothing more you need to do. However, if you wish to use data-binding, you need a further step, as otherwise the data-context of the controls in the header will not be set correctly. This requires a bit of code-behind.
The following methods search through the visual tree for ContentPresenters within DataGridColumnHeaders and set the DataContexts of these ContentPresenters:
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Media;
/// <summary>
/// Sets the DataContext of each column header within the given data-grid.
/// </summary>
/// <param name="dataGrid">The DataGrid.</param>
/// <param name="dataContext">The data-context to set.</param>
public static void SetHeaderDataContexts(DataGrid dataGrid, object dataContext)
{
// First we look for a DataGridColumnHeadersPresenter.
DataGridColumnHeadersPresenter colsPresenter = GetObjectOfType<DataGridColumnHeadersPresenter>(dataGrid);
if (colsPresenter == null)
{
return;
}
// The ColumnHeadersPresenter contains all of the column headers as
// direct children. Within each column header is a ContentPresenter,
// whose DataContext will normally be null. For each ContentPresenter
// found, set its DataContext to be that given.
int colHeaderCount = VisualTreeHelper.GetChildrenCount(colsPresenter);
for (int i = 0; i < colHeaderCount; ++i)
{
var header = VisualTreeHelper.GetChild(colsPresenter, i) as DataGridColumnHeader;
if (header != null)
{
ContentPresenter contentPresenter = GetObjectOfType<ContentPresenter>(header);
if (contentPresenter != null)
{
contentPresenter.DataContext = dataContext;
}
}
}
}
/// <summary>
/// Returns the first descendant object of the given parent object within
/// the visual tree that is an instance of the specified type.
/// </summary>
/// <remarks>
/// The visual tree is searched in a depth-first manner, and the first
/// object of type <c>TObject</c> found within the tree is returned. If no
/// control of this type is found, <c>null</c> is returned instead.
/// </remarks>
/// <typeparam name="TObject">The type of object to search for. This must
/// be a subclass of <see cref="DependencyObject"/>.</typeparam>
/// <param name="parent">The parent control to search within.</param>
/// <returns>
/// The first control of the specified type found, or <c>null</c> if none
/// were found.
/// </returns>
public static TObject GetObjectOfType<TObject>(DependencyObject parent) where TObject : DependencyObject
{
int count = VisualTreeHelper.GetChildrenCount(parent);
for (int i = 0; i < count; ++i)
{
DependencyObject child = VisualTreeHelper.GetChild(parent, i);
if (child is TObject)
{
return child as TObject;
}
else
{
TObject obj = GetObjectOfType<TObject>(child);
if (obj != null)
{
return obj;
}
}
}
return null;
}
The only thing that remains to be done is to call SetHeaderDataContexts. I found that calling it from the user-control constructor didn't work, nor did calling it from the Loaded event (in both cases it had no effect). Calling it from the LayoutUpdated event of the grid really didn't work, as that caused an exception to be thrown.
However, calling it within the constructor by using
Dispatcher.BeginInvoke(() => SetHeaderDataContexts(theDataGrid, this.DataContext));
did appear to work.
Acknowledgements: the idea of setting the ContentTemplate comes from Lars Holm Jensen's answer to a similar question, and the idea of searching through the visual tree comes from a blog post from Manas Patnaik. Both links were found via a similar question.
Luke's answer is excellent.
However, I found that when I put a ComboBox into the header template, the binding (set in code-behind from part (2) of Luke's answer) disappeared after an item in the Combo was selected, or when the column is resized. This is because the column header is being recreated when the column resizes, so the binding gets lost.
I fixed it by setting the binding instead like this -
XAML -
<DataTemplate>
<StackPanel Orientation="Horizontal" Loaded="HeaderTemplate_OnLoaded" >
<CheckBox IsChecked="{Binding Path=SomeFlag, Mode=TwoWay}" />
<TextBlock Text="Header text" />
</StackPanel>
</DataTemplate>
Code-behind -
private void HeaderTemplate_OnLoaded(object sender, RoutedEventArgs e)
{
((FrameworkElement)sender).DataContext = this.DataContext;
}
This worked for me without problems every time.
The column header's style can indeed be changed. I was trying to center the header text & this link's technique worked for me: Silverlight DataGrid Header Horizontal Alignment

How to remove border around the DataGrid in silverlight

How do i remove the border around the Data grid in silverlight when i try BorderThickness="0" BorderBrush="Transparent" it gets rid of the broder on right left and bottom of the grid but not the top i think thats the header border or something but unsure i have also removed headers HeadersVisibility="None"
would be great if someone could help.
Cheers
In Silverlight 2 Beta 2 the generated DataGrid is surrounded by a border. Unfortunately, the removal of this border cannot be accomplished by simply setting a property on the DataGrid. To remove this, the definition of the DataGrid style or "skin" will need to be overridden.
The appearance for each Silverlight control (FrameworkElement) is defined within a ControlTemplate. Using Styles, this template can be overridden within your application with a set of customized XAML code. Default XAML definitions are found within the Silverlight Control Styles and Templates documentation. Specific to this topic, XAML definitions for the DataGrid are found in the DataGrid Styles and Templates documentation.
In the DataGrid XAML, look for the Template definition. Once this has been located, note that the RootElement of the the DataGrid is surrounded by three distinct Border elements.
These elements are likely the items that need to be removed. To start the customization, the style XAML for the DataGrid will need to be added as a new resource into our application. I'm going to add this directly to my UserControl, but it could also be added to the Application resources (in App.xaml).
To add the XAML to the UserControl create a new node named UserControl.Resources and copy the DataGrid XAML into it (use the handy "Copy Code" link on the documentation web page).
The namespace definitions for the DataGrid and the Resource must match. In the copied XAML the namespace is local:DataGrid. The default namespace generated by the Visual Studio tool is my:DataGrid. In the above example, I changed all references of local to my.
The next item to take care of is that the Style must have a Key. This is used to map a Framework element (our DataGrid) to a specific style definition. I've given the style a key of TestGrid which is used in the following DataGrid definition.
At this point, when you run the application the DataGrid should appear exactly as it did before (we haven't changed anything yet).
Before I start removing the definitions for the Border elements, I want to make sure that these are the culprits. To do this, I'm going to change their colors to something a little more obvious.
Running the application, I get the a screen
Zooming in, it's obvious how these elements take part in the display of the DataGrid.
Removing the Border elements from the XAML generates the desired results.
Hopefully, this not only provides a reference for how to remove the border from a DataGrid, but also provides a quick introduction to the possibilities available for customizing Silverlight controls.
Copied from: http://devcenter.auburnrandall.com/Default.aspx?type=post&id=52
The element you are seeing it is a Rectangle called ColumnHeadersAndRowsSeparator. Just create a Style without it:
<Style TargetType="sdk:DataGrid">
<Setter Property="RowBackground" Value="#AAEAEFF4" />
<Setter Property="AlternatingRowBackground" Value="#00FFFFFF" />
<Setter Property="Background" Value="#FFFFFFFF" />
<Setter Property="HeadersVisibility" Value="Column" />
<Setter Property="HorizontalScrollBarVisibility" Value="Auto" />
<Setter Property="VerticalScrollBarVisibility" Value="Auto" />
<Setter Property="SelectionMode" Value="Extended" />
<Setter Property="CanUserReorderColumns" Value="True" />
<Setter Property="CanUserResizeColumns" Value="True" />
<Setter Property="CanUserSortColumns" Value="True" />
<Setter Property="AutoGenerateColumns" Value="True" />
<Setter Property="RowDetailsVisibilityMode" Value="VisibleWhenSelected" />
<Setter Property="BorderBrush">
<Setter.Value>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#FFA3AEB9" Offset="0"/>
<GradientStop Color="#FF8399A9" Offset="0.375"/>
<GradientStop Color="#FF718597" Offset="0.375"/>
<GradientStop Color="#FF617584" Offset="1"/>
</LinearGradientBrush>
</Setter.Value>
</Setter>
<Setter Property="BorderThickness" Value="1" />
<Setter Property="DragIndicatorStyle">
<Setter.Value>
<!-- TODO: Change the TargetType to Control when the fix Jolt bugs 18719 is verified -->
<Style TargetType="ContentControl">
<Setter Property="Foreground" Value="#7FFFFFFF" />
<Setter Property="Template">
<Setter.Value>
<!-- TODO: Change the TargetType to Control when the fix Jolt bugs 18719 is verified -->
<ControlTemplate TargetType="ContentControl">
<Grid>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="SortStates">
<VisualState x:Name="Unsorted" />
<VisualState x:Name="SortAscending">
<Storyboard>
<DoubleAnimation Storyboard.TargetName="SortIcon" Storyboard.TargetProperty="Opacity" Duration="0" To="1.0"/>
</Storyboard>
</VisualState>
<VisualState x:Name="SortDescending">
<Storyboard>
<DoubleAnimation Storyboard.TargetName="SortIcon" Storyboard.TargetProperty="Opacity" Duration="0" To="1.0"/>
<DoubleAnimation Storyboard.TargetName="SortIcon" Storyboard.TargetProperty="(RenderTransform).ScaleY" Duration="0" To="-.9"/>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Rectangle x:Name="BackgroundRectangle" Stretch="Fill" Fill="#66808080" Grid.ColumnSpan="2" />
<Rectangle x:Name="BackgroundGradient" Stretch="Fill" Grid.ColumnSpan="2" Opacity="0" >
<Rectangle.Fill>
<LinearGradientBrush StartPoint=".7,0" EndPoint=".7,1">
<GradientStop Color="#FFFFFFFF" Offset="0.015" />
<GradientStop Color="#F9FFFFFF" Offset="0.375" />
<GradientStop Color="#E5FFFFFF" Offset="0.6" />
<GradientStop Color="#C6FFFFFF" Offset="1" />
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
<Grid HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" Margin="{TemplateBinding Padding}">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<ContentPresenter Content="{TemplateBinding Content}"/>
<Path Grid.Column="1" Name="SortIcon" Fill="#7FFFFFFF" RenderTransformOrigin=".5,.5" HorizontalAlignment="Left" VerticalAlignment="Center" Opacity="0" Stretch="Uniform" Width="8" Margin="4,0,0,0" Data="F1 M -5.215,6.099L 5.215,6.099L 0,0L -5.215,6.099 Z ">
<Path.RenderTransform>
<ScaleTransform ScaleX=".9" ScaleY=".9" />
</Path.RenderTransform>
</Path>
</Grid>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Setter.Value>
</Setter>
<Setter Property="DropLocationIndicatorStyle">
<Setter.Value>
<Style TargetType="ContentControl">
<Setter Property="Background" Value="#FF3F4346"/>
<Setter Property="Width" Value="2"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ContentControl">
<Rectangle Fill="{TemplateBinding Background}" Width="{TemplateBinding Width}" Height="{TemplateBinding Height}"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Setter.Value>
</Setter>
<Setter Property="GridLinesVisibility" Value="Vertical" />
<Setter Property="HorizontalGridLinesBrush" Value="#FFC9CACA" />
<Setter Property="IsTabStop" Value="True" />
<Setter Property="VerticalGridLinesBrush" Value="#FFC9CACA" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="sdk:DataGrid">
<Grid>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal"/>
<VisualState x:Name="Disabled">
<Storyboard>
<DoubleAnimation Storyboard.TargetName="DisabledVisualElement" Storyboard.TargetProperty="Opacity" Duration="0" To="1"/>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Border BorderThickness="{TemplateBinding BorderThickness}" BorderBrush="{TemplateBinding BorderBrush}" CornerRadius="2">
<Grid Name="Root" Background="{TemplateBinding Background}">
<Grid.Resources>
<!--Start: TopLeftHeaderTemplate-->
<ControlTemplate x:Key="TopLeftHeaderTemplate" TargetType="localprimitives:DataGridColumnHeader">
<Grid Name="Root">
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Border BorderThickness="0,0,1,0" BorderBrush="#FFC9CACA" Background="#FF1F3B53" Grid.RowSpan="2">
<Rectangle Stretch="Fill" StrokeThickness="1">
<Rectangle.Fill>
<LinearGradientBrush StartPoint=".7,0" EndPoint=".7,1">
<GradientStop Color="#FCFFFFFF" Offset="0.015" />
<GradientStop Color="#F7FFFFFF" Offset="0.375" />
<GradientStop Color="#E5FFFFFF" Offset="0.6" />
<GradientStop Color="#D1FFFFFF" Offset="1" />
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
</Border>
<Rectangle VerticalAlignment="Bottom" Width="Auto" StrokeThickness="1" Height="1" Fill="#FFDBDCDC" Grid.RowSpan="2"/>
</Grid>
</ControlTemplate>
<!--End: TopLeftHeaderTemplate-->
<!--Start: TopRightHeaderTemplate-->
<ControlTemplate x:Key="TopRightHeaderTemplate" TargetType="localprimitives:DataGridColumnHeader">
<Grid Name="RootElement">
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Border BorderThickness="1,0,0,0" BorderBrush="#FFC9CACA" Background="#FF1F3B53" Grid.RowSpan="2">
<Rectangle Stretch="Fill">
<Rectangle.Fill>
<LinearGradientBrush StartPoint=".7,0" EndPoint=".7,1">
<GradientStop Color="#FCFFFFFF" Offset="0.015" />
<GradientStop Color="#F7FFFFFF" Offset="0.375" />
<GradientStop Color="#E5FFFFFF" Offset="0.6" />
<GradientStop Color="#D1FFFFFF" Offset="1" />
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
</Border>
</Grid>
</ControlTemplate>
<!--End: TopRightHeaderTemplate-->
</Grid.Resources>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition/>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition/>
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<localprimitives:DataGridColumnHeader Name="TopLeftCornerHeader" Template="{StaticResource TopLeftHeaderTemplate}" Width="22" />
<localprimitives:DataGridColumnHeadersPresenter Name="ColumnHeadersPresenter" Grid.Column="1"/>
<localprimitives:DataGridColumnHeader Name="TopRightCornerHeader" Grid.Column="2" Template="{StaticResource TopRightHeaderTemplate}" />
<!-- HERE IT IS THAT LINE YOU SEE -->
<!--<Rectangle Name="ColumnHeadersAndRowsSeparator" Grid.ColumnSpan="3" VerticalAlignment="Bottom" Width="Auto" StrokeThickness="1" Height="1" Fill="#FFC9CACA"/>-->
<localprimitives:DataGridRowsPresenter Name="RowsPresenter" Grid.ColumnSpan="2" Grid.Row="1" />
<Rectangle Name="BottomRightCorner" Fill="#FFE9EEF4" Grid.Column="2" Grid.Row="2" />
<Rectangle Name="BottomLeftCorner" Fill="#FFE9EEF4" Grid.Row="2" Grid.ColumnSpan="2" />
<ScrollBar Name="VerticalScrollbar" Orientation="Vertical" Grid.Column="2" Grid.Row="1" Width="18" Margin="0,-1,-1,-1"/>
<Grid Grid.Column="1" Grid.Row="2">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Rectangle Name="FrozenColumnScrollBarSpacer" />
<ScrollBar Name="HorizontalScrollbar" Grid.Column="1" Orientation="Horizontal" Height="18" Margin="-1,0,-1,-1"/>
</Grid>
</Grid>
</Border>
<Border x:Name="DisabledVisualElement" IsHitTestVisible="False" Height="Auto" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Width="Auto" CornerRadius="2" Background="#8CFFFFFF" Opacity="0"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

Removing the MouseOver effect from a Silverlight Context Menu

I'm trying to achieve the effect of a pop-up when the user right-clicks in a Silverlight application that shows essentially a custom control. I'm using a Context Menu, and all is working great except that I'm having trouble styling the context menu so that it doesn't highlight itself when the user mouses over.
Here's a snippet of what I'm trying to do:
<toolkit:ContextMenuService.ContextMenu>
<toolkit:ContextMenu Height="100" Background="Transparent" HorizontalOffset="-100" VerticalOffset="-100" Margin="98,112,0,0" Name="contextMenu1" VerticalAlignment="Top" Width="200">
<toolkit:ContextMenu.Style>
<Style TargetType="toolkit:ContextMenu">
<Setter Property="BorderThickness" Value="0" />
<Setter Property="Padding" Value="0" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="toolkit:ContextMenu">
<Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" CornerRadius="2">
<Grid>
<ItemsPresenter Margin="{TemplateBinding Padding}" />
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</toolkit:ContextMenu.Style>
<Canvas Width="100" Height="100" Background="Transparent">
<Button Width="100" Height="30">Something</Button>
<Button Width="100" Height="30" Canvas.Top="70">Something Else</Button>
</Canvas>
</toolkit:ContextMenu>
</toolkit:ContextMenuService.ContextMenu>
When the menu is visible I get the effect I want (the two buttons just floating near the mouse), but when I mouse over it the entire box of the context menu highlights itself.
Here's a sample app that demonstrates this:
http://github.com/vermeeca/ContextMenuDemo
How can I disable that effect?
Thanks to a co-worker I've got the solution. I just had to set the ItemContainerStyle on the ContextMenu.
<UserControl.Resources>
<Style x:Key="NoMouseOverStyle" TargetType="toolkit:MenuItem">
<Setter Property="Background" Value="Transparent"/>
<Setter Property="BorderBrush" Value="Transparent"/>
<Setter Property="Padding" Value="4,3,2,3"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="toolkit:MenuItem">
<Grid>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal"/>
<VisualState x:Name="Disabled">
<Storyboard>
<DoubleAnimation Duration="0" To="0.5" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="Presenter"/>
</Storyboard>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="FocusStates">
<VisualState x:Name="Unfocused"/>
<!-- VisualState x:Name="Focused">
<Storyboard>
<DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="Bg"/>
<ColorAnimation Duration="0" To="#40FFFFFF" Storyboard.TargetProperty="(Shape.Stroke).(SolidColorBrush.Color)" Storyboard.TargetName="InnerBorder"/>
</Storyboard>
</VisualState -->
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Rectangle Fill="{TemplateBinding Background}" RadiusY="2" RadiusX="2" Stroke="{TemplateBinding BorderBrush}" StrokeThickness="1"/>
<Rectangle x:Name="Bg" Opacity="0" RadiusY="2" RadiusX="2" Stroke="#8071CBF1" StrokeThickness="1">
<Rectangle.Fill>
<LinearGradientBrush EndPoint="0,1" StartPoint="0,0">
<GradientStop Color="#34C5EBFF" Offset="0"/>
<GradientStop Color="#3481D8FF" Offset="1"/>
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
<Rectangle x:Name="InnerBorder" Margin="1" RadiusY="2" RadiusX="2" Stroke="Transparent"/>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition MinWidth="24" Width="Auto"/>
<ColumnDefinition Width="4"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="17"/>
</Grid.ColumnDefinitions>
<ContentPresenter Content="{TemplateBinding Icon}" Margin="1" VerticalAlignment="Center"/>
<ContentPresenter x:Name="Presenter" ContentTemplate="{TemplateBinding HeaderTemplate}" Content="{TemplateBinding Header}" Grid.Column="2" Margin="{TemplateBinding Padding}"/>
</Grid>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</UserControl.Resources>
And then
<toolkit:ContextMenu Height="100" Background="Transparent" HorizontalOffset="-100" VerticalOffset="-100" Margin="98,112,0,0" Name="contextMenu1" VerticalAlignment="Top" Width="200" ItemContainerStyle="{StaticResource NoMouseOverStyle}">

Silverlight AutoCompleteBox BorderBrush runtime color change?

Is it possible to update a templated AutoCompleteBox's BorderBrush at runtime? I can't seem to set the BorderBrush or the background.
Even base statements like TxtFoodSearch.BorderBrush = new SolidColorBrush(Colors.Red) don't seem to made a difference after the page has loaded.
My Xaml is below.
<controls:AutoCompleteBox x:Name="MyAutoCompleteSample" Margin="17,24,58,32" FontSize="12">
<controls:AutoCompleteBox.Style>
<Style TargetType="controls:AutoCompleteBox">
<Setter Property="IsTabStop" Value="False" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="controls:AutoCompleteBox">
<Grid Margin="{TemplateBinding Padding}"
Background="{TemplateBinding Background}">
<TextBox IsTabStop="True" x:Name="Text" Style="{TemplateBinding TextBoxStyle}" Margin="0"
KeyDown="MyAutoCompleteSample_KeyDown"
/>
<Popup x:Name="Popup">
<Border x:Name="PopupBorder" HorizontalAlignment="Stretch" Opacity="0.0" BorderThickness="0" CornerRadius="3">
<Border.RenderTransform>
<TranslateTransform X="1" Y="1" />
</Border.RenderTransform>
<Border.Background>
<SolidColorBrush Color="#11000000" />
</Border.Background>
<Border
HorizontalAlignment="Stretch"
Opacity="1.0"
Padding="0"
ToolTipService.ToolTip="Select or enter your food selection"
BorderThickness="{TemplateBinding BorderThickness}"
BorderBrush="{TemplateBinding BorderBrush}"
CornerRadius="3">
<Border.RenderTransform>
<TransformGroup>
<TranslateTransform X="-1" Y="-1" />
</TransformGroup>
</Border.RenderTransform>
<Border.Background>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#FFDDDDDD" Offset="0"/>
<GradientStop Color="#AADDDDDD" Offset="1"/>
</LinearGradientBrush>
</Border.Background>
<ListBox
x:Name="SelectionAdapter"
ScrollViewer.HorizontalScrollBarVisibility="Auto"
ScrollViewer.VerticalScrollBarVisibility="Auto"
ItemContainerStyle="{TemplateBinding ItemContainerStyle}"
ItemTemplate="{TemplateBinding ItemTemplate}" />
</Border>
</Border>
</Popup>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="PopupStates">
<VisualStateGroup.Transitions>
<VisualTransition GeneratedDuration="0:0:0.1" To="PopupOpened" />
<VisualTransition GeneratedDuration="0:0:0.2" To="PopupClosed" />
</VisualStateGroup.Transitions>
<VisualState x:Name="PopupOpened">
<Storyboard>
<DoubleAnimation Storyboard.TargetName="PopupBorder" Storyboard.TargetProperty="Opacity" To="1.0" />
</Storyboard>
</VisualState>
<VisualState x:Name="PopupClosed">
<Storyboard>
<DoubleAnimation Storyboard.TargetName="PopupBorder" Storyboard.TargetProperty="Opacity" To="0.0" />
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</controls:AutoCompleteBox.Style>
</controls:AutoCompleteBox>
One way I've managed to find how to address the styling through code is the following.
Walk the visual tree and get the AutoCompleteBox, cast that into a textbox, then adjust the colors (border, background, etc)
//Cast into textbox
TextBox Temp = VisualTreeHelper.GetChild(VisualTreeHelper.GetChild(MyAutoCompleteControl, 0), 0) as TextBox;
Temp.BorderBrush = new SolidColorBrush(Colors.Red);//Change border color
I'm sure there is a better way, but this seems to work.
If you're using Silverlight 3 (where styles can be set multiple times), then it is easier: you can actually set the TextBoxStyle (on MSDN here).
You can then create a new Style in code-behind (a pain), or perhaps change/apply another of your pre-defined styles in code.

Resources