WPF自定義控件與樣式(5)-Calendar/DatePicker日期控件自定義樣式及擴展一.前言 申明:WPF自定義控件與樣式是一個系列文章,前后是有些關(guān)聯(lián)的,但大多是按照由簡到繁的順序逐步發(fā)布的等,若有不明白的地方可以參考本系列前面的文章,文末附有部分文章鏈接。 本文主要內(nèi)容:
二.Calendar自定義樣式 先看看效果: 從上面圖可以看出,日歷的顯示其實有三種狀態(tài),如下面的分解圖:
因此一個完整的日歷,就包含多個部分,首先是"日"按鈕的樣式: ![]() <!--Day按鈕樣式--> <Style x:Key="CalendarDayButtonStyle" TargetType="{x:Type CalendarDayButton}"> <Setter Property="MinWidth" Value="28" /> <Setter Property="MinHeight" Value="5" /> <Setter Property="FontFamily" Value="{StaticResource FontFamily}" /> <Setter Property="HorizontalContentAlignment" Value="Center" /> <Setter Property="VerticalContentAlignment" Value="Center" /> <Setter Property="Background" Value="Transparent" /> <Setter Property="Foreground" Value="{StaticResource TextForeground}" /> <Setter Property="Margin" Value="0" /> <Setter Property="IsTabStop" Value="False" /> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type CalendarDayButton}"> <Grid x:Name="Grid" Margin="{TemplateBinding Margin}"> <Border x:Name="Bg" Background="{TemplateBinding Background}" /> <ContentPresenter x:Name="NormalText" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="5,2,5,2" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" TextElement.Foreground="{TemplateBinding Foreground}" /> </Grid> <ControlTemplate.Triggers> <Trigger Property="IsSelected" Value="True"> <Setter Property="Background" Value="{StaticResource ItemSelectedBackground}"></Setter> <Setter Property="Foreground" Value="{StaticResource ItemSelectedForeground}"></Setter> </Trigger> <Trigger Property="IsToday" Value="True"> <Setter Property="Background" Value="{StaticResource ItemHighlighteBackground}"></Setter> <Setter Property="Foreground" Value="{StaticResource ItemHighlighteForeground}"></Setter> </Trigger> <Trigger Property="IsMouseOver" Value="True"> <Setter Property="Background" Value="{StaticResource ItemMouseOverBackground}"></Setter> <Setter Property="Foreground" Value="{StaticResource ItemMouseOverForeground}"></Setter> </Trigger> <!--不可用日期--> <Trigger Property="IsBlackedOut" Value="True"> <Setter Property="Opacity" Value="{StaticResource DisableOpacity}" TargetName="Grid"></Setter> </Trigger> <!--不在當(dāng)月的日期--> <Trigger Property="IsInactive" Value="True"> <Setter Property="Opacity" Value="0.65" TargetName="Grid"></Setter> </Trigger> <Trigger Property="IsEnabled" Value="False"> <Setter Property="Opacity" Value="{StaticResource DisableOpacity}" TargetName="Grid"></Setter> </Trigger> </ControlTemplate.Triggers> </ControlTemplate> </Setter.Value> </Setter> </Style> 日歷日期面板樣式: ![]() <!--日歷日期面板樣式--> <Style x:Key="CalendarItemStyle" TargetType="{x:Type CalendarItem}"> <Setter Property="Margin" Value="0,1,0,1" /> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type CalendarItem}"> <ControlTemplate.Resources> <!-- 頭部星期樣式--> <DataTemplate x:Key="{x:Static CalendarItem.DayTitleTemplateResourceKey}"> <TextBlock Text="{Binding}" FontWeight="Bold" FontFamily="{StaticResource FontFamily}" Foreground="{StaticResource PressedForeground}" FontSize="{StaticResource HeaderFontSize}" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="0,6,0,6" Opacity="0.8" /> </DataTemplate> </ControlTemplate.Resources> <Grid x:Name="PART_Root"> <Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="1" Background="{TemplateBinding Background}" Margin="{TemplateBinding Margin}"> <Grid Margin="2"> <Grid.ColumnDefinitions> <ColumnDefinition Width="Auto" /> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition Height="Auto" /> <RowDefinition Height="*" /> </Grid.RowDefinitions> <!--Header--> <Grid Grid.Row="0" HorizontalAlignment="Stretch" Background="{StaticResource HeaderBackground}"> <Grid.ColumnDefinitions> <ColumnDefinition Width="*"/> <ColumnDefinition Width="2*"/> <ColumnDefinition Width="*"/> </Grid.ColumnDefinitions> <local:FButton x:Name="PART_HeaderButton" FontWeight="Bold" Style="{StaticResource FButton_Transparency}" Focusable="False" Grid.Column="1" FIcon="{x:Null}"/> <local:FButton x:Name="PART_PreviousButton" Style="{StaticResource FButton_Transparency}" Focusable="False" Grid.Column="0" FIconSize="18" Content="" FIcon=""/> <local:FButton x:Name="PART_NextButton" Style="{StaticResource FButton_Transparency}" Focusable="False" Grid.Column="2" FIconSize="18" Content="" FIcon=""/> </Grid> <!--PART_MonthView--> <Grid x:Name="PART_MonthView" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="6,1,6,6" Grid.Row="1" Visibility="Visible"> <Grid.ColumnDefinitions> <ColumnDefinition Width="*" /> <ColumnDefinition Width="*" /> <ColumnDefinition Width="*" /> <ColumnDefinition Width="*" /> <ColumnDefinition Width="*" /> <ColumnDefinition Width="*" /> <ColumnDefinition Width="*" /> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition Height="*" /> <RowDefinition Height="*" /> <RowDefinition Height="*" /> <RowDefinition Height="*" /> <RowDefinition Height="*" /> <RowDefinition Height="*" /> <RowDefinition Height="*" /> </Grid.RowDefinitions> </Grid> <!--PART_YearView--> <Grid x:Name="PART_YearView" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="6,10,6,10" Grid.Row="1" Visibility="Hidden"> <Grid.ColumnDefinitions> <ColumnDefinition Width="*" /> <ColumnDefinition Width="*" /> <ColumnDefinition Width="*" /> <ColumnDefinition Width="*" /> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition Height="*" /> <RowDefinition Height="*" /> <RowDefinition Height="*" /> </Grid.RowDefinitions> </Grid> </Grid> </Border> </Grid> <ControlTemplate.Triggers> <Trigger Property="IsEnabled" Value="False"> <Setter Property="Opacity" TargetName="PART_Root" Value="{StaticResource DisableOpacity}" /> </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> <!--Decade 美 ['d?ked] n. 十年,十年期;十--> <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 x:Key="CalendarButtonStyle" TargetType="{x:Type CalendarButton}"> <Setter Property="Background" Value="Transparent" /> <Setter Property="MinWidth" Value="40" /> <Setter Property="MinHeight" Value="42" /> <Setter Property="FontSize" Value="{StaticResource FontSize}" /> <Setter Property="FontFamily" Value="{StaticResource FontFamily}" /> <Setter Property="HorizontalContentAlignment" Value="Center" /> <Setter Property="VerticalContentAlignment" Value="Center" /> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type CalendarButton}"> <Grid x:Name="Grid" Margin="{TemplateBinding Margin}"> <Border x:Name="Bg" Background="{TemplateBinding Background}" /> <ContentPresenter x:Name="NormalText" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="5,2,5,2" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" TextElement.Foreground="{TemplateBinding Foreground}" /> </Grid> <ControlTemplate.Triggers> <Trigger Property="IsFocused" Value="True"> <Setter Property="Background" Value="{StaticResource ItemSelectedBackground}"></Setter> <Setter Property="Foreground" Value="{StaticResource ItemSelectedForeground}"></Setter> </Trigger> <Trigger Property="IsMouseOver" Value="True"> <Setter Property="Background" Value="{StaticResource ItemMouseOverBackground}"></Setter> <Setter Property="Foreground" Value="{StaticResource ItemMouseOverForeground}"></Setter> </Trigger> <!--不在當(dāng)月的日期--> <Trigger Property="IsInactive" Value="True"> <Setter Property="Opacity" Value="0.8" TargetName="Grid"></Setter> </Trigger> <Trigger Property="IsEnabled" Value="False"> <Setter Property="Opacity" Value="{StaticResource DisableOpacity}" TargetName="Grid"></Setter> </Trigger> </ControlTemplate.Triggers> </ControlTemplate> </Setter.Value> </Setter> </Style> 最后綜合以上的樣式,定義我們需要的Calendar樣式就差一步之遙了。 <!--默認(rèn)日歷樣式--> <Style x:Key="DefaultCalendar" TargetType="{x:Type Calendar}"> <Setter Property="SnapsToDevicePixels" Value="True" /> <Setter Property="Foreground" Value="{StaticResource TextForeground}" /> <Setter Property="CalendarDayButtonStyle" Value="{StaticResource CalendarDayButtonStyle}" /> <Setter Property="CalendarItemStyle" Value="{StaticResource CalendarItemStyle}" /> <Setter Property="CalendarButtonStyle" Value="{StaticResource CalendarButtonStyle}" /> <Setter Property="Background" Value="{StaticResource PopupBackground}" /> <Setter Property="BorderBrush" Value="{StaticResource ControlBorderBrush}" /> <Setter Property="BorderThickness" Value="1" /> <Setter Property="FontSize" Value="13" /> <Setter Property="FontFamily" Value="{StaticResource FontFamily}" /> <Setter Property="IsTodayHighlighted" Value="True" /> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type Calendar}"> <StackPanel x:Name="PART_Root" HorizontalAlignment="Center" Background="Transparent"> <CalendarItem x:Name="PART_CalendarItem" BorderBrush="{TemplateBinding BorderBrush}" FontSize="{TemplateBinding FontSize}" FontFamily="{TemplateBinding FontFamily}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Style="{TemplateBinding CalendarItemStyle}" /> </StackPanel> </ControlTemplate> </Setter.Value> </Setter> </Style>
三.DatePicker自定義樣式,及Label標(biāo)簽、水印、清除日期功能擴展 有了上面的日歷樣式,下面做DatePicker的樣式就好辦了,其實就是TextBox+Button+Calendar。此處的實現(xiàn)同上一篇(WPF自定義控件與樣式(3)-TextBox & RichTextBox & PasswordBox樣式)思路基本一致,因此本文就不做更多的解釋,可以參考本系列前面的文章(末尾附錄有鏈接)先看看效果圖: 3.1 DatePicker自定義樣式 基本樣式定義: ![]() 水印效果: 使用示例: <DatePicker Margin="3" core:ControlAttachProperty.Watermark="媽的快輸入日期"/> <DatePicker Margin="3" SelectedDate="{x:Static system:DateTime.Today}"/> <DatePicker Margin="3" IsEnabled="False" SelectedDate="{x:Static system:DateTime.Today}"/> 3.2 Label標(biāo)簽 通過擴展基礎(chǔ)樣式中的標(biāo)簽附加屬性實現(xiàn),定義樣式代碼: <!--DatePicker包含附加屬性Label的樣式 LabelDatePicker --> <Style TargetType="{x:Type DatePicker}" x:Key="LabelDatePicker" BasedOn="{StaticResource DefaultDatePicker}"> <Setter Property="Width" Value="260"></Setter> <Setter Property="local:ControlAttachProperty.LabelTemplate" > <Setter.Value> <ControlTemplate TargetType="ContentControl"> <Border Width="60" Background="{StaticResource TextLabelBackground}"> <TextBlock VerticalAlignment="Center" HorizontalAlignment="Right" Margin="2" Text="{TemplateBinding Content}"></TextBlock> </Border> </ControlTemplate> </Setter.Value> </Setter> </Style> 效果圖: 使用示例: <DatePicker Margin="3" Style="{StaticResource LabelClearButtonDatePicker}" core:ControlAttachProperty.Watermark="選擇出生日期" core:ControlAttachProperty.Label="出生日期"/> <DatePicker Margin="3" Style="{StaticResource LabelDatePicker}" core:ControlAttachProperty.Label="死亡日期" SelectedDate="{x:Static system:DateTime.Today}"/> <DatePicker Margin="3" Style="{StaticResource LabelDatePicker}" core:ControlAttachProperty.Label="非法日期" IsEnabled="False" SelectedDate="{x:Static system:DateTime.Today}"/> 3.3 清除日期值的功能擴展 此功能在前面的文章有介紹過(參考本文末尾鏈接),效果在上面的圖片中可以看到。樣式代碼: <!--DatePicker包含清除Text按鈕的樣式 ClearButtonDatePicker --> <Style TargetType="{x:Type DatePicker}" x:Key="ClearButtonDatePicker" BasedOn="{StaticResource DefaultDatePicker}"> <Setter Property="local:ControlAttachProperty.AttachContent"> <Setter.Value> <ControlTemplate> <local:FButton FIcon="" Style="{StaticResource FButton_Transparency}" IsTabStop="False" FIconMargin="0" local:ControlAttachProperty.IsClearTextButtonBehaviorEnabled="True" Command="local:ControlAttachProperty.ClearTextCommand" CommandParameter="{Binding RelativeSource={RelativeSource FindAncestor,AncestorType={x:Type DatePicker}}}" Margin="1,3,0,4" FIconSize="14" Foreground="{StaticResource TextForeground}" Cursor="Arrow"/> </ControlTemplate> </Setter.Value> </Setter> </Style> <!--DatePicker包含附加屬性Label,以及ClearText按鈕的樣式 LabelClearButtonDatePicker --> <Style TargetType="{x:Type DatePicker}" x:Key="LabelClearButtonDatePicker" BasedOn="{StaticResource DefaultDatePicker}"> <Setter Property="Width" Value="280"></Setter> <Setter Property="local:ControlAttachProperty.LabelTemplate" > <Setter.Value> <ControlTemplate TargetType="ContentControl"> <Border Width="60" Background="{StaticResource TextLabelBackground}"> <TextBlock VerticalAlignment="Center" HorizontalAlignment="Right" Margin="2" Text="{TemplateBinding Content}"></TextBlock> </Border> </ControlTemplate> </Setter.Value> </Setter> <Setter Property="local:ControlAttachProperty.AttachContent"> <Setter.Value> <ControlTemplate> <local:FButton FIcon="" Style="{StaticResource FButton_Transparency}" IsTabStop="False" FIconMargin="0" local:ControlAttachProperty.IsClearTextButtonBehaviorEnabled="True" Command="local:ControlAttachProperty.ClearTextCommand" CommandParameter="{Binding RelativeSource={RelativeSource FindAncestor,AncestorType={x:Type DatePicker}}}" Margin="0,3,0,4" FIconSize="14" Foreground="{StaticResource TextForeground}" Cursor="Arrow"/> </ControlTemplate> </Setter.Value> </Setter> </Style> 使用示例: <DatePicker Margin="3" Style="{StaticResource ClearButtonDatePicker}"/> <DatePicker Margin="3" Style="{StaticResource LabelClearButtonDatePicker}" core:ControlAttachProperty.Watermark="選擇出生日期" core:ControlAttachProperty.Label="出生日期"/>
附錄:參考引用 WPF自定義控件與樣式(1)-矢量字體圖標(biāo)(iconfont) WPF自定義控件與樣式(3)-TextBox & RichTextBox & PasswordBox樣式、水印、Label標(biāo)簽、功能擴展 WPF自定義控件與樣式(4)-CheckBox/RadioButton自定義樣式
版權(quán)所有,文章來源:http://www.cnblogs.com/anding 個人能力有限,本文內(nèi)容僅供學(xué)習(xí)、探討,歡迎指正、交流。 |
|