通过Silverlight中Calendar控件的扩展学习XAML(上)

通过Silverlight中Calendar控件的扩展学习XAML(上),第1张

概述本文通过自定义calendar的开发,通过分析Silverlight自带的Calendar的样式、模板的分析,实现日历的定制化开发。 WPF中,自带的Calendar控件是这样子的: 而我们想要的结果是这样子的: 这个控件有两种方法去做。 一个是自己重新绘制图形,用一个7*6的表格来放日期,再根据当前月第一天的星期,计算出第一行第一列的日期,然后依次填充即可。详情可参考 Kelly Elias的这

本文通过自定义calendar的开发,通过分析Silverlight自带的Calendar的样式、模板的分析,实现日历的定制化开发。


WPF中,自带的Calendar控件是这样子的:


而我们想要的结果是这样子的:



这个控件有两种方法去做。

一个是自己重新绘制图形,用一个7*6的表格来放日期,再根据当前月第一天的星期,计算出第一行第一列的日期,然后依次填充即可。详情可参考 Kelly Elias的这篇文章An Editable WPF Calendar Control,但这个控件其中用到了很重要的一个类UniformGrID在Silverlight中是没有的,需要自己重写,不要急,Jeff Wilco在博文UniformGrid for Silverlight中提供了解决方案。

另一个则是基于自带的Calendar,利用XAML强大的样式(Style)和模板(Template)功能完成扩展,也就是今天要讲的。


第一种方式实现简单容易扩展,可快速满足各种需求。但是功能太少,一些基本的日历功能都需要重写,比如月份更换、日期选择和反选等等。相反,第二种因为是基于自带的Calendar,不用引用过多的外部资源,即可拥有许多强大的功能,还能和其他控件融为一体等等。所以不用说,肯定用第二种的好。


关于Calendar的样式和模板,MSDN给了完整的示例。本文也是基于官方示例和非官方英文文献撰写。


首先,创建一个控件,添加一个UserControl:

    <GrID x:name="LayoutRoot"          Background="White">        <VIEwBox>            <sdk:Calendar name='calendar1' />        </VIEwBox>    </GrID>
其中,VIEwBox是用来实现Calendar自适应大小的。


一个Calendar可设置的样式包括Style、CalendarItemStyle、CalendarbuttonStyle和CalendarDaybuttonStyle

Style是用来设置Calendar整体的样式:

 <Style x:Key="CalendarStyle1"               targettype="sdk:Calendar">            <Setter Property="IsTabStop"                    Value="False" />            <Setter Property="Background">                <Setter.Value>                    <linearGradIEntBrush EndPoint="0.5,1"                                         StartPoint="0.5,0">                        <GradIEntStop color="#FFD3DEE8"                                      Offset="0" />                        <GradIEntStop color="#FFD3DEE8"                                      Offset="0.16" />                        <GradIEntStop color="#FFFCFCFD"                                      Offset="0.16" />                        <GradIEntStop color="#FFFFFFFF"                                      Offset="1" />                    </linearGradIEntBrush>                </Setter.Value>            </Setter>--------------------------------------------------------------------------------------------------------------------------            <Setter Property="Template">                <Setter.Value>                    <ControlTemplate targettype="sdk:Calendar">                        <GrID x:name="Root"                              HorizontalAlignment="Stretch"                              VerticalAlignment="Stretch">                            <System_windows_Controls_Primitives:CalendarItem VerticalAlignment="Stretch"                                                                             VerticalContentAlignment="Stretch"                                                                             HorizontalAlignment="Stretch"                                                                             HorizontalContentAlignment="Stretch"                                                                             x:name="CalendarItem"                                                                             borderBrush="{TemplateBinding borderBrush}"                                                                             borderThickness="{TemplateBinding borderThickness}"                                                                             Background="{TemplateBinding Background}"                                                                             Style="{StaticResource CalendarItemStyle1}" />                        </GrID>                    </ControlTemplate>                </Setter.Value> --------------------------------------------------------------------------------------------------------------------------            </Setter> </Style>

CalendarItemStyle是用来设置CalendarItem(即月份选择部分和日期排列),CalendarItem的设置也可以嵌套到Style中设置(Style代码中横线夹住部分)

        <Style x:Key="CalendarItemStyle1"               targettype="System_windows_Controls_Primitives:CalendarItem">            <Setter Property='VerticalAlignment'Value='Stretch' />            <Setter Property='VerticalContentAlignment' Value='Stretch' />            <Setter Property='HorizontalAlignment'  Value='Stretch' />            <Setter Property='HorizontalContentAlignment' Value='Stretch' />            <Setter Property="Template">                <Setter.Value>                    <ControlTemplate targettype="System_windows_Controls_Primitives:CalendarItem">                        <GrID HorizontalAlignment="Stretch"  VerticalAlignment="Stretch">                            <GrID.Resources>                                <SolIDcolorBrush x:Key="DisabledBrush"  color="#8CFFFFFF" />                            </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="DisabledVisual" />                                        </Storyboard>                                    </VisualState>                                </VisualStateGroup>                            </visualstatemanager.VisualStateGroups>                            <border HorizontalAlignment="Stretch" VerticalAlignment="Stretch"  borderBrush="{TemplateBinding borderBrush}" borderThickness="{TemplateBinding borderThickness}"  Background="{TemplateBinding Background}" CornerRadius="5"  margin="2">                                <border HorizontalAlignment="Stretch" VerticalAlignment="Stretch" borderBrush="#FFFFFFFF" borderThickness="2" CornerRadius="5" padding="5">                                    <GrID HorizontalAlignment="Stretch" VerticalAlignment="Stretch">                                        <GrID.Resources>                                            <ControlTemplate x:Key="headerbuttonTemplate" targettype="button">                                                <GrID Cursor="Hand">                                                    <visualstatemanager.VisualStateGroups>                                                        <VisualStateGroup x:name="CommonStates">                                                            <VisualState x:name="normal" />                                                            <VisualState x:name="MouSEOver">                                                                <Storyboard>                                                                    <colorAnimation Duration="0" To="#FF73A9D8" Storyboard.TargetProperty="(ContentControl.Foreground).(SolIDcolorBrush.color)" Storyboard.Targetname="Content" />                                                                </Storyboard>                                                            </VisualState>                                                            <VisualState x:name="Disabled">                                                                <Storyboard>                                                                    <DoubleAnimation Duration="0" To=".5" Storyboard.TargetProperty="Opacity" Storyboard.Targetname="Content" />                                                                </Storyboard>                                                            </VisualState>                                                        </VisualStateGroup>                                                    </visualstatemanager.VisualStateGroups>                                                    <ContentControl x:name="Content" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" Foreground="#FF333333" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" IsTabStop="False" margin="1,5,1,9" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" />                                                </GrID>                                            </ControlTemplate>                                            <DataTemplate x:name="DayTitleTemplate">                                                <TextBlock FontWeight="Bold" margin="5" FontSize="12" HorizontalAlignment="left" Text="{Binding}" VerticalAlignment="Center"></TextBlock>                                            </DataTemplate>                                            <ControlTemplate x:Key="PrevIoUsbuttonTemplate" targettype="button">                                                <GrID Cursor="Hand">                                                    <visualstatemanager.VisualStateGroups>                                                        <VisualStateGroup x:name="CommonStates">                                                            <VisualState x:name="normal" />                                                            <VisualState x:name="MouSEOver">                                                                <Storyboard>                                                                    <colorAnimation Duration="0" To="#FF73A9D8" Storyboard.TargetProperty="(Path.Fill).(SolIDcolorBrush.color)" Storyboard.Targetname="IconPath" />                                                                </Storyboard>                                                            </VisualState>                                                            <VisualState x:name="Disabled">                                                                <Storyboard>                                                                    <DoubleAnimation Duration="0"  To=".5" Storyboard.TargetProperty="(Path.Fill).(SolIDcolorBrush.Opacity)" Storyboard.Targetname="IconPath" />                                                                </Storyboard>                                                            </VisualState>                                                        </VisualStateGroup>                                                    </visualstatemanager.VisualStateGroups>                                                    <Rectangle Fill="#11E5EBF1" Opacity="1" Stretch="Fill" />                                                    <GrID>                                                        <Path x:name="IconPath" Data="M288.75,232.25 L288.75,240.625 L283,236.625 z" Fill="#FF333333" HorizontalAlignment="left" Height="10" margin="14,-6,0" Stretch="Fill" VerticalAlignment="Center" WIDth="6" />                                                    </GrID>                                                </GrID>                                            </ControlTemplate>                                            <ControlTemplate x:Key="NextbuttonTemplate" targettype="button">                                                <GrID Cursor="Hand">                                                    <visualstatemanager.VisualStateGroups>                                                        <VisualStateGroup x:name="CommonStates">                                                            <VisualState x:name="normal" />                                                            <VisualState x:name="MouSEOver">                                                                <Storyboard>                                                                    <colorAnimation Duration="0" To="#FF73A9D8" Storyboard.TargetProperty="(Path.Fill).(SolIDcolorBrush.color)" Storyboard.Targetname="IconPath" />                                                                </Storyboard>                                                            </VisualState>                                                            <VisualState x:name="Disabled">                                                                <Storyboard>                                                                    <DoubleAnimation Duration="0"To=".5" Storyboard.TargetProperty="(Path.Fill).(SolIDcolorBrush.Opacity)" Storyboard.Targetname="IconPath" />                                                                </Storyboard>                                                            </VisualState>                                                        </VisualStateGroup>                                                    </visualstatemanager.VisualStateGroups>                                                    <Rectangle Fill="#11E5EBF1" Opacity="1" Stretch="Fill" />                                                    <GrID>                                                        <Path x:name="IconPath" Data="M282.875,231.875 L282.875,240.375 L288.625,236 z" Fill="#FF333333" HorizontalAlignment="Right" Height="10" margin="0,14,0"  Stretch="Fill" VerticalAlignment="Center" WIDth="6" />                                                    </GrID>                                                </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>                                        <button x:name="PrevIoUsbutton" HorizontalAlignment="left" Height="20" Template="{StaticResource PrevIoUsbuttonTemplate}" Visibility="Collapsed" WIDth="28" />                                        <button x:name="headerbutton" GrID.Column="1" FontWeight="Bold" FontSize="10.5" HorizontalAlignment="Stretch" HorizontalContentAlignment="Center" Template="{StaticResource buttonControlTemplate1}" VerticalAlignment="Center" />                                        <button x:name="Nextbutton" GrID.Column="2" HorizontalAlignment="Right" Height="20" Template="{StaticResource NextbuttonTemplate}" Visibility="Collapsed" WIDth="28" />                                        <GrID x:name="MonthVIEw" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" GrID.ColumnSpan="3" GrID.Row="1" Visibility="Collapsed">                                            <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="YearVIEw" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" GrID.ColumnSpan="3" GrID.Row="1" Visibility="Collapsed">                                            <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="DisabledVisual" Fill="{StaticResource DisabledBrush}" margin="0,2,2" Opacity="0" RadiusY="2" RadiusX="2" Stretch="Fill" stroke="{StaticResource DisabledBrush}" strokeThickness="1" Visibility="Collapsed" />                        </GrID>                    </ControlTemplate>                </Setter.Value>            </Setter>        </Style>

我们分析一下这个长长的XAML,Blend是分析样式和模板的一个非常好用的工具,在Blend中编辑该模板:


右边列出那长串XAML所包含的树形结构,折叠后的XAML即:



PrevIoUsbuttonTemplate定义了“上一个月”按钮的样式,Nextbutton指定是“下一个月”按钮,而headerbutton就是“月份”以及“日历名称”的部分。至于后面的MonthVIEw和YearVIEw,则分别定义了正常和点击当前月份后日历的显示。

在这里说一下,CalendarItem是在Calendar逻辑树下的,所以Calendar的DataContext是可以被CalendarItem获取到的,所以,在设置Calendar的各个button时候,是可以绑定viewmodel(MVVM模式中VM概念)中的属性的。例如:

    <ControlTemplate x:Key="buttonControlTemplate"                         targettype="button">            <GrID Cursor="Hand">                <GrID.RowDeFinitions>                    <RowDeFinition></RowDeFinition>                    <RowDeFinition></RowDeFinition>                </GrID.RowDeFinitions>                <ContentControl x:name="Content"                                ContentTemplate="{TemplateBinding ContentTemplate}"                                Content="{TemplateBinding Content}"                                Foreground="#FF333333"                                HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"                                IsTabStop="False"                                margin="1,9"                                VerticalAlignment="{TemplateBinding VerticalContentAlignment}" />                <TextBlock Foreground="#ff666666"                           FontSize="9"                           margin="-20"                           GrID.Row="1"                           VerticalAlignment="Center"                           HorizontalAlignment="Center"                           Text='{Binding CalendarModel.Resourcename}' />            </GrID>        </ControlTemplate>
其中,Text='{Binding CalendarModel.Calendarname}'是可以找到UserControl.DataContext绑定的Calendarviewmodel实例的。所以,通过这个button模板,可以轻易动态修改日历名称。


下节中,本文将继续讨论CalendarDaybuttonStyle的设置以及Daybutton内容的绑定和设置

总结

以上是内存溢出为你收集整理的通过Silverlight中Calendar控件的扩展学习XAML(上)全部内容,希望文章能够帮你解决通过Silverlight中Calendar控件的扩展学习XAML(上)所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1018250.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-23
下一篇 2022-05-23

发表评论

登录后才能评论

评论列表(0条)

保存