首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> 關於.NET

WPF 日歷控件開發實戰(一):Header 區域佈局與樣式體系

     編輯:關於.NET

目標:深度理解 WPF 控件開發全流程

日歷控件整體效果

一、Header 佈局結構

包含兩部分:左右導航按鈕 + 中央標題區

Header 結構拆解

1. 幾何圖形定義(PathGeometry 迷你語法)

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

2. 四狀態漸層筆刷

<LinearGradientBrush x:Key="MonthCalendarButtonFillNormal" StartPoint="0,0" EndPoint="1,1">
    <GradientStop Color="#FFE1EAFE" Offset="0"/>
    <GradientStop Color="#FFC3D3FD" Offset="0.3"/>
    <GradientStop Color="#FFC3D3FD" Offset="0.6"/>
    <GradientStop Color="#FFBBCDF9" Offset="1"/>
</LinearGradientBrush>

<LinearGradientBrush x:Key="MonthCalendarButtonFillHover" StartPoint="0,0" EndPoint="1,1">
    <GradientStop Color="#FFD6E7FF" Offset="0"/>
    <GradientStop Color="#FFD6E7FF" Offset="0.6"/>
    <GradientStop Color="#FFB9DAFB" Offset="1"/>
</LinearGradientBrush>

<LinearGradientBrush x:Key="MonthCalendarButtonFillPressed" StartPoint="0,0" EndPoint="1,1">
    <GradientStop Color="#FF93A8D9" Offset="0"/>
    <GradientStop Color="#FFA5BDFB" Offset="0.3"/>
    <GradientStop Color="#FFA5BDFB" Offset="0.7"/>
    <GradientStop Color="#FFD2DEEB" Offset="1.0"/>
</LinearGradientBrush>

<LinearGradientBrush x:Key="MonthCalendarButtonFillDisabled" StartPoint="0,0" EndPoint="1,1">
    <GradientStop Color="#FFF7F7F7" Offset="0"/>
    <GradientStop Color="#FFF0F0F0" Offset="0.3"/>
    <GradientStop Color="#FFECECEC" Offset="0.6"/>
    <GradientStop Color="#FFE3E3E3" Offset="1.0"/>
</LinearGradientBrush>

3. 按鈕樣式(TargetType=ButtonBase 通用性)

<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>

關鍵點

  • TargetType=ButtonBase:支援 Button/RepeatButton 通用
  • 此為預設樣式,非強制樣式(後文會講)
  • ComponentResourceKey 將資源定義在指定組件,後端調用:FindResource(new ComponentResourceKey(typeof(MonthCalendar), "PreviousButtonStyleKey")) as Style

4. Title 控件與樣式重寫

static MonthCalendarTitle()
{
    DefaultStyleKeyProperty.OverrideMetadata(typeof(MonthCalendarTitle), new FrameworkPropertyMetadata(typeof(MonthCalendarTitle)));
}

標題樣式含 ControlTemplate、DataBinding、Converter、Trigger:

<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 Text="{Binding Converter={StaticResource MonthCalendarMonthYearHeaderConverter}}"
                        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>

注意:Text="{Binding Converter=...}" 僅指定資料源即可,轉換器負責將日期格式化為「年 月」形式。

5. Header 整合 XAML

<!-- 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 旋轉幾何圖形(非 RenderTransform)
  4. 自定義樣式 TitleStyle,預設為空
  5. 為何 RepeatButton 未使用定義的 ButtonBase 樣式?(可與第 4 點對比思考)
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved