WPF自定义控件与样式(5)-Calendar/DatePicker日期控件自定义样式及扩展
一.前言
申明:WPF自定義控件與樣式是一個系列文章,前后是有些關聯的,但大多是按照由簡到繁的順序逐步發布的等,若有不明白的地方可以參考本系列前面的文章,文末附有部分文章鏈接。
本文主要內容:
- 日歷控件Calendar自定義樣式;
- 日期控件DatePicker自定義樣式,及Label標簽、水印、清除日期功能擴展;
二.Calendar自定義樣式
先看看效果:
從上面圖可以看出,日歷的顯示其實有三種狀態,如下面的分解圖:
- "日"部分的顯示;
- "月"部分的顯示;
- "年"部分的顯示;
因此一個完整的日歷,就包含多個部分,首先是"日"按鈕的樣式:??
<!--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><!--不在當月的日期--><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> View Code日歷日期面板樣式:??
<!--日歷日期面板樣式--><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> View Code年月按鈕樣式:??
<!--年、月按鈕樣式--><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><!--不在當月的日期--><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> View Code最后綜合以上的樣式,定義我們需要的Calendar樣式就差一步之遙了。??
<!--默認日歷樣式--><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標簽、水印、清除日期功能擴展
有了上面的日歷樣式,下面做DatePicker的樣式就好辦了,其實就是TextBox+Button+Calendar。此處的實現同上一篇(WPF自定義控件與樣式(3)-TextBox & RichTextBox & PasswordBox樣式)思路基本一致,因此本文就不做更多的解釋,可以參考本系列前面的文章(末尾附錄有鏈接)先看看效果圖:
3.1 DatePicker自定義樣式
基本樣式定義:??
<Style x:Key="DefaultDatePicker" TargetType="{x:Type DatePicker}"><Setter Property="Foreground" Value="{StaticResource TextForeground}" /><Setter Property="Background" Value="{StaticResource TextBackground}" /><Setter Property="BorderThickness" Value="1" /><Setter Property="BorderBrush" Value="{StaticResource ControlBorderBrush}" /><Setter Property="local:ControlAttachProperty.FocusBorderBrush" Value="{StaticResource FocusBorderBrush}" /><Setter Property="local:ControlAttachProperty.MouseOverBorderBrush" Value="{StaticResource MouseOverBorderBrush}" /><Setter Property="local:ControlAttachProperty.FIconSize" Value="21" /><Setter Property="FontFamily" Value="{StaticResource FontFamily}" /><Setter Property="FontSize" Value="{StaticResource FontSize}" /><Setter Property="MinHeight" Value="26" /><Setter Property="Height" Value="30" /><Setter Property="Width" Value="200" /><Setter Property="HorizontalContentAlignment" Value="Stretch" /><Setter Property="IsTodayHighlighted" Value="True" /><Setter Property="Padding" Value="0" /><Setter Property="Margin" Value="0" /><Setter Property="SelectedDate" Value="{x:Null}" /><Setter Property="SnapsToDevicePixels" Value="True" /><Setter Property="CalendarStyle" Value="{StaticResource DefaultCalendar}" /><Setter Property="Template"><Setter.Value><ControlTemplate TargetType="{x:Type DatePicker}"><Grid x:Name="PART_Root"><Border x:Name="Bg" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}"Background="{TemplateBinding Background}" /><Grid x:Name="PART_InnerGrid" Margin="0"><Grid.ColumnDefinitions><ColumnDefinition Width="Auto" /><ColumnDefinition Width="*" /><ColumnDefinition Width="Auto" /><ColumnDefinition Width="Auto" /></Grid.ColumnDefinitions><!--Label區域--><ContentControl x:Name="Label" Template="{TemplateBinding local:ControlAttachProperty.LabelTemplate}" IsTabStop="False" IsHitTestVisible="False"Content="{TemplateBinding local:ControlAttachProperty.Label}" Margin="1,1,0,1"/><!--附加內容區域--><Border x:Name="PART_AttachContent" Grid.Column="2" VerticalAlignment="Center" HorizontalAlignment="Center" ><ContentControl VerticalAlignment="Center" VerticalContentAlignment="Center" Template="{TemplateBinding local:ControlAttachProperty.AttachContent}"/></Border><!--下拉按鈕--><ToggleButton x:Name="PART_DropDownToggle" IsTabStop="False" Style="{StaticResource FIconToggleButton}" IsChecked="{Binding IsDropDownOpen, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}" Margin="1,1,3,1"Grid.Column="3" local:ControlAttachProperty.FIconSize="{TemplateBinding local:ControlAttachProperty.FIconSize}"Background="{TemplateBinding local:ControlAttachProperty.FocusBackground}"/><!--水印--><Border Grid.Column="1"><TextBlock x:Name="Message" Padding="0" Visibility="Collapsed" Text="{TemplateBinding local:ControlAttachProperty.Watermark}" Foreground="{TemplateBinding Foreground}" IsHitTestVisible="False" Opacity="{StaticResource WatermarkOpacity}" HorizontalAlignment="Left" TextAlignment="Center" VerticalAlignment="Center" Margin="5,2,5,2" /></Border><!--Date內容區--><Grid Grid.Column="1"><TextBox x:Name="PART_TextBox" Style="{StaticResource EditableTextBoxStyle}" HorizontalAlignment="Stretch" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" IsHitTestVisible="True" IsReadOnly="True"FontFamily="{TemplateBinding FontFamily}" Foreground="{TemplateBinding Foreground}" FontSize="{TemplateBinding FontSize}" Text="{Binding Path=SelectedDate,Mode=OneWay,RelativeSource={RelativeSource TemplatedParent},StringFormat={StaticResource DateFormat}}"/></Grid><!--彈出日歷--><Popup x:Name="PART_Popup" AllowsTransparency="True" Placement="Bottom"PlacementTarget="{Binding ElementName=PART_Root}" StaysOpen="False" /></Grid></Grid><ControlTemplate.Triggers><!--1.顯示水印--><DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Path=Text}" Value=""><Setter TargetName="Message" Property="Visibility" Value="Visible" /></DataTrigger><Trigger Property="IsMouseOver" Value="True"><Setter Property="BorderBrush" Value="{Binding Path=(local:ControlAttachProperty.MouseOverBorderBrush),RelativeSource={RelativeSource Self}}"/></Trigger><Trigger Property="IsFocused" Value="True"><Setter Property="BorderBrush" Value="{Binding Path=(local:ControlAttachProperty.FocusBorderBrush),RelativeSource={RelativeSource Self}}"/></Trigger><Trigger Property="IsKeyboardFocusWithin" Value="True"><Setter Property="BorderBrush" Value="{Binding Path=(local:ControlAttachProperty.FocusBorderBrush),RelativeSource={RelativeSource Self}}"/></Trigger><Trigger Property="IsEnabled" Value="False"><Setter TargetName="PART_Root" Property="Opacity" Value="{StaticResource DisableOpacity}" /></Trigger></ControlTemplate.Triggers></ControlTemplate></Setter.Value></Setter></Style> View Code水印效果:
使用示例:
<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標簽
通過擴展基礎樣式中的標簽附加屬性實現,定義樣式代碼:??
<!--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)-矢量字體圖標(iconfont)
WPF自定義控件與樣式(2)-自定義按鈕FButton
WPF自定義控件與樣式(3)-TextBox & RichTextBox & PasswordBox樣式、水印、Label標簽、功能擴展
WPF自定義控件與樣式(4)-CheckBox/RadioButton自定義樣式
?
版權所有,文章來源:http://www.cnblogs.com/anding
個人能力有限,本文內容僅供學習、探討,歡迎指正、交流。
?
總結
以上是生活随笔為你收集整理的WPF自定义控件与样式(5)-Calendar/DatePicker日期控件自定义样式及扩展的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Ajax实践之用户是否存在
- 下一篇: svg学习网站