Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Change foreground color of calendar items

Tags:

wpf

calendar

I'm customizing a calendar control in WPF and I'm able to adjust the background color, header foreground colors etc.. But I can't find how to edit the appearance of the 1-31 day calendar items. At the

Screenshot:

enter image description here

As you can see, the numbers are all dark grey and almost not readable. I would also like to get the rid of the blue-ish overlay on mouseover.

Code:

<Window x:Class="WPFDatePickerSample.Window2"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window2" Height="500" Width="500"
    Background="#2F2F2F">

<Window.Resources>
    <Style TargetType="{x:Type CalendarItem}">
        <Setter Property="Margin" Value="50"/>

        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type CalendarItem}">
                    <ControlTemplate.Resources>
                        <DataTemplate x:Key="{x:Static CalendarItem.DayTitleTemplateResourceKey}">
                            <TextBlock Foreground="#FFA9C822" FontWeight="Normal" FontSize="12" HorizontalAlignment="Center" Margin="0,5,0,5" Text="{Binding}" VerticalAlignment="Center"/>
                        </DataTemplate>
                    </ControlTemplate.Resources>

                    <Grid x:Name="PART_Root">
                        <Grid.Resources>
                            <SolidColorBrush x:Key="DisabledColor" Color="#A5FFFFFF"/>
                        </Grid.Resources>

                        <VisualStateManager.VisualStateGroups>
                            <VisualStateGroup x:Name="CommonStates">
                                <VisualState x:Name="Normal"/>
                                <VisualState x:Name="Disabled">
                                    <Storyboard>
                                        <DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="PART_DisabledVisual"/>
                                    </Storyboard>
                                </VisualState>
                            </VisualStateGroup>
                        </VisualStateManager.VisualStateGroups>

                        <Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" CornerRadius="1">
                            <Border BorderBrush="#FFFFFFFF" BorderThickness="0" CornerRadius="0">
                                <Grid>
                                    <Grid.Resources>
                                        <ControlTemplate x:Key="PreviousButtonTemplate" TargetType="{x:Type Button}">
                                            <Grid Cursor="Hand">
                                                <VisualStateManager.VisualStateGroups>
                                                    <VisualStateGroup x:Name="CommonStates">
                                                        <VisualState x:Name="Normal"/>
                                                        <VisualState x:Name="MouseOver">
                                                            <Storyboard>
                                                                <ColorAnimation Duration="0" To="#FFA9C822" Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)" Storyboard.TargetName="path"/>
                                                            </Storyboard>
                                                        </VisualState>
                                                        <VisualState x:Name="Disabled">
                                                            <Storyboard>
                                                                <DoubleAnimation Duration="0" To=".5" Storyboard.TargetProperty="(Shape.Fill).(Brush.Opacity)" Storyboard.TargetName="path"/>
                                                            </Storyboard>
                                                        </VisualState>
                                                    </VisualStateGroup>
                                                </VisualStateManager.VisualStateGroups>

                                                <Rectangle Fill="Transparent" Opacity="1" Stretch="Fill"/>

                                                <Grid>
                                                    <Path x:Name="path" Data="M288.75,232.25 L288.75,240.625 L283,236.625 z" Fill="Silver" HorizontalAlignment="Left" Height="10" Margin="5,-6,0,0" Stretch="Fill" VerticalAlignment="Center" Width="6"/>
                                                </Grid>
                                            </Grid>
                                        </ControlTemplate>

                                        <ControlTemplate x:Key="NextButtonTemplate" TargetType="{x:Type Button}">
                                            <Grid Cursor="Hand">
                                                <VisualStateManager.VisualStateGroups>
                                                    <VisualStateGroup x:Name="CommonStates">
                                                        <VisualState x:Name="Normal"/>
                                                        <VisualState x:Name="MouseOver">
                                                            <Storyboard>
                                                                <ColorAnimation Duration="0" To="#FFA9C822" Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)" Storyboard.TargetName="path"/>
                                                            </Storyboard>
                                                        </VisualState>

                                                        <VisualState x:Name="Disabled">
                                                            <Storyboard>
                                                                <DoubleAnimation Duration="0" To=".5" Storyboard.TargetProperty="(Shape.Fill).(Brush.Opacity)" Storyboard.TargetName="path"/>
                                                            </Storyboard>
                                                        </VisualState>
                                                    </VisualStateGroup>
                                                </VisualStateManager.VisualStateGroups>

                                                <Rectangle Fill="Transparent" Opacity="1" Stretch="Fill"/>

                                                <Grid>
                                                    <Path x:Name="path" Data="M282.875,231.875 L282.875,240.375 L288.625,236 z" Fill="Silver" HorizontalAlignment="Right" Height="10" Margin="0,-6,5,0" Stretch="Fill" VerticalAlignment="Center" Width="6"/>
                                                </Grid>
                                            </Grid>
                                        </ControlTemplate>

                                        <ControlTemplate x:Key="HeaderButtonTemplate" TargetType="{x:Type Button}">
                                            <Grid Cursor="Hand">
                                                <VisualStateManager.VisualStateGroups>
                                                    <VisualStateGroup x:Name="CommonStates">
                                                        <VisualState x:Name="Normal"/>
                                                        <VisualState x:Name="MouseOver">
                                                            <Storyboard>
                                                                <DoubleAnimation Duration="0" To=".7" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="buttonContent"/>
                                                            </Storyboard>
                                                        </VisualState>

                                                        <VisualState x:Name="Disabled">
                                                            <Storyboard>
                                                                <DoubleAnimation Duration="0" To=".5" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="buttonContent"/>
                                                            </Storyboard>
                                                        </VisualState>
                                                    </VisualStateGroup>
                                                </VisualStateManager.VisualStateGroups>

                                                <ContentPresenter x:Name="buttonContent" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" TextElement.Foreground="Silver" TextElement.FontFamily="Segoe UI" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="1,3,1,9" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
                                            </Grid>
                                        </ControlTemplate>
                                    </Grid.Resources>

                                    <Grid.ColumnDefinitions>
                                        <ColumnDefinition Width="Auto"/>
                                        <ColumnDefinition Width="Auto"/>
                                        <ColumnDefinition Width="Auto"/>
                                    </Grid.ColumnDefinitions>

                                    <Grid.RowDefinitions>
                                        <RowDefinition Height="Auto"/>
                                        <RowDefinition Height="*"/>
                                    </Grid.RowDefinitions>

                                    <Grid Grid.Row="0" Grid.ColumnSpan="4" Background="#3C3C3C" HorizontalAlignment="Stretch">
                                        <Button x:Name="PART_PreviousButton" Grid.Column="0" Focusable="False" HorizontalAlignment="Left" Height="20" Grid.Row="0" Template="{StaticResource PreviousButtonTemplate}" Width="28"/>
                                        <Button x:Name="PART_HeaderButton" Grid.Column="1" FontWeight="Normal" Focusable="False" FontSize="13" HorizontalAlignment="Center" Grid.Row="0" Template="{StaticResource HeaderButtonTemplate}" VerticalAlignment="Center" />
                                        <Button x:Name="PART_NextButton" Grid.Column="2" Focusable="False" HorizontalAlignment="Right" Height="20" Grid.Row="0" Template="{StaticResource NextButtonTemplate}" Width="28"/>
                                    </Grid>
                                    <Grid x:Name="PART_MonthView" Grid.ColumnSpan="3" HorizontalAlignment="Center" Margin="6,-1,6,6" Grid.Row="1" Visibility="Visible">
                                        <Grid.ColumnDefinitions>
                                            <ColumnDefinition Width="Auto"/>
                                            <ColumnDefinition Width="Auto"/>
                                            <ColumnDefinition Width="Auto"/>
                                            <ColumnDefinition Width="Auto"/>
                                            <ColumnDefinition Width="Auto"/>
                                            <ColumnDefinition Width="Auto"/>
                                            <ColumnDefinition Width="Auto"/>
                                        </Grid.ColumnDefinitions>

                                        <Grid.RowDefinitions>
                                            <RowDefinition Height="Auto"/>
                                            <RowDefinition Height="Auto"/>
                                            <RowDefinition Height="Auto"/>
                                            <RowDefinition Height="Auto"/>
                                            <RowDefinition Height="Auto"/>
                                            <RowDefinition Height="Auto"/>
                                            <RowDefinition Height="Auto"/>
                                        </Grid.RowDefinitions>
                                    </Grid>

                                    <Grid x:Name="PART_YearView" Grid.ColumnSpan="3" HorizontalAlignment="Center" Margin="6,-3,7,6" Grid.Row="1" Visibility="Hidden">
                                        <Grid.ColumnDefinitions>
                                            <ColumnDefinition Width="Auto"/>
                                            <ColumnDefinition Width="Auto"/>
                                            <ColumnDefinition Width="Auto"/>
                                            <ColumnDefinition Width="Auto"/>
                                        </Grid.ColumnDefinitions>

                                        <Grid.RowDefinitions>
                                            <RowDefinition Height="Auto"/>
                                            <RowDefinition Height="Auto"/>
                                            <RowDefinition Height="Auto"/>
                                        </Grid.RowDefinitions>
                                    </Grid>
                                </Grid>
                            </Border>
                        </Border>

                        <Rectangle x:Name="PART_DisabledVisual" Fill="{StaticResource DisabledColor}" Opacity="0" RadiusY="2" RadiusX="2" Stretch="Fill" Stroke="{StaticResource DisabledColor}" StrokeThickness="1" Visibility="Collapsed"/>
                    </Grid>

                    <ControlTemplate.Triggers>
                        <Trigger Property="IsEnabled" Value="False">
                            <Setter Property="Visibility" TargetName="PART_DisabledVisual" Value="Visible" />
                        </Trigger>

                        <DataTrigger Binding="{Binding DisplayMode, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Calendar}}}" Value="Year">
                            <Setter Property="Visibility" TargetName="PART_MonthView" Value="Hidden" />
                            <Setter Property="Visibility" TargetName="PART_YearView" Value="Visible" />
                        </DataTrigger>

                        <DataTrigger Binding="{Binding DisplayMode, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Calendar}}}" Value="Decade">
                            <Setter Property="Visibility" TargetName="PART_MonthView" Value="Hidden" />
                            <Setter Property="Visibility" TargetName="PART_YearView" Value="Visible" />
                        </DataTrigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

    <Style TargetType="{x:Type Calendar}">
        <Setter Property="Background" Value="#3C3C3C"/>

        <Setter Property="SnapsToDevicePixels" Value="True" />
        <Setter Property="BorderBrush" Value="Transparent" />
        <Setter Property="BorderThickness" Value="1" />

        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type Calendar}">
                    <StackPanel x:Name="PART_Root" HorizontalAlignment="Center">
                        <CalendarItem x:Name="PART_CalendarItem" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" />
                    </StackPanel>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</Window.Resources>

<Grid>
    <Calendar Width="400" Height="400"></Calendar>
</Grid>

like image 524
Robby Smet Avatar asked Nov 07 '13 12:11

Robby Smet


People also ask

Can you color code events in Outlook calendar?

From your Calendar folder, select View > View Settings. Select Conditional Formatting. In the Conditional Formatting dialog box, select Add to create a new rule. Give your rule a name and use the Color drop-down to pick a color.


1 Answers

although this a question with a few years, I only needed to style a calendar now. Mine is for a touchscreen app where the normal calendar is impossible to use. So I was checking out your question and Sheridan's answer and after going through MSDN CalendarDayButtonStyle I finished my job, so here is the result for anyone interested, this is my touch calendar based on yours.

enter image description here

And this is the style:

<Style x:Key="CalendarDayButtonStyle" TargetType="{x:Type CalendarDayButton}">
    <!--<Setter Property="Background" Value="#FFBADDE9" />-->

    <Setter Property="FontSize" Value="20" />
    <Setter Property="HorizontalContentAlignment" Value="Center" />
    <Setter Property="VerticalContentAlignment" Value="Center" />
    <Setter Property="MinWidth" Value="35" />
    <Setter Property="MinHeight" Value="35" />
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="CalendarDayButton">
                <Grid>
                    <VisualStateManager.VisualStateGroups>
                        <VisualStateGroup x:Name="CommonStates">
                            <VisualStateGroup.Transitions>
                                <VisualTransition GeneratedDuration="0:0:0.1" />
                            </VisualStateGroup.Transitions>
                            <VisualState x:Name="Normal" />
                            <VisualState x:Name="MouseOver">
                                <Storyboard>
                                    <DoubleAnimation Storyboard.TargetName="Background" Storyboard.TargetProperty="Opacity" To=".5" Duration="0" />
                                </Storyboard>
                            </VisualState>
                            <VisualState x:Name="Pressed">
                                <Storyboard>
                                    <DoubleAnimation Storyboard.TargetName="Background" Storyboard.TargetProperty="Opacity" To=".5" Duration="0" />
                                </Storyboard>
                            </VisualState>
                            <VisualState x:Name="Disabled">
                                <Storyboard>
                                    <DoubleAnimation Storyboard.TargetName="Background" Storyboard.TargetProperty="Opacity" To="0" Duration="0" />
                                    <DoubleAnimation Storyboard.TargetName="Content" Storyboard.TargetProperty="Opacity" To=".35" Duration="0" />
                                </Storyboard>
                            </VisualState>
                        </VisualStateGroup>
                        <VisualStateGroup x:Name="SelectionStates">
                            <VisualStateGroup.Transitions>
                                <VisualTransition GeneratedDuration="0" />
                            </VisualStateGroup.Transitions>
                            <VisualState x:Name="Unselected" />
                            <VisualState x:Name="Selected">
                                <Storyboard>
                                    <DoubleAnimation Storyboard.TargetName="SelectedBackground" Storyboard.TargetProperty="Opacity" To=".75" Duration="0" />
                                </Storyboard>
                            </VisualState>
                        </VisualStateGroup>
                        <VisualStateGroup x:Name="CalendarButtonFocusStates">
                            <VisualStateGroup.Transitions>
                                <VisualTransition GeneratedDuration="0" />
                            </VisualStateGroup.Transitions>
                            <VisualState x:Name="CalendarButtonFocused">
                                <Storyboard>
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="FocusVisual" Storyboard.TargetProperty="Visibility" Duration="0">
                                        <DiscreteObjectKeyFrame KeyTime="0" Value="{x:Static Visibility.Visible}" />
                                    </ObjectAnimationUsingKeyFrames>
                                </Storyboard>
                            </VisualState>
                            <VisualState x:Name="CalendarButtonUnfocused">
                                <Storyboard>
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="FocusVisual" Storyboard.TargetProperty="Visibility" Duration="0">
                                        <DiscreteObjectKeyFrame KeyTime="0" Value="{x:Static Visibility.Collapsed}" />
                                    </ObjectAnimationUsingKeyFrames>
                                </Storyboard>
                            </VisualState>
                        </VisualStateGroup>
                        <VisualStateGroup x:Name="ActiveStates">
                            <VisualStateGroup.Transitions>
                                <VisualTransition GeneratedDuration="0" />
                            </VisualStateGroup.Transitions>
                            <VisualState x:Name="Active" />
                            <VisualState x:Name="Inactive">
                                <Storyboard>
                                    <ColorAnimation Storyboard.TargetName="Content" Storyboard.TargetProperty="(ContentControl.Foreground).(GradientBrush.GradientStops)[2].(GradientStop.Color)" To="{DynamicResource DisableDay1}" Duration="0" />
                                    <ColorAnimation Storyboard.TargetName="Content" Storyboard.TargetProperty="(ContentControl.Foreground).(GradientBrush.GradientStops)[3].(GradientStop.Color)" To="{DynamicResource DisableDay2}" Duration="0" />
                                </Storyboard>
                            </VisualState>
                        </VisualStateGroup>
                        <VisualStateGroup x:Name="DayStates">
                            <VisualStateGroup.Transitions>
                                <VisualTransition GeneratedDuration="0" />
                            </VisualStateGroup.Transitions>
                            <VisualState x:Name="RegularDay"  />
                            <VisualState x:Name="Today">
                                <Storyboard>
                                    <DoubleAnimation Storyboard.TargetName="TodayBackground" Storyboard.TargetProperty="Opacity" To="1" Duration="0" />
                                    <DoubleAnimation Storyboard.TargetName="Content" Storyboard.TargetProperty="(ContentControl.Foreground).(GradientBrush.GradientStops)[1].(GradientStop.Offset)" To="1" Duration="0" />
                                    <DoubleAnimation Storyboard.TargetName="Content" Storyboard.TargetProperty="(ContentControl.Foreground).(GradientBrush.GradientStops)[2].(GradientStop.Offset)" To="1" Duration="0" />
                                </Storyboard>
                            </VisualState>
                        </VisualStateGroup>
                        <VisualStateGroup x:Name="BlackoutDayStates">
                            <VisualStateGroup.Transitions>
                                <VisualTransition GeneratedDuration="0" />
                            </VisualStateGroup.Transitions>
                            <VisualState x:Name="NormalDay" />
                            <VisualState x:Name="BlackoutDay">
                                <Storyboard>
                                    <DoubleAnimation Storyboard.TargetName="BlackoutVisual" Storyboard.TargetProperty="Opacity" To=".2" Duration="0" />
                                </Storyboard>
                            </VisualState>
                        </VisualStateGroup>
                    </VisualStateManager.VisualStateGroups>

                    <Rectangle x:Name="TodayBackground" RadiusX="1" RadiusY="1" Opacity="0" Fill="#FFAAAAAA" />
                    <Rectangle x:Name="SelectedBackground" RadiusX="1" RadiusY="1" Opacity="0" Fill="{TemplateBinding Background}" />
                    <Rectangle x:Name="Background" RadiusX="1" RadiusY="1" Opacity="0" Fill="{TemplateBinding Background}" />

                    <ContentControl x:Name="Content" IsTabStop="False" Content="{TemplateBinding Content}" ContentTemplate="{TemplateBinding ContentTemplate}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" FontSize="{TemplateBinding FontSize}" Margin="5,1,5,1">
                        <ContentControl.Foreground>
                            <LinearGradientBrush>
                                <GradientStop Offset="0" Color="{DynamicResource SelectedDay1}" />
                                <GradientStop Offset="0" Color="{DynamicResource SelectedDay2}" />
                                <GradientStop Offset="0" Color="{DynamicResource NormalDay1}" />
                                <GradientStop Offset="1" Color="{DynamicResource NormalDay2}" />
                            </LinearGradientBrush>
                        </ContentControl.Foreground>
                    </ContentControl>

                    <Path x:Name="BlackoutVisual" Opacity="0" Margin="3" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" RenderTransformOrigin="0.5,0.5" Fill="#FF000000" Stretch="Fill" Data="M8.1772461,11.029181 L10.433105,11.029181 L11.700684,12.801641 L12.973633,11.029181 L15.191895,11.029181 L12.844727,13.999395 L15.21875,17.060919 L12.962891,17.060919 L11.673828,15.256231 L10.352539,17.060919 L8.1396484,17.060919 L10.519043,14.042364 z" />
                    <Rectangle x:Name="FocusVisual" Visibility="Collapsed" IsHitTestVisible="false" RadiusX="1" RadiusY="1" Stroke="#FF6DBDD1" />
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

So you just need do set the colors to the resources:

<Color x:Key="DisableDay1">Black</Color>
<Color x:Key="DisableDay2">Black</Color>

<Color x:Key="NormalDay1">LightGray</Color>
<Color x:Key="NormalDay2">Gray</Color>

<Color x:Key="SelectedDay1">White</Color>
<Color x:Key="SelectedDay2">White</Color>

...and add the style template to your calendar:

<Style x:Key="TouchCalendarStyle" TargetType="{x:Type Calendar}">    
    <Setter Property="CalendarDayButtonStyle" Value="{DynamicResource CalendarDayButtonStyle}"/>
    ...
</Style>

So thank's for your help. :)

like image 199
Nemesis Avatar answered Nov 06 '22 03:11

Nemesis