《學習筆記》Layui-WPF窗體美化

一睹為快:

 1.創建自定義控制項,並取名為LayuiWPFStyle

 

 

 2.在當前目錄中創建Fonts和WindowStyle文件加用來存放字體文件和自定義窗體,字體用fontawesome字體當然你們可以用自己的自己也行

 

 

 3.創建自定義控制項,並取名為LayWindow,記住是WPF的別點錯了

 

 

 

 

 

 4.雙擊LayWindow讓當前類文件繼承Window

 

 

 5.由於我們窗體分為頭部和內容,而頭部分為窗體名稱和窗體圖標以及窗體按鈕組成

 

 

 6.此時我們需要對窗體進行重繪以及添加必要的附加屬性,快捷鍵Propdp+雙擊Tab,MyProperty是擴展屬性名稱我們可以隨便定義,例如我們需要定義窗體頭部欄高度我們可以定義為HearderHieght,類型為Int,ownerclass替換為當前自定義窗體的名稱:LayWindow,

如圖二

 

 

 

 

 

 7.進入Generic.xaml文件中,我們會發現當我們每創建一個自定義控制項時系統會默認幫我創建一個簡單的Style樣式,但是此時的樣式時不奏效的,他只是給我們個友好的提示。此時我們需要開始從寫窗體樣式了,我們可以將窗體分為兩份,一份為頭部一分為身體(也就是內容)我們可以使用RowDefinitions進行分行,頭部高度設置為自適應類容高度如圖Height=”auto”

 

 

 8.創建一個頭部欄:並且此時可以開始用上我們的自定義屬性HearderHieght,切記我們自定義的屬性想要生效不能用TemplateBinding(模板綁定)進行綁定必須要用Binding(數據源綁定)進行綁定如:Height=”{Binding Path=HearderHieght, RelativeSource={RelativeSource Mode=TemplatedParent}}”

 

 

 9.窗體內容我們用ContentPresenter進行組合使用

 

 

 10.訂製窗體頭部,分別頭部分為三列,左邊分為窗體圖標和窗體名稱,中間預留,右邊分為最大化、最小化和關閉按鈕,為了方便我們統一顏色我將背景色單獨抽離開

 

 

 

 

 

 

   <Style TargetType="{x:Type local:LayWindow}" >
        <Setter Property="Background" Value="{StaticResource WindowBackground}"/>
        <Setter Property="HearderHieght" Value="35"/>
        <Setter Property="AllowsTransparency" Value="True"/>
        <Setter Property="WindowStyle" Value="None"/>
        <Setter Property="HearderFontColor" Value="White"/>
        <Setter Property="Margin" Value="7"/>
        <Setter Property="WindowChrome.WindowChrome" >
            <Setter.Value>
                <WindowChrome CaptionHeight="0" ResizeBorderThickness="10"/>
            </Setter.Value>
        </Setter>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type local:LayWindow}">
                    <Border Padding="{TemplateBinding Margin}">
                        <Grid>
                            <Grid  Background="#ccc" >
                                <Grid.Effect>
                                    <DropShadowEffect ShadowDepth="0" Direction="0"  BlurRadius="5" Color="#ccc">
                                    </DropShadowEffect>
                                </Grid.Effect>
                            </Grid>
                            <Grid  Background="White">
                                <Grid.RowDefinitions>
                                    <RowDefinition Height="auto"/>
                                    <RowDefinition/>
                                </Grid.RowDefinitions>
                                <Border x:Name="WindowHearder" Height="{Binding Path=HearderHieght, RelativeSource={RelativeSource Mode=TemplatedParent}}" Background="{TemplateBinding Background}"
                            BorderBrush="{TemplateBinding BorderBrush}"
                            BorderThickness="{TemplateBinding BorderThickness}"/><!--頂部顏色-->
                                <Grid x:Name="HearderContent">
                                    <Grid.ColumnDefinitions>
                                        <ColumnDefinition Width="auto"/>
                                        <ColumnDefinition/>
                                        <ColumnDefinition Width="auto"/>
                                    </Grid.ColumnDefinitions>
                                    <StackPanel Orientation="Horizontal">
                                        <Image Source="{TemplateBinding Icon}"  VerticalAlignment="Center"/><!--窗體圖標-->
                                        <TextBlock Text="{TemplateBinding Title}" VerticalAlignment="Center" Foreground="{Binding Path=HearderFontColor,RelativeSource={RelativeSource Mode=TemplatedParent}}"/><!--窗體名稱-->
                                    </StackPanel>
                                    <StackPanel Orientation="Horizontal" Grid.Column="2">
                                        <!--最小化按鈕-->
                                        <Button Visibility="{Binding Path=WinMinBtnVisibility,RelativeSource={RelativeSource Mode=TemplatedParent}}" Content="&#xf2d1;"  x:Name="WinMinBtn" Uid="1" 
                                                Style="{DynamicResource windowBtn}" Foreground="{TemplateBinding HearderFontColor}" Width="{Binding Path=HearderHieght, RelativeSource={RelativeSource Mode=TemplatedParent}}" 
                                                Height="{Binding Path=HearderHieght, RelativeSource={RelativeSource Mode=TemplatedParent}}" ToolTip="{TemplateBinding ToolTip}" />
                                        <!--最大化按鈕-->
                                        <Button Visibility="{Binding Path=WinMaxBtnVisibility,RelativeSource={RelativeSource Mode=TemplatedParent}}" Content="&#xf2d0;" x:Name="WinMaxBtn" Uid="2" 
                                                Style="{DynamicResource windowBtn}" Foreground="{TemplateBinding HearderFontColor}" Width="{Binding Path=HearderHieght, RelativeSource={RelativeSource Mode=TemplatedParent}}" 
                                                Height="{Binding Path=HearderHieght, RelativeSource={RelativeSource Mode=TemplatedParent}}" ToolTip="{TemplateBinding ToolTip}"/>
                                        <!--關閉按鈕-->
                                        <Button Content="&#xf00d;" RenderTransformOrigin="0.5,0.5" x:Name="WinCloseBtn" Uid="3" Style="{DynamicResource windowBtn}" Foreground="{TemplateBinding HearderFontColor}" 
                                                Width="{Binding Path=HearderHieght, RelativeSource={RelativeSource Mode=TemplatedParent}}" Height="{Binding Path=HearderHieght, RelativeSource={RelativeSource Mode=TemplatedParent}}" 
                                                ToolTip="{TemplateBinding ToolTip}"/>
                                    </StackPanel>
                                </Grid>
                                <ContentPresenter Grid.Row="1"/>
                            </Grid>
                        </Grid>
                    </Border>
                    <ControlTemplate.Triggers>
                        <Trigger Property="WinMinBtnVisibility" Value="False">
                            <Setter Property="Visibility" TargetName="WinMinBtn" Value="Collapsed"/>
                        </Trigger>
                        <Trigger Property="WinMaxBtnVisibility" Value="False">
                            <Setter Property="Visibility" TargetName="WinMaxBtn" Value="Collapsed"/>
                        </Trigger>
                        <DataTrigger Binding="{Binding RelativeSource={RelativeSource Mode=Self},Path=WindowHearderVisibility}" Value="False">
                            <Setter Property="Visibility" TargetName="HearderContent" Value="Collapsed"/>
                            <Setter Property="Visibility" TargetName="WindowHearder" Value="Collapsed"/>
                        </DataTrigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

View Code

 

11.此時我們的Style樣式寫完了開始實現功能,此時我們回到LayWindow.CS文件中,實現public override void OnApplyTemplate方法,此方法時方便我們查找我們模板中的某些控制項如窗體按鈕

public class LayWindow : Window
    {
        private Button WinMaxBtn;//全局最大化按鈕
        private bool WinMax = true;//全局最大窗體控制
        static LayWindow()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(LayWindow), new FrameworkPropertyMetadata(typeof(LayWindow)));
        }
        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();
            SizeChanged += new SizeChangedEventHandler(WindowSizeChanged);//實現窗體大小變化方法
            Border  WindowHearder = this.Template.FindName("WindowHearder",this) as Border;
            WindowHearder.MouseLeftButtonDown += new MouseButtonEventHandler(WindowDisplacement);//註冊窗體移動事件
            Button WinMinBtn = this.Template.FindName("WinMinBtn", this) as Button;//查找最小化按鈕
            WinMinBtn.ToolTip = "最小化";//設置按鈕提示名稱
            WinMinBtn.Click += new RoutedEventHandler(WinBtn_Click);//實現按鈕點擊方法
            WinMaxBtn = this.Template.FindName("WinMaxBtn", this) as Button;//查找最大化按鈕
            WinMaxBtn.ToolTip = "最大化";//設置按鈕提示名稱
            if (WinMaxBtn.Visibility != Visibility.Visible) WinMax = false;
            WinMaxBtn.Click += new RoutedEventHandler(WinBtn_Click);//實現按鈕點擊方法
            Button WinCloseBtn = this.Template.FindName("WinCloseBtn", this) as Button;//查找關閉按鈕
            WinCloseBtn.ToolTip = "關閉";//設置按鈕提示名稱
            WinCloseBtn.Click += new RoutedEventHandler(WinBtn_Click);//實現按鈕點擊方法
        }
        /// <summary>
        /// 窗體改變事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void WindowSizeChanged(object sender, SizeChangedEventArgs e)
        {
            Window window= sender as Window;
            if (window.WindowState == WindowState.Maximized)
            {
                WinMaxBtn.Content = "\xf2d2";
            }
            else if(window.WindowState == WindowState.Normal)
            {
                WinMaxBtn.Content = "\xf2d0";
            }
        }
        /// <summary>
        /// 窗體按鈕事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void WinBtn_Click(object sender, RoutedEventArgs e)
        {   
            WindowStyleChange(Convert.ToInt32((sender as Button).Uid), (sender as Button).TemplatedParent as Window);
        }
        /// <summary>
        /// 窗體狀態變化
        /// </summary>
        /// <param name="styleCode"></param>
        /// <param name="window"></param>
        private void WindowStyleChange(int styleCode ,Window window) {
            switch (styleCode)
            {
                case 1:
                    window.WindowState = WindowState.Minimized;
                    break;
                case 2:
                    if (window.WindowState == WindowState.Maximized)
                    {
                        WinMaxBtn.Content = "\xf2d0";
                        WinMaxBtn.ToolTip = "最大化";
                        window.WindowState = WindowState.Normal;
                    }
                    else
                    {
                        WinMaxBtn.Content = "\xf2d2";
                        WinMaxBtn.ToolTip = "還原";
                        window.WindowState = WindowState.Maximized;
                    } 
                    break;
                case 3:
                    window.Close();
                    break;
            }
        }
        /// <summary>
        /// 窗體移動事件
        /// </summary>
        /// <param name="sender">窗體頭部</param>
        /// <param name="e"></param>
        private void WindowDisplacement(object sender, MouseButtonEventArgs e)
        {
            if ((sender as Border).TemplatedParent is Window) {

                Window window = (sender as Border).TemplatedParent as Window;
                switch (e.ClickCount)
                {
                    case 1://左鍵單擊效果
                        window.DragMove();
                        break;
                    case 2://左鍵雙擊效果
                        if(WinMax)
                        if (window.WindowState == WindowState.Maximized)
                        {
                            WinMaxBtn.Content = "\xf2d0";
                            window.WindowState = WindowState.Normal;
                        }
                        else
                        {
                            WinMaxBtn.Content = "\xf2d2";
                            window.WindowState = WindowState.Maximized;
                        }
                        break;
                }
            }
            
        }
        /// <summary>
        /// 窗體頭部高度
        /// </summary>
        public int HearderHieght
        {
            get { return (int)GetValue(HearderHieghtProperty); }
            set { SetValue(HearderHieghtProperty, value); }
        }

        // Using a DependencyProperty as the backing store for HearderHieght.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty HearderHieghtProperty =
            DependencyProperty.Register("HearderHieght", typeof(int), typeof(LayWindow));

        /// <summary>
        /// 窗體頭部字體樣式
        /// </summary>
        public Brush HearderFontColor
        {
            get { return (Brush)GetValue(HearderFontColorProperty); }
            set { SetValue(HearderFontColorProperty, value); }
        }

        // Using a DependencyProperty as the backing store for HearderFontColor.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty HearderFontColorProperty =
            DependencyProperty.Register("HearderFontColor", typeof(Brush), typeof(LayWindow));


        /// <summary>
        /// 窗體頭部欄狀態
        /// </summary>
        public bool WindowHearderVisibility
        {
            get { return (bool)GetValue(WindowHearderVisibilityProperty); }
            set { SetValue(WindowHearderVisibilityProperty, value); }
        }

        // Using a DependencyProperty as the backing store for WindowHearderVisibility.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty WindowHearderVisibilityProperty =
            DependencyProperty.Register("WindowHearderVisibility", typeof(bool), typeof(LayWindow), new PropertyMetadata(true));


        #region 窗體頭部欄控制
        public bool WinMinBtnVisibility
        {
            get { return (bool)GetValue(WinMinBtnVisibilityProperty); }
            set { SetValue(WinMinBtnVisibilityProperty, value); }
        }

        // Using a DependencyProperty as the backing store for WinMinBtnVisibility.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty WinMinBtnVisibilityProperty =
            DependencyProperty.Register("WinMinBtnVisibility", typeof(bool), typeof(LayWindow), new PropertyMetadata(true));

        public bool WinMaxBtnVisibility
        {
            get { return (bool)GetValue(WinMaxBtnVisibilityProperty); }
            set { SetValue(WinMaxBtnVisibilityProperty, value); }
        }

        // Using a DependencyProperty as the backing store for WinMinBtnVisibility.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty WinMaxBtnVisibilityProperty =
            DependencyProperty.Register("WinMaxBtnVisibility", typeof(bool), typeof(LayWindow), new PropertyMetadata(true));
        #endregion

    }

View Code

<FontFamily x:Key="FontFamilyStyle">/LayuiWPFStyle;component/Fonts/#FontAwesome</FontFamily>
<Style TargetType="TextBlock" >
        <Setter Property="FontFamily" Value="{StaticResource FontFamilyStyle}"/>
        <Setter Property="FontSize" Value="16"/>
    </Style>
    <Style x:Key="btnBase" TargetType="Button" >
        <Setter Property="Cursor" Value="Hand"/>
    </Style>
    <Style x:Key="windowBtn" TargetType="Button" BasedOn="{StaticResource btnBase}">
        <Setter Property="Background" Value="Transparent"/>
        <Setter Property="BorderThickness" Value="0"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="Button">
                    <Grid>
                        <Border x:Name="WindowHearder" Height="{Binding Path=HearderHieght, RelativeSource={RelativeSource Mode=TemplatedParent}}" Background="{TemplateBinding Background}"
                            BorderBrush="{TemplateBinding BorderBrush}"
                            BorderThickness="{TemplateBinding BorderThickness}"/>
                        <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

View Code

 

12,此時我們的自定義窗體的所有業務程式碼已完成,創建一個WPF項目,我們取名為Layui-WPFUI,並且引用我們剛剛做好的窗體

 

 

 13.窗機WPF項目中的App.xaml文件添加自定義控制項的相關樣式文件

 <Application.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="/LayuiWPFStyle;component/Themes/Generic.xaml"/>
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Application.Resources>

View Code

 

 

 

 14.點擊MainWindow將原來的左上角的Window替換為Lay:LayWindow,並且引用xmlns:Lay=”clr-namespace:LayuiWPFStyle;assembly=LayuiWPFStyle”如圖

 

 16.按F7進入後台程式碼讓MainWindow繼承我們的LayWindow

 

 

 

 

 17.此時我們的自定義窗體就完成啦,點擊運行就得到我們的美化後的窗體(頂部左側的Ico圖標可忽略自己也可以添加一個Ico圖標)

 

 

 注意如若你的項目運行出錯很有可能你的Generic.xaml文件裡面有文字注釋,上圖中我是為了方便學習特意添加註釋,當控制項寫完後可將注釋去掉即可

 

Tags: