您的位置:首页 > 其它

wpf日历控件制作过程分析(1)---定义header

2008-06-18 15:06 453 查看
希望通过分析能更好的理解wpf控件的开发



一.日历的header布局

包含两部分,两个按钮和一个Title



首先定义按钮的样式(随自己定),可以先定义几个状态为普通状态,鼠标经过状态,按下状态和禁用4个状态显示不同的样式.其中按钮上还有一个小三角.所以还要定义一个三角的Geometry

代码开始

1.画出Geometry(涉及知识点为Geometry的画法及迷你语法,如M Z等)


<PathGeometry x:Key="geometry" Figures="M0,0 4.5,4 9,0 5.5,0 4.5,1 3.5,0z"/>

2.定义4个不同状态下的笔刷(可自由发挥)




Code


    <LinearGradientBrush x:Key="MonthCalendarButtonFillNormal" StartPoint="0,0" EndPoint="1,1">


        <LinearGradientBrush.GradientStops>


            <GradientStop Color="#FFE1EAFE" Offset="0"/>


            <GradientStop Color="#FFC3D3FD" Offset="0.3"/>


            <GradientStop Color="#FFC3D3FD" Offset="0.6"/>


            <GradientStop Color="#FFBBCDF9" Offset="1"/>


        </LinearGradientBrush.GradientStops>


    </LinearGradientBrush>


    <LinearGradientBrush x:Key="MonthCalendarButtonFillHover" StartPoint="0, 0" EndPoint="1, 1">


        <LinearGradientBrush.GradientStops>


            <GradientStop Color="#FFD6E7FF" Offset="0"/>


            <GradientStop Color="#FFD6E7FF" Offset="0.6"/>


            <GradientStop Color="#FFB9DAFB" Offset="1"/>


        </LinearGradientBrush.GradientStops>


    </LinearGradientBrush>


    <LinearGradientBrush x:Key="MonthCalendarButtonFillPressed" StartPoint="0, 0" EndPoint="1, 1">


        <LinearGradientBrush.GradientStops>


            <GradientStop Color="#FF93A8D9" Offset="0"/>


            <GradientStop Color="#FFA5BDFB" Offset="0.3"/>


            <GradientStop Color="#FFA5BDFB" Offset="0.7"/>


            <GradientStop Color="#FFD2DEEB" Offset="1.0"/>


        </LinearGradientBrush.GradientStops>


    </LinearGradientBrush>


    <LinearGradientBrush x:Key="MonthCalendarButtonFillDisabled" StartPoint="0, 0" EndPoint="1, 1">


        <LinearGradientBrush.GradientStops>


            <GradientStop Color="#FFF7F7F7" Offset="0"/>


            <GradientStop Color="#FFF0F0F0" Offset="0.3"/>


            <GradientStop Color="#FFECECEC" Offset="0.6"/>


            <GradientStop Color="#FFE3E3E3" Offset="1.0"/>


        </LinearGradientBrush.GradientStops>


    </LinearGradientBrush>

3.定义按钮样式,按钮上再使用上面的笔刷




Code


    <Style x:Key="{ComponentResourceKey TypeInTargetAssembly={x:Type DateControls:MonthCalendar},ResourceId=PreviousButtonStyleKey}" TargetType="{x:Type ButtonBase}">


        <Setter Property="Width" Value="16" />


        <Setter Property="Height" Value="16" />


        <Setter Property="Background" Value="{StaticResource MonthCalendarButtonFillNormal}" />


        <Setter Property="Foreground" Value="#FF4D6185"/>


        <Setter Property="Focusable" Value="false"/>


        <Setter Property="VerticalAlignment" Value="Top"/>


    </Style>




    <Style x:Key="{ComponentResourceKey TypeInTargetAssembly={x:Type DateControls:MonthCalendar},ResourceId=NextButtonStyleKey}" TargetType="{x:Type ButtonBase}">


        <Setter Property="Width" Value="16" />


        <Setter Property="Height" Value="16" />


        <Setter Property="Background" Value="{StaticResource MonthCalendarButtonFillNormal}" />


        <Setter Property="Foreground" Value="#FF4D6185"/>


        <Setter Property="Focusable" Value="false"/>


        <Setter Property="VerticalAlignment" Value="Top"/>


    </Style>

注意点

1.这里的TargetType是ButtonBase,因为有可能按钮是Button或RepeatButton都有可能,这里指向为ButtonBase是一种通用的做法

2.为何不直接定义还要为Button定义样式?,这里提供的样式为默认样式(下面我们会讲到)

3.ComponentResourceKey将资源定义在指定程序集中,在后端访问的方法如下


FindResource(new ComponentResourceKey(typeof(MonthCalendar), "PreviousButtonStyleKey")) as Style;

4.定义Title类,在静态构造函数中用OverrideMetadata方法重写样式(多数控件都需要这么做)


        static MonthCalendarTitle()




        

{


            DefaultStyleKeyProperty.OverrideMetadata(typeof(MonthCalendarTitle), new FrameworkPropertyMetadata(typeof(MonthCalendarTitle)));


        }

然后定义一个Title




Code


    <Style x:Key="{x:Type DateControls:MonthCalendarTitle}" TargetType="{x:Type DateControls:MonthCalendarTitle}">


        <Setter Property="Background" Value="Blue"/>


        <Setter Property="Foreground" Value="White"/>


        <Setter Property="FontWeight" Value="Bold"/>


        <Setter Property="Padding" Value="8"/>


        <Setter Property="Focusable" Value="false"/>


        <Setter Property="HorizontalContentAlignment" Value="Center"/>


        <Setter Property="VerticalContentAlignment" Value="Center"/>


        <Setter Property="Template">


            <Setter.Value>


                <ControlTemplate TargetType="{x:Type DateControls:MonthCalendarTitle}">


                    <Border Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}">


                    <TextBlock [b]Text="{Binding Converter={StaticResource MonthCalendarMonthYearHeaderConverter}}" 
[/b]

                FontFamily="{TemplateBinding FontFamily}" FontSize="{TemplateBinding FontSize}" FontStretch="{TemplateBinding FontStretch}" FontStyle="{TemplateBinding FontStyle}" FontWeight="{TemplateBinding FontWeight}" 


                HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" 


                Margin="{TemplateBinding Padding}" Foreground="{TemplateBinding Foreground}"/>


                    </Border>


                </ControlTemplate>


            </Setter.Value>


        </Setter>


        <Style.Triggers>


            <Trigger Property="IsEnabled" Value="false">


                <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>


            </Trigger>


        </Style.Triggers>


    </Style>

注意上面黑字,这里使用了数据绑定的类型转换器,只要给这个控件指定数据源就可以了,其作用是把日期转换上面第二张截图的格式

5.整合header




Code


                                <!--header beginer-->


                                <Grid x:Name="Title">


                                    


                                    <DateControls:MonthCalendarTitle x:Name="TitleHost" DataContext="{TemplateBinding VisibleMonth}" Style="{TemplateBinding TitleStyle}"/>


                                    <RepeatButton x:Name="PART_PreviousButton" Command="DateControls:MonthCalendar.PreviousCommand"


                                         Margin="7 5 0 0" HorizontalAlignment="Left" >


                                        <Viewbox>


                                            <Path Data="{StaticResource geometry}" Fill="Black">


                                                <Path.LayoutTransform>


                                                    <RotateTransform Angle="90"/>


                                                </Path.LayoutTransform>


                                            </Path>


                                        </Viewbox>


                                    </RepeatButton>


                                    <RepeatButton x:Name="PART_NextButton" Command="DateControls:MonthCalendar.NextCommand"


                                         Margin="0 5 7 0" HorizontalAlignment="Right">


                                        <Viewbox>


                                            <Path Data="{StaticResource geometry}" Fill="Black">


                                                <Path.LayoutTransform>


                                                    <RotateTransform Angle="-90"/>


                                                </Path.LayoutTransform>


                                            </Path>


                                        </Viewbox>


                                    </RepeatButton>


                                </Grid>


                                <!--heander end-->

注意点:

1.使用DataContext作为数据源

2.用RepeatButton当作按钮(可重复触发事件)

3.使用LayoutTransform翻转Geometry图形

4.自定义样式TitleStyle,默认为空
5.未见RepeatButton使用定义的ButtonBase样式?(可与第四点比较)

下次继续
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息