How can I set LinearGradientBrush as the background for of ContentPages? - xamarin

How can I add LinearGradientBrush as ContentPage.Background in App.xaml's ResourceDictionary? My code pasted below:
<LinearGradientBrush EndPoint="0,1">
<GradientStop Color="LightBlue"
Offset="0.1" />
<GradientStop Color="DarkBlue"
Offset="1.0" />
</LinearGradientBrush>

As LinearGradientBrush is a preview concept,don't forgget to add below codes in your App.xaml.cs.
Device.SetFlags(new string[] {"Brush_Experimental" });
and add below to the App.xaml:
<Application.Resources>
<ResourceDictionary>
<Style TargetType="ContentPage" ApplyToDerivedTypes="True">
<Setter Property="Background">
<LinearGradientBrush EndPoint="0,1">
<GradientStop Color="LightBlue"
Offset="0.1" />
<GradientStop Color="DarkBlue"
Offset="1.0" />
</LinearGradientBrush>
</Setter>
</Style>
</ResourceDictionary>
</Application.Resources>

Related

Xamarin.Forms: How to set the Color of Icons in FlyoutItems in AppShell

I am implementing a Xamarin.Forms app using AppShell and can't seem to figure out how to set the color of the selected / unselected icons in the Flyout menu. Here is the section of the appshell.xaml that I believe is controlling the behavior (I used various high contrast colors to show what settings are controlling what). (The complete code sample: https://github.com/wadebaird/ShellExample for more reference):
<Style x:Name="FlyoutItem" Class="FlyoutItemLayoutStyle" TargetType="Layout" ApplyToDerivedTypes="True">
<Setter Property="VisualStateManager.VisualStateGroups">
<VisualStateGroupList>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal">
<VisualState.Setters>
<!-- This is the color of the unselected text for the labels in the flyout-->
<Setter TargetName="FlyoutItemLabel" Property="Label.TextColor" Value="Magenta" />
<Setter TargetName="FlyoutItemLabel" Property="Label.BackgroundColor" Value="Cyan" />
<!-- This is the background color of the selected icon in the flyout -->
<Setter Property="BackgroundColor" Value="Green" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Selected">
<VisualState.Setters>
<!-- This is the color of the selected text in the flyout -->
<Setter TargetName="FlyoutItemLabel" Property="Label.TextColor" Value="Black"/>
<Setter TargetName="FlyoutItemLabel" Property="Label.BackgroundColor" Value="Yellow" />
<!-- This is the background color of the selected icon in the flyout -->
<Setter Property="BackgroundColor" Value="Red" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateGroupList>
</Setter>
</Style>
And here is the visuals from these settings. In this image, the "Entity at the top is the "selected" item. I would expect / want the icons to match the colors of the text but can't seem to find the setting.
Here is what I'm going for to show how "white" for the icons doesn't work:
I can manually set the color on the FontImageSource, but then it is always that color and doesn't match the selected / unselected:
<ShellContent Route="aboutPage" Title="About" ContentTemplate="{DataTemplate views:AboutPage}" >
<ShellContent.Icon>
<FontImageSource Size="{StaticResource FlyoutIconSize}" Color="Black" Glyph="{x:Static fontAwesome:FontAwesomeIcons.InfoCircle}" FontFamily="FA-Solid" />
</ShellContent.Icon>
</ShellContent>
I tried various things such as this withing the "Common States"- "Normal"/"Selected" and couldn't get anything to work.:
<Setter Property="FontImageSource.Color" Value="{AppThemeBinding Light={StaticResource PrimaryUnselectedTextColorLight}, Dark={StaticResource PrimaryUnselectedTextColorDark}}" />
And on a side note (and this is probably a bug). It appears on iOS that when first opening the flyout nothing is "selected":
Where on Android, the proper item is selected:
I know this is a seperate item, and I'll log a bug if I can't find an existing issue/bug, but I figured I'd mention it as someone thgat knows the answer to my above probably is already aware of this issue.
You could use the Shell.ItemTemplate to set the background color of the Label and Icon. And use the VisualStateGroup to change the color of Selected status.
Shell.ItemTemplate:
<Shell.ItemTemplate>
<DataTemplate>
<Grid ColumnDefinitions="0.2*,0.8*" ColumnSpacing="0" Style="{StaticResource FloutItemStyle}">
<Image x:Name="FlyoutItemIcon" Source="{Binding FlyoutIcon}" HeightRequest="45" />
<Label x:Name="FlyoutItemLabel" Grid.Column="1"
Text="{Binding Title}"
FontAttributes="Italic"
VerticalTextAlignment="Center" />
</Grid>
</DataTemplate>
</Shell.ItemTemplate>
Style:
<Style x:Key="FloutItemStyle" Class="FlyoutItemLayoutStyle" TargetType="Layout" ApplyToDerivedTypes="True">
<Setter Property="VisualStateManager.VisualStateGroups">
<VisualStateGroupList>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal">
<VisualState.Setters>
<Setter Property="BackgroundColor" Value="{x:OnPlatform UWP=Transparent, iOS=White}" />
<Setter TargetName="FlyoutItemLabel" Property="Label.TextColor" Value="{StaticResource Primary}" />
<Setter TargetName="FlyoutItemLabel" Property="Label.BackgroundColor" Value="Blue" />
<Setter TargetName="FlyoutItemIcon" Property="Image.BackgroundColor" Value="Green" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Selected">
<VisualState.Setters>
<Setter Property="BackgroundColor" Value="{StaticResource Primary}" />
<Setter TargetName="FlyoutItemLabel" Property="Label.BackgroundColor" Value="{StaticResource Primary}" />
<Setter TargetName="FlyoutItemIcon" Property="Image.BackgroundColor" Value="{StaticResource Primary}" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateGroupList>
</Setter>
</Style>
After Wendy Zang replied with a partial solution (it solved the background color but not the foreground), it got me on the right track
and I was able to find the answer to this posted question, which utilized two labels instead of an image. (I also tried to use the Image that Wendy suggested above and an effect like the IconTintColorEffect.TintColor from this post, but I couldn't get that to work quite right either as the sizing of the icon was a lot trickier with it being an image.)
I tried the solution with having the different types of derived classes with the IconGlyph property and I got it to work well, but I didn't like the cleanliness of it. I then thought of using an IValueConverter to fix the binding for the label class:
public class FlyoutGlyphConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (value == null)
return null;
if (value is not BaseShellItem baseShellItem)
throw new ArgumentException($"This converter may only be used on values of type {nameof(BaseShellItem)}.");
if (baseShellItem.Icon is not FontImageSource fontImageSource)
throw new ArgumentException($"This converter may only be used on values of type {nameof(BaseShellItem)}s with Icons of type {nameof(FontImageSource)}.");
return fontImageSource.Glyph;
}
}
And my xaml ended up being like so:
<Shell.ItemTemplate>
<DataTemplate x:DataType="root:IShellIconFont">
<Grid Margin="0" Padding="0" ColumnSpacing="0">
<VisualStateManager.VisualStateGroups>
<VisualStateGroupList>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal">
<VisualState.Setters>
<!-- This is the color of the unselected text for the labels in the flyout-->
<Setter TargetName="FlyoutItemLabel" Property="Label.TextColor" Value="#2196F3" />
<Setter TargetName="FlyoutItemLabel" Property="Label.BackgroundColor" Value="White" />
<!-- This is the background color of the selected icon in the flyout -->
<Setter TargetName="FlyoutItemIcon" Property="Image.BackgroundColor" Value="White" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Selected">
<VisualState.Setters>
<!-- This is the color of the selected text in the flyout -->
<Setter TargetName="FlyoutItemLabel" Property="Label.TextColor" Value="White"/>
<Setter TargetName="FlyoutItemLabel" Property="Label.BackgroundColor" Value="#2196F3" />
<!-- This is the background color of the selected icon in the flyout -->
<Setter TargetName="FlyoutItemIcon" Property="Image.BackgroundColor" Value="#2196F3" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateGroupList>
</VisualStateManager.VisualStateGroups>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.2*" />
<ColumnDefinition Width="0.8*" />
</Grid.ColumnDefinitions>
<Label x:Name="FlyoutItemIcon" Grid.Column="0" FontFamily="FA-Solid" FontSize="{StaticResource FlyoutIconSize}"
Text="{Binding ., Converter={StaticResource FlyoutGlyph}}" TextColor="{Binding Source={x:Reference FlyoutItemLabel}, Path=TextColor}"
VerticalTextAlignment="Center" HorizontalTextAlignment="Center"
Margin="0" Padding="0"/>
<Label x:Name="FlyoutItemLabel" Grid.Column="1" Text="{Binding Title}" FontSize="{StaticResource FlyoutLabelFontSize}"
FontAttributes="Bold" VerticalTextAlignment="Center" HeightRequest="45" />
</Grid>
</DataTemplate>
</Shell.ItemTemplate>
<FlyoutItem Route="root" Title="Entitys" FlyoutDisplayOptions="AsMultipleItems">
<root:ShellContentIconFont Route="mainPage" Title="Entity" Glyph="{x:Static fontAwesome:FontAwesomeIcons.BookOpen}" ContentTemplate="{DataTemplate views:MainPage}" />
<root:ShellContentIconFont Route="favoritesPage" Title="Favorites" Glyph="{x:Static fontAwesome:FontAwesomeIcons.Star}" ContentTemplate="{DataTemplate views:FavoritesPage}" />
<root:TabIconFont Route="entitys" Title="Entitys" Glyph="{x:Static fontAwesome:FontAwesomeIcons.Book}" >
<ShellContent Route="entitysCalendar" Title="Calendar" ContentTemplate="{DataTemplate views:EntitysCalendarPage}" />
<ShellContent Route="entitysList" Title="List" ContentTemplate="{DataTemplate views:EntitysListPage}" />
</root:TabIconFont>
</FlyoutItem>
<FlyoutItem Route="root" Title="Entitys" FlyoutDisplayOptions="AsMultipleItems">
<ShellContent Route="mainPage" Title="Entity" ContentTemplate="{DataTemplate views:MainPage}">
<ShellContent.Icon>
<FontImageSource Size="{StaticResource FlyoutIconSize}" Glyph="{x:Static fontAwesome:FontAwesomeIcons.BookOpen}" FontFamily="FA-Solid" />
</ShellContent.Icon>
</ShellContent>
<ShellContent Route="favoritesPage" Title="Favorites" ContentTemplate="{DataTemplate views:FavoritesPage}">
<ShellContent.Icon>
<FontImageSource Size="{StaticResource FlyoutIconSize}" Glyph="{x:Static fontAwesome:FontAwesomeIcons.Star}" FontFamily="FA-Solid" />
</ShellContent.Icon>
</ShellContent>
<Tab Route="entitys" Title="Entitys">
<Tab.Icon>
<FontImageSource Size="{StaticResource FlyoutIconSize}" Glyph="{x:Static fontAwesome:FontAwesomeIcons.Book}" FontFamily="FA-Solid" />
</Tab.Icon>
<ShellContent Route="entitysCalendar" Title="Calendar" ContentTemplate="{DataTemplate views:EntitysCalendarPage}" />
<ShellContent Route="entitysList" Title="List" ContentTemplate="{DataTemplate views:EntitysListPage}" />
</Tab>
</FlyoutItem>
<ShellContent Route="aboutPage" Title="About" ContentTemplate="{DataTemplate views:AboutPage}" >
<ShellContent.Icon>
<FontImageSource Size="{StaticResource FlyoutIconSize}" Glyph="{x:Static fontAwesome:FontAwesomeIcons.InfoCircle}" FontFamily="FA-Solid" />
</ShellContent.Icon>
</ShellContent>
Here is the final result:
A side not, something in this solution fixed the iOS issue where nothing was selected on initial opening. I'm guessing it was the definded DataTemplate.

Change Toolbar Color for Xamarin Mobile App

I am new to xamarin.forms development and I am using VisualStudio 2019 to achieve the same. I am developing a sample shell application but unable to change the colour of toolbar(blue color in the picture). Could anyone please help me on this issue.
We could set the background color by add BackgroundColor="Green" in the shell.xaml
For example we set it it Green
<Shell xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:d="http://xamarin.com/schemas/2014/forms/design"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
xmlns:local="clr-namespace:xxx"
Title="xxx"
BackgroundColor="Green"
x:Class="xxx.AppShell">
This will let color of TabBar been changed to green at the same time . So we should create styles for TabBar.
<Shell.Resources>
<ResourceDictionary>
<Color x:Key="NavigationPrimary">#2196F3</Color> //color of TabBar
<Style x:Key="BaseStyle" TargetType="Element">
<Setter Property="Shell.BackgroundColor" Value="{StaticResource NavigationPrimary}" />
<Setter Property="Shell.ForegroundColor" Value="White" />
<Setter Property="Shell.TitleColor" Value="White" />
<Setter Property="Shell.DisabledColor" Value="#B4FFFFFF" />
<Setter Property="Shell.UnselectedColor" Value="#95FFFFFF" />
<Setter Property="Shell.TabBarBackgroundColor" Value="{StaticResource NavigationPrimary}" />
<Setter Property="Shell.TabBarForegroundColor" Value="White"/>
<Setter Property="Shell.TabBarUnselectedColor" Value="#95FFFFFF"/>
<Setter Property="Shell.TabBarTitleColor" Value="White"/>
</Style>
<Style x:Key="MyBaseStyle" TargetType="Element">
<Setter Property="Shell.ForegroundColor" Value="White" />
<Setter Property="Shell.TitleColor" Value="White" />
<Setter Property="Shell.DisabledColor" Value="#B4FFFFFF" />
<Setter Property="Shell.UnselectedColor" Value="#95FFFFFF" />
<Setter Property="Shell.TabBarBackgroundColor" Value="{StaticResource NavigationPrimary}" />
<Setter Property="Shell.TabBarForegroundColor" Value="White"/>
<Setter Property="Shell.TabBarUnselectedColor" Value="#95FFFFFF"/>
<Setter Property="Shell.TabBarTitleColor" Value="White"/>
</Style>
<Style TargetType="ShellItem" BasedOn="{StaticResource BaseStyle}" />
<Style TargetType="TabBar" BasedOn="{StaticResource MyBaseStyle}" />
</ResourceDictionary>
</Shell.Resources>
<!-- Your Pages -->
<TabBar >
<Tab Title="xxx" Icon="xxx" >
<ShellContent ContentTemplate="{DataTemplate xxx}" />
</Tab>
<Tab Title="xxx" Icon="xxx">
<ShellContent ContentTemplate="{DataTemplate xxx}" />
</Tab>
</TabBar>

Change windowStyle of Prism Dialogwindow

How can I change the window style dynamically via Trigger?
Like:
<Style TargetType="UserControl">
<Setter Property="prism:Dialog.WindowStyle" Value="{DynamicResource DefaultDialogStyleTheme}"></Setter>
<Style.Triggers>
<DataTrigger
Binding="{Binding SecondOne, UpdateSourceTrigger=PropertyChanged}"
Value="true">
<Setter Property="prism:Dialog.WindowStyle" Value="{DynamicResource DialogStyleTheme}"></Setter>
</DataTrigger>
</Style.Triggers>
</Style>`
You can register your own IDialogWindow implementation that has all the styles you desire.
The library's implementation's code's here (xaml) and there (code-behind) as a reference.
Thanks for your help :), But for example before we switched to new Prism, we've used a PopupWindowAction to raise a default window or a custom window:
var wrapperWindow = GetWindow(args.Context);
wrapperWindow.ShowDialog();
GetWindow returns a Window or CustomWindowObject.
That's the custom window style:
<Style x:Key="DialogStyleTheme" TargetType="implementation:CustomDialogWindow">
<Setter Property="WindowStyle" Value="None" />
<Setter Property="ResizeMode" Value="CanMinimize" />
<Setter Property="SizeToContent" Value="WidthAndHeight" />
<Setter Property="Background" Value="Transparent" />
<Setter Property="AllowsTransparency" Value="True" />
<Setter Property="FontSize" Value="60" />
<Setter Property="ShowInTaskbar" Value="False" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="implementation:CustomDialogWindow">
<Border BorderThickness="2" CornerRadius="10" BorderBrush="White" Background="DimGray"
x:Name="MainBorder">
<Grid Background="{TemplateBinding Background}" Margin="5,5,5,5">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="30" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid Grid.Row="0" x:Name="MoveGrid">
<Image x:Name="Image">
<Image.Style>
<Style TargetType="Image">
<Setter Property="Stretch" Value="UniformToFill" />
<Style.Triggers>
<DataTrigger Binding="{Binding SmallTitle}" Value="true">
<Setter Property="Height" Value="40" />
</DataTrigger>
</Style.Triggers>
</Style>
</Image.Style>
</Image>
<TextBlock Text="{Binding Title}">
<TextBlock.Style>
<Style BasedOn="{StaticResource TouchHeadTextBlock}" TargetType="TextBlock">
<Style.Triggers>
<DataTrigger Binding="{Binding SmallTitle}" Value="true">
<Setter Property="FontSize" Value="25" />
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
</Grid>
<ContentPresenter Grid.Row="2" x:Name="ContentPresenter" ClipToBounds="True" />
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
And I'm setting the WindowStyle in my UserControl and I want to change this style via trigger....
prism:Dialog.WindowStyle="{DynamicResource DialogStyleTheme}"
Initialization:
containerRegistry.RegisterDialog<ItemSelectionDialogView, ItemSelectionDialogViewModel>();
containerRegistry.RegisterDialogWindow<CustomDialogWindow>();

how to put stackpanel style property in style and setter

how can put the below style property into style , setter
<StackPanel >
<StackPanel.Background>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="Black" Offset="0"/>
<GradientStop Color="#FF707070"/>
</LinearGradientBrush>
</StackPanel.Background>
</StackPanel>
it thing it may like
<Style TargetType="StackPanel" x:Key="Psp">
<Setter Property="Background" Value="Black" ></Setter>
<Setter Property="Background">
<Setter.Value >
<StackPanel >
<StackPanel.Background>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="Black" Offset="0"/>
<GradientStop Color="#FF707070"/>
</LinearGradientBrush>
</StackPanel.Background>
</StackPanel>
</Setter.Value>
</Setter>
</Style>
it giving error on <Setter.Value >
Specified value cannot be assigned, the following type is expected
"Brush"
<StackPanel Grid.Row="1" Style="{StaticResource Psp}">
<TextBlock Text="This is a test"></TextBlock>
</StackPanel>
In your app.xaml
<Application.Resources>
<Style TargetType="StackPanel" x:Key="Psp">
<Setter Property="Background" Value="Black" ></Setter>
<Setter Property="Background">
<Setter.Value >
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="Black" Offset="0"/>
<GradientStop Color="#FF707070"/>
</LinearGradientBrush>
</Setter.Value>
</Setter>
</Style>
</Application.Resources>
In your page
<StackPanel Grid.Row="1" Style="{StaticResource Psp}">
<TextBlock Text="This is a test"></TextBlock>
</StackPanel>
You can obviously define the style on the page level or control level too.
Thanks every i have solve this problem
<Style TargetType="StackPanel" x:Key="Psp">
<Setter Property="Margin" Value="5,5,3,5" />
<Setter Property="Height" Value="40"/>
<Setter Property="Background" Value="{StaticResource Brushh}" ></Setter>
</Style>
<LinearGradientBrush x:Key="Brushh" EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="Black" Offset="0"/>
<GradientStop Color="#FF707070"/>
</LinearGradientBrush>

Animate Expander in WPF

How to animate the expanded and collapsed actions of a Wpf expander control?
I've found this article on Code Project : Read Here
The author creates his own SimpleExpander Template, then adds a stretch out animation to it. He even added a nifty rotating arrow to it.
I created a style based on msdn Style and the point in this answer:
<Window x:Class="Test.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:Test"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
xmlns:scm="clr-namespace:System.ComponentModel;assembly=WindowsBase"
mc:Ignorable="d">
<Window.Resources>
<Color x:Key="WindowColor">#FFE8EDF9</Color>
<Color x:Key="ContentAreaColorLight">#FFC5CBF9</Color>
<Color x:Key="ContentAreaColorDark">#FF7381F9</Color>
<Color x:Key="DisabledControlLightColor">#FFE8EDF9</Color>
<Color x:Key="DisabledControlDarkColor">#FFC5CBF9</Color>
<Color x:Key="DisabledForegroundColor">#FF888888</Color>
<Color x:Key="SelectedBackgroundColor">#FFC5CBF9</Color>
<Color x:Key="SelectedUnfocusedColor">#FFDDDDDD</Color>
<Color x:Key="ControlLightColor">White</Color>
<Color x:Key="ControlMediumColor">#FF7381F9</Color>
<Color x:Key="ControlDarkColor">#FF211AA9</Color>
<Color x:Key="ControlMouseOverColor">#FF3843C4</Color>
<Color x:Key="ControlPressedColor">#FF211AA9</Color>
<Color x:Key="GlyphColor">#FF444444</Color>
<Color x:Key="GlyphMouseOver">sc#1, 0.004391443, 0.002428215, 0.242281124</Color>
<!--Border colors-->
<Color x:Key="BorderLightColor">#FFCCCCCC</Color>
<Color x:Key="BorderMediumColor">#FF888888</Color>
<Color x:Key="BorderDarkColor">#FF444444</Color>
<Color x:Key="PressedBorderLightColor">#FF888888</Color>
<Color x:Key="PressedBorderDarkColor">#FF444444</Color>
<Color x:Key="DisabledBorderLightColor">#FFAAAAAA</Color>
<Color x:Key="DisabledBorderDarkColor">#FF888888</Color>
<Color x:Key="DefaultBorderBrushDarkColor">Black</Color>
<!--Control-specific resources.-->
<Color x:Key="HeaderTopColor">#FFC5CBF9</Color>
<Color x:Key="DatagridCurrentCellBorderColor">Black</Color>
<Color x:Key="SliderTrackDarkColor">#FFC5CBF9</Color>
<Color x:Key="NavButtonFrameColor">#FF3843C4</Color>
<LinearGradientBrush x:Key="MenuPopupBrush"
EndPoint="0.5,1"
StartPoint="0.5,0">
<GradientStop Color="{DynamicResource ControlLightColor}"
Offset="0" />
<GradientStop Color="{DynamicResource ControlMediumColor}"
Offset="0.5" />
<GradientStop Color="{DynamicResource ControlLightColor}"
Offset="1" />
</LinearGradientBrush>
<LinearGradientBrush x:Key="ProgressBarIndicatorAnimatedFill"
StartPoint="0,0"
EndPoint="1,0">
<LinearGradientBrush.GradientStops>
<GradientStopCollection>
<GradientStop Color="#000000FF"
Offset="0" />
<GradientStop Color="#600000FF"
Offset="0.4" />
<GradientStop Color="#600000FF"
Offset="0.6" />
<GradientStop Color="#000000FF"
Offset="1" />
</GradientStopCollection>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
<ControlTemplate x:Key="ExpanderToggleButton"
TargetType="{x:Type ToggleButton}">
<Border x:Name="Border"
CornerRadius="2,0,0,0"
BorderThickness="0,0,1,0">
<Border.Background>
<LinearGradientBrush EndPoint="0.5,1"
StartPoint="0.5,0">
<GradientStop Color="{DynamicResource ControlLightColor}" />
<GradientStop Color="{DynamicResource ControlMediumColor}"
Offset="1" />
</LinearGradientBrush>
</Border.Background>
<Border.BorderBrush>
<LinearGradientBrush StartPoint="0,0"
EndPoint="0,1">
<LinearGradientBrush.GradientStops>
<GradientStopCollection>
<GradientStop Color="{DynamicResource BorderLightColor}"
Offset="0.0" />
<GradientStop Color="{DynamicResource BorderDarkColor}"
Offset="1.0" />
</GradientStopCollection>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
</Border.BorderBrush>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="MouseOver">
<Storyboard>
<ColorAnimationUsingKeyFrames Storyboard.TargetName="Border"
Storyboard.TargetProperty="(Panel.Background).
(GradientBrush.GradientStops)[1].(GradientStop.Color)">
<EasingColorKeyFrame KeyTime="0"
Value="{StaticResource ControlMouseOverColor}" />
</ColorAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Pressed">
<Storyboard>
<ColorAnimationUsingKeyFrames Storyboard.TargetName="Border"
Storyboard.TargetProperty="(Panel.Background).
(GradientBrush.GradientStops)[1].(GradientStop.Color)">
<EasingColorKeyFrame KeyTime="0"
Value="{StaticResource ControlPressedColor}" />
</ColorAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Disabled">
<Storyboard>
<ColorAnimationUsingKeyFrames Storyboard.TargetName="Border"
Storyboard.TargetProperty="(Panel.Background).
(GradientBrush.GradientStops)[1].(GradientStop.Color)">
<EasingColorKeyFrame KeyTime="0"
Value="{StaticResource DisabledControlDarkColor}" />
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames Storyboard.TargetName="Border"
Storyboard.TargetProperty="(Border.BorderBrush).
(GradientBrush.GradientStops)[1].(GradientStop.Color)">
<EasingColorKeyFrame KeyTime="0"
Value="{StaticResource DisabledBorderLightColor}" />
</ColorAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="CheckStates">
<VisualState x:Name="Checked">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)"
Storyboard.TargetName="CollapsedArrow">
<DiscreteObjectKeyFrame KeyTime="0"
Value="{x:Static Visibility.Hidden}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)"
Storyboard.TargetName="ExpandededArrow">
<DiscreteObjectKeyFrame KeyTime="0"
Value="{x:Static Visibility.Visible}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Unchecked" />
<VisualState x:Name="Indeterminate" />
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Grid>
<Path x:Name="CollapsedArrow"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Data="M 0 0 L 4 4 L 8 0 Z">
<Path.Fill>
<SolidColorBrush Color="{DynamicResource GlyphColor}" />
</Path.Fill>
</Path>
<Path x:Name="ExpandededArrow"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Visibility="Collapsed"
Data="M 0 4 L 4 0 L 8 4 Z">
<Path.Fill>
<SolidColorBrush Color="{DynamicResource GlyphColor}" />
</Path.Fill>
</Path>
</Grid>
</Border>
</ControlTemplate>
<Style TargetType="{x:Type Expander}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Expander}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition x:Name="ContentRow" >
<RowDefinition.Resources>
<local:MultiplyConverter x:Key="multiplyConverter"/>
</RowDefinition.Resources>
<RowDefinition.Tag>
<sys:Double>0.0</sys:Double>
</RowDefinition.Tag>
<RowDefinition.Height>
<MultiBinding Converter="{StaticResource multiplyConverter}">
<Binding Path="DesiredSize.Height" ElementName="Content" />
<Binding Path="Tag" RelativeSource="{RelativeSource Self}" />
</MultiBinding>
</RowDefinition.Height>
</RowDefinition>
</Grid.RowDefinitions>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="MouseOver" />
<VisualState x:Name="Disabled">
<Storyboard>
<ColorAnimationUsingKeyFrames Storyboard.TargetName="Border"
Storyboard.TargetProperty="(Panel.Background).
(GradientBrush.GradientStops)[1].(GradientStop.Color)">
<EasingColorKeyFrame KeyTime="0"
Value="{StaticResource DisabledControlDarkColor}" />
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames Storyboard.TargetName="Border"
Storyboard.TargetProperty="(Border.BorderBrush).
(GradientBrush.GradientStops)[1].(GradientStop.Color)">
<EasingColorKeyFrame KeyTime="0"
Value="{StaticResource DisabledBorderLightColor}" />
</ColorAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Border x:Name="Border" Grid.Row="0" BorderThickness="1" CornerRadius="2,2,0,0">
<Border.BorderBrush>
<LinearGradientBrush EndPoint="0,1"
StartPoint="0,0">
<GradientStop Color="{DynamicResource BorderLightColor}"
Offset="0" />
<GradientStop Color="{DynamicResource BorderDarkColor}"
Offset="1" />
</LinearGradientBrush>
</Border.BorderBrush>
<Border.Background>
<LinearGradientBrush StartPoint="0,0"
EndPoint="0,1">
<LinearGradientBrush.GradientStops>
<GradientStopCollection>
<GradientStop Color="{DynamicResource ControlLightColor}"
Offset="0.0" />
<GradientStop Color="{DynamicResource ControlMediumColor}"
Offset="1.0" />
</GradientStopCollection>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
</Border.Background>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="20" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<ToggleButton OverridesDefaultStyle="True"
Template="{StaticResource ExpanderToggleButton}"
IsChecked="{Binding IsExpanded, Mode=TwoWay,
RelativeSource={RelativeSource TemplatedParent}}">
<ToggleButton.Background>
<LinearGradientBrush EndPoint="0.5,1"
StartPoint="0.5,0">
<GradientStop Color="{DynamicResource ControlLightColor}"
Offset="0" />
<GradientStop Color="{DynamicResource ControlMediumColor}"
Offset="1" />
</LinearGradientBrush>
</ToggleButton.Background>
</ToggleButton>
<ContentPresenter Grid.Column="1" Margin="4" ContentSource="Header" RecognizesAccessKey="True" />
</Grid>
</Border>
<Border x:Name="Content" Grid.Row="1" BorderThickness="1,0,1,1" CornerRadius="0,0,2,2">
<Border.BorderBrush>
<SolidColorBrush Color="{DynamicResource BorderMediumColor}" />
</Border.BorderBrush>
<Border.Background>
<SolidColorBrush Color="{DynamicResource ContentAreaColorDark}" />
</Border.Background>
<ContentPresenter Margin="4" />
</Border>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsExpanded" Value="True">
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetName="ContentRow" Storyboard.TargetProperty="Tag" From="0" To="1" Duration="0:0:1"/>
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetName="ContentRow" Storyboard.TargetProperty="Tag" From="1" To="0" Duration="0:0:1"/>
</Storyboard>
</BeginStoryboard>
</Trigger.ExitActions>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<StackPanel>
<Expander Header="Canny" >
<StackPanel>
<Button Content="A" />
<Button Content="B" />
<Button Content="C" />
</StackPanel>
</Expander>
<Expander Header="Sobel" >
<StackPanel>
<Button Content="A" />
<Button Content="B" />
<Button Content="C" />
</StackPanel>
</Expander>
<Expander Header="LoG" >
<StackPanel>
<Button Content="A" />
<Button Content="B" />
<Button Content="C" />
</StackPanel>
</Expander>
</StackPanel>
</Window>
Which requires this converter:
public class MultiplyConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
return new GridLength((double)values[0] * (double)values[1], GridUnitType.Pixel);
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
The main point is to set DoubleAnimation on ContentRow.Height in the template. However, you need to use a MultiBinding to bind the To property of this animation.

Resources