Prism+MaterialDesign+EntityFramework Core+Postgresql WPF開發總結 之 中級篇


本着每天記錄一點成長一點的原則,打算將目前完成的一個WPF項目相關的技術分享出來,供團隊學習與總結。

總共分三個部分:

基礎篇主要針對C#初學者,鞏固C#常用知識點;

中級篇主要針對WPF布局與MaterialDesign美化設計,在減輕代碼量的情況做出漂亮的應用;

終極篇為框架應用實戰,包含MVVM框架Prism,ORM框架EntityFramework Core,開源數據庫Postgresql。

目錄

  1. Prism+MaterialDesign+EntityFramework Core+Postgresql WPF開發總結 之 基礎篇
  2. Prism+MaterialDesign+EntityFramework Core+Postgresql WPF開發總結 之 中級篇
  3. Prism+MaterialDesign+EntityFramework Core+Postgresql WPF開發總結 之 終極篇(待續)

前言

WPF的發布同時伴隨着MVVM框架的發布,此篇將圍繞MVVM框架做表示與數據分離設計,包含基礎UI設計以及MaterialDesign的高端設計。MVVM框架細節請參照終極篇。其中的一個效果圖如下,其他效果圖請往下看。

基礎UI設計

用Windows Presentation Foundation (WPF),可以創建具有非凡視覺效果的桌面Windows 應用程序。目前.NET Core 3.0 支持使用 Windows Presentation Foundation (WPF) Windows 桌面應用程序,以后有可能擴展到其他OS平台。

WPF設計中使用的XAML標記語言,類似XML標記語言。XAML以及WPF自帶的基礎控件此處不做介紹可以參照微軟文檔。

一、常見布局

布局關鍵點就是不管什么像素下都能適應窗體大小。WPF內部提供了一套強大的布局系統,設計人員只需要使用相對定位布局就可以。

通用布局:網格,堆疊,停靠。掌握這三種差不多可以應對所有開發。

1、網格布局

也就是常用的Grid布局。通過行列把界面划分為網格,子控件指定相應的行列號布局到指定格子。

行與列的高寬可以使用【*】按比例划分,也可以使用【Auto】根據內容自動調整。默認情況下,行和列占用的空間量最少,以容納給定行或列中包含的任何單元內的最大內容。

    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>
        <Grid Grid.Row="0">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto" />
                <ColumnDefinition Width="Auto" />
                <ColumnDefinition Width="Auto" />
            </Grid.ColumnDefinitions>
            <TextBox Grid.Column="0" Text="column1 auto" />
            <TextBox Grid.Column="1" Text="column2 auto" />
            <TextBox Grid.Column="2" Text="column3 auto" />
        </Grid>
        <Grid Grid.Row="1">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto" />
                <ColumnDefinition Width="*" />
                <ColumnDefinition Width="Auto" />
            </Grid.ColumnDefinitions>
            <TextBox Grid.Column="0" Text="column1 auto" />
            <TextBox Grid.Column="1" Text="column2 *" />
            <TextBox Grid.Column="2" Text="column3 auto" />
        </Grid>
        <Grid Grid.Row="2">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="*" />
                <ColumnDefinition Width="2*" />
            </Grid.ColumnDefinitions>
            <TextBox Grid.Column="0" Text="column1 *" />
            <TextBox Grid.Column="1" Text="column2 2*" />
        </Grid>
        <Grid Grid.Row="3">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="*" />
                <ColumnDefinition Width="2*" />
            </Grid.ColumnDefinitions>
            <TextBox
                Grid.Column="0"
                Height="100"
                Text="column1 * height=100" />
            <TextBox Grid.Column="1" Text="column2 2*" />
        </Grid>
    </Grid>
View Code

效果如圖:大小隨窗體自動調整。

2、堆疊

控件按指定方向排列,顯示不下的時候根據所使用的控件不同會有區別。

  1. StackPanel:子控件按垂直或水平堆疊,超出空間不換行。
  2. VirtualizingStackPanel:子控件在水平或垂直的行上虛擬化並排列,超出空間不換行。(大量數據綁定時常用)
  3. WrapPanel:子控件按從左到右的順序定位,在當前行上的控件超出允許的空間時,換行到下一行。(列表模板常用)
    <Grid ShowGridLines="True">
        <Grid.RowDefinitions>
            <RowDefinition Height="60" />
            <RowDefinition Height="60" />
            <RowDefinition Height="60" />
            <RowDefinition Height="60" />
            <RowDefinition Height="60" />
            <RowDefinition Height="60" />
        </Grid.RowDefinitions>
        <StackPanel Orientation="Horizontal">
            <TextBlock Text="statckpanelHorizontal 1" />
            <TextBlock Text="statckpanelHorizontal 2" />
            <TextBlock Text="statckpanelHorizontal 3" />
            <TextBlock Text="statckpanelHorizontal 4" />
            <TextBlock Text="statckpanelHorizontal 5" />
            <TextBlock Text="statckpanelHorizontal 6" />
        </StackPanel>
        <StackPanel Grid.Row="1" Orientation="Vertical">
            <TextBlock Text="statckpanelVertical 1" />
            <TextBlock Text="statckpanelVertical 2" />
            <TextBlock Text="statckpanelVertical 3" />
            <TextBlock Text="statckpanelVertical 4" />
            <TextBlock Text="statckpanelVertical 5" />
            <TextBlock Text="statckpanelVertical 6" />
        </StackPanel>
        <VirtualizingStackPanel Grid.Row="2" Orientation="Horizontal">
            <TextBlock Text="VirtualizingStackPanelHorizontal 1" />
            <TextBlock Text="VirtualizingStackPanelHorizontal 2" />
            <TextBlock Text="VirtualizingStackPanelHorizontal 3" />
            <TextBlock Text="VirtualizingStackPanelHorizontal 4" />
            <TextBlock Text="VirtualizingStackPanelHorizontal 5" />
            <TextBlock Text="VirtualizingStackPanelHorizontal 6" />
        </VirtualizingStackPanel>
        <VirtualizingStackPanel Grid.Row="3" Orientation="Vertical">
            <TextBlock Text="VirtualizingStackPanelVertical 1" />
            <TextBlock Text="VirtualizingStackPanelVertical 2" />
            <TextBlock Text="VirtualizingStackPanelVertical 3" />
            <TextBlock Text="VirtualizingStackPanelVertical 4" />
            <TextBlock Text="VirtualizingStackPanelVertical 5" />
            <TextBlock Text="VirtualizingStackPanelVertical 6" />
        </VirtualizingStackPanel>
        <WrapPanel Grid.Row="4" Orientation="Horizontal">
            <TextBlock Text="WrapPanelHorizontal 1" />
            <TextBlock Text="WrapPanelHorizontal 2" />
            <TextBlock Text="WrapPanelHorizontal 3" />
            <TextBlock Text="WrapPanelHorizontal 4" />
            <TextBlock Text="WrapPanelHorizontal 5" />
            <TextBlock Text="WrapPanelHorizontal 6" />
        </WrapPanel>
        <WrapPanel Grid.Row="5" Orientation="Vertical">
            <TextBlock Text="WrapPanelVertical 1" />
            <TextBlock Text="WrapPanelVertical 2" />
            <TextBlock Text="WrapPanelVertical 3" />
            <TextBlock Text="WrapPanelVertical 4" />
            <TextBlock Text="WrapPanelVertical 5" />
            <TextBlock Text="WrapPanelVertical 6" />
        </WrapPanel>
    </Grid>
View Code

效果如下:

StackPanel與VirtualizingStackPanel布局效果一樣。WrapPanel比較特殊:指定水平方向堆疊時,水平放不下自動換成下一行顯示;指定垂直方向堆疊時,垂直放不下時自動換成下一列顯示。

3、停靠

DockPanel:子控件與面板的邊緣對齊。這個分模塊布局時用的最多。

    <DockPanel>
        <WrapPanel
            Height="50"
            Background="LightBlue"
            DockPanel.Dock="Top"
            Orientation="Horizontal">
            <TextBlock Text="Header----DockPanel.Dock=Top" />
            <TextBlock Text="Header1" />
            <TextBlock Text="Header1" />
            <TextBlock Text="Header1" />
            <TextBlock Text="Header1" />
            <TextBlock Text="Header1" />
        </WrapPanel>
        <WrapPanel
            Background="LightGray"
            DockPanel.Dock="Left"
            Orientation="Vertical">
            <TextBlock Text="Left----DockPanel.Dock=Left" />
            <TextBlock Text="menu1" />
            <TextBlock Text="menu1" />
            <TextBlock Text="menu1" />
            <TextBlock Text="menu1" />
            <TextBlock Text="menu1" />
            <TextBlock Text="menu1" />
            <TextBlock Text="menu1" />
            <TextBlock Text="menu1" />
            <TextBlock Text="menu1" />
        </WrapPanel>
        <WrapPanel
            Background="LightSkyBlue"
            DockPanel.Dock="Right"
            Orientation="Horizontal">
            <TextBlock Text="Right----DockPanel.Dock=Right" />
            <TextBlock Text="content" />
            <TextBlock Text="content" />
            <TextBlock Text="content" />
            <TextBlock Text="content" />
            <TextBlock Text="content" />
            <TextBlock Text="content" />
        </WrapPanel>
    </DockPanel>
View Code

效果如下:與Grid類似,不過是固定區域按方向自動延展。

二、式樣與模板

通過定義式樣和模板,重復使用它能讓應用代碼量下降,同時也方便以后維護修改。

1、式樣 Style

    <Window.Resources>
        <!--  默認表示字體為16pt  -->
        <Style TargetType="TextBlock">
            <Setter Property="HorizontalAlignment" Value="Center" />
            <Setter Property="FontSize" Value="16" />
        </Style>
        <!--  繼承默認設置並擴展  -->
        <Style
            x:Key="Title"
            BasedOn="{StaticResource {x:Type TextBlock}}"
            TargetType="TextBlock">
            <Setter Property="FontWeight" Value="Bold" />
            <Setter Property="FontSize" Value="20" />
        </Style>
    </Window.Resources>
    <StackPanel Orientation="Vertical">
        <TextBlock Text="default style" />
        <TextBlock Style="{StaticResource Title}" Text="Title style" />
    </StackPanel>
View Code

自定義式樣效果圖:

2、模板 Template

WPF的所有控件都提供了默認的模板ControlTemplate,模板一般和式樣結合使用。模板中需要特別學習VisualState和Trigger,通過VisualState可以設計在不同狀態(鼠標按下,松開等)時控件顯示樣式,而通過Trigger可以讓控件跟隨參照對象數據或者綁定的數據做式樣變化,內容比較多此篇不詳細介紹。

如下是一個根據綁定的數據內容顯示不同控件的例子。

<Window
    x:Class="WPFUI.Core.Template"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:local="clr-namespace:WPFUI.Core"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:sys="clr-namespace:System;assembly=mscorlib"
    Title="Template"
    Width="800"
    Height="450"
    mc:Ignorable="d">
    <Window.Resources>
        <!--  TextBox的顯示模板  -->
        <DataTemplate x:Key="typeText" DataType="sys:String">
            <TextBox Width="100" Text="{Binding Path=Content, RelativeSource={RelativeSource TemplatedParent}}" />
        </DataTemplate>
        <!--  Label的顯示模板  -->
        <DataTemplate x:Key="typelabel" DataType="sys:String">
            <Label Content="{Binding Path=Content, RelativeSource={RelativeSource TemplatedParent}}" />
        </DataTemplate>
        <!--  CheckBox的顯示模板  -->
        <DataTemplate x:Key="typeCheck" DataType="sys:String">
            <CheckBox Content="{Binding Path=Content, RelativeSource={RelativeSource TemplatedParent}}" />
        </DataTemplate>
        <!--  Image的顯示模板  -->
        <DataTemplate x:Key="typeimg" DataType="sys:String">
            <Label Background="LightBlue" Content="{Binding Path=Content, RelativeSource={RelativeSource TemplatedParent}}" />
        </DataTemplate>
        <DataTemplate x:Key="typeTemp">
            <ContentPresenter
                x:Name="detail"
                Content="{Binding Path=Content, RelativeSource={RelativeSource TemplatedParent}}"
                ContentTemplate="{StaticResource typeText}" />
            <DataTemplate.Triggers>
                <!--  如果字符為text,則顯示TextBox模板  -->
                <DataTrigger Binding="{Binding}" Value="text">
                    <Setter TargetName="detail" Property="ContentTemplate" Value="{StaticResource typeText}" />
                </DataTrigger>
                <!--  如果字符為label,則顯示Label模板  -->
                <DataTrigger Binding="{Binding}" Value="label">
                    <Setter TargetName="detail" Property="ContentTemplate" Value="{StaticResource typelabel}" />
                </DataTrigger>
                <!--  如果字符為check,則顯示CheckBox模板  -->
                <DataTrigger Binding="{Binding}" Value="check">
                    <Setter TargetName="detail" Property="ContentTemplate" Value="{StaticResource typeCheck}" />
                </DataTrigger>
                <!--  如果字符為img,則顯示Image模板  -->
                <DataTrigger Binding="{Binding}" Value="img">
                    <Setter TargetName="detail" Property="ContentTemplate" Value="{StaticResource typeimg}" />
                </DataTrigger>
            </DataTemplate.Triggers>
        </DataTemplate>
    </Window.Resources>
    <Grid>
        <ListView ItemTemplate="{StaticResource typeTemp}">
            <!--  測試數據  -->
            <ListView.ItemsSource>
                <x:Array Type="sys:String">
                    <sys:String>text</sys:String>
                    <sys:String>label</sys:String>
                    <sys:String>check</sys:String>
                    <sys:String>img</sys:String>
                </x:Array>
            </ListView.ItemsSource>
            <ListView.ItemsPanel>
                <ItemsPanelTemplate>
                    <WrapPanel Orientation="Vertical" />
                </ItemsPanelTemplate>
            </ListView.ItemsPanel>
        </ListView>
    </Grid>
</Window>
View Code

效果如下:

 高端UI設計 MaterialDeisgn

它是Google開源的一套UI設計系統,用它可以設計出非常美觀的Web頁面,App,桌面程序,尤其是圖標非常全面。有它你不用懂Photoshop也可以設計出高端的界面。

官網地址:https://material.io/

一、引入MaterialDesign

WPF專用的MaterialDesign開源代碼地址:https://github.com/MaterialDesignInXAML/MaterialDesignInXamlToolkit

項目介紹網站:http://materialdesigninxaml.net/

1、添加MaterialDesignThemes包

2、編輯App.xaml添加資源 

全局引入MaterialDesign的資源文件

<prism:PrismApplication
    x:Class="WpfMaterial.Core.App"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:WpfMaterial.Core"
    xmlns:prism="http://prismlibrary.com/">
    <Application.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Light.xaml" />
                <ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Defaults.xaml" />
                <ResourceDictionary Source="pack://application:,,,/MaterialDesignColors;component/Themes/Recommended/Primary/MaterialDesignColor.Indigo.xaml" />
                <ResourceDictionary Source="pack://application:,,,/MaterialDesignColors;component/Themes/Recommended/Accent/MaterialDesignColor.Lime.xaml" />
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Application.Resources>
</prism:PrismApplication>
View Code

3、配置MaterialDesign參照和字體

添加命名空間和字體(字體對圖標顯示很重要),這樣就可以使用它里面的控件了。

<Window
    x:Class="WpfMaterial.Core.Views.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
    xmlns:prism="http://prismlibrary.com/"
    Title="{Binding Title}"
    Width="525"
    Height="350"
    prism:ViewModelLocator.AutoWireViewModel="True"
    Background="{DynamicResource MaterialDesignPaper}"
    FontFamily="{DynamicResource MaterialDesignFont}">
    <Grid>
        <materialDesign:Card Margin="16" Padding="32">
            <TextBlock Style="{DynamicResource MaterialDesignTitleTextBlock}">My First Material Design App</TextBlock>
        </materialDesign:Card>
    </Grid>
</Window>
View Code

卡片效果:

二、使用MaterialDesign

場景一:登錄界面

簡單又美麗,圖標都是MaterialDesign自帶的。

相關代碼:

        <materialDesign:Card
            Width="425"
            Height="350"
            Margin="16"
            Padding="32">
            <Grid>
                <Grid.RowDefinitions>
                    <RowDefinition Height="Auto" />
                    <RowDefinition Height="Auto" />
                    <RowDefinition Height="Auto" />
                    <RowDefinition Height="Auto" />
                    <RowDefinition Height="Auto" />
                </Grid.RowDefinitions>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="Auto" />
                    <ColumnDefinition Width="Auto" />
                    <ColumnDefinition Width="*" />
                </Grid.ColumnDefinitions>
                <TextBlock
                    Grid.Row="0"
                    Grid.ColumnSpan="4"
                    Margin="20"
                    HorizontalAlignment="Center"
                    FontSize="28"
                    Text="Login" />
                <materialDesign:PackIcon
                    Grid.Row="2"
                    Grid.Column="0"
                    Width="30"
                    Height="30"
                    Margin="30,15,10,15"
                    VerticalAlignment="Center"
                    Kind="Account" />
                <TextBox
                    Grid.Row="2"
                    Grid.Column="2"
                    Margin="0,10,30,10"
                    materialDesign:HintAssist.Hint="用戶名"
                    Style="{StaticResource MaterialDesignFloatingHintTextBox}" />

                <materialDesign:PackIcon
                    Grid.Row="3"
                    Grid.Column="0"
                    Width="30"
                    Height="30"
                    Margin="30,15,10,15"
                    VerticalAlignment="Center"
                    Kind="Key" />
                <PasswordBox
                    Grid.Row="3"
                    Grid.Column="2"
                    Margin="0,10,30,10"
                    materialDesign:HintAssist.Hint="密碼"
                    Style="{StaticResource MaterialDesignFloatingHintPasswordBox}" />
                <Button
                    Grid.Row="4"
                    Grid.ColumnSpan="4"
                    Height="50"
                    Margin="40,20,40,25"
                    Content="登錄"
                    FontSize="20" />
            </Grid>
        </materialDesign:Card>
View Code

場景二:列表界面

常見使用

相關代碼:

<Window
    x:Class="WpfMaterial.Core.Views.ListView"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
    xmlns:prism="http://prismlibrary.com/"
    xmlns:vm="clr-namespace:WpfMaterial.Core.ViewModels"
    Background="{DynamicResource MaterialDesignPaper}"
    FontFamily="{DynamicResource MaterialDesignFont}"
    FontSize="16">
    <Window.DataContext>
        <vm:ListViewViewModel />
    </Window.DataContext>
    <Window.Resources>
        <Style
            x:Key="CrudIsSelectedCheckBoxStyle"
            BasedOn="{StaticResource {x:Type CheckBox}}"
            TargetType="{x:Type CheckBox}">
            <Setter Property="HorizontalAlignment" Value="Center" />
            <Setter Property="VerticalAlignment" Value="Center" />
        </Style>

        <Style
            x:Key="CrudDataGridColumnHeaderStyle"
            BasedOn="{StaticResource {x:Type DataGridColumnHeader}}"
            TargetType="{x:Type DataGridColumnHeader}">
            <Setter Property="Background" Value="{DynamicResource PrimaryHueMidBrush}" />
            <Setter Property="BorderBrush" Value="LightGray" />
            <Setter Property="BorderThickness" Value="1" />
            <Setter Property="IsEnabled" Value="False" />
            <Setter Property="Padding" Value="2" />
            <Setter Property="Height" Value="30" />
            <Setter Property="Foreground" Value="{DynamicResource PrimaryHueMidForegroundBrush}" />
        </Style>
        <Style
            x:Key="CrudDataGridRowHeaderStyle"
            BasedOn="{StaticResource {x:Type DataGridRowHeader}}"
            TargetType="{x:Type DataGridRowHeader}">
            <Setter Property="BorderThickness" Value="0" />
            <Setter Property="Width" Value="0" />
        </Style>
        <Style
            x:Key="CrudDataGridRowStyle"
            BasedOn="{StaticResource {x:Type DataGridRow}}"
            TargetType="{x:Type DataGridRow}">
            <Setter Property="VerticalContentAlignment" Value="Stretch" />
            <Setter Property="Height" Value="30" />
            <Style.Triggers>
                <Trigger Property="IsSelected" Value="True">
                    <Setter Property="Background" Value="{DynamicResource PrimaryHueLightBrush}" />
                    <Setter Property="Foreground" Value="{DynamicResource PrimaryHueLightForegroundBrush}" />
                </Trigger>
            </Style.Triggers>
        </Style>
        <Style
            x:Key="CrudDataGridCellStyle"
            BasedOn="{StaticResource {x:Type DataGridCell}}"
            TargetType="{x:Type DataGridCell}">
            <Setter Property="Foreground" Value="{DynamicResource PrimaryHueLightForegroundBrush}" />
            <Setter Property="BorderBrush" Value="LightGray" />
            <Setter Property="BorderThickness" Value="1" />
            <Setter Property="Padding" Value="0" />
            <Style.Triggers>
                <Trigger Property="IsSelected" Value="True">
                    <Setter Property="Background" Value="{DynamicResource PrimaryHueLightBrush}" />
                    <Setter Property="Foreground" Value="{DynamicResource PrimaryHueLightForegroundBrush}" />
                    <Setter Property="BorderBrush" Value="LightGray" />
                </Trigger>
            </Style.Triggers>
        </Style>
        <Style
            x:Key="CrudEditButtonStyle"
            BasedOn="{StaticResource MaterialDesignFlatButton}"
            TargetType="{x:Type Button}">
            <Setter Property="HorizontalAlignment" Value="Center" />
            <Setter Property="Cursor" Value="Hand" />
            <Setter Property="ToolTip" Value="編輯" />
            <Setter Property="Content" Value="編輯" />
        </Style>
    </Window.Resources>
    <Grid>
        <DataGrid
            Margin="5"
            AutoGenerateColumns="False"
            CanUserAddRows="False"
            CanUserDeleteRows="False"
            CanUserResizeColumns="False"
            CanUserResizeRows="False"
            CellStyle="{StaticResource CrudDataGridCellStyle}"
            ColumnHeaderStyle="{StaticResource CrudDataGridColumnHeaderStyle}"
            ItemsSource="{Binding Items}"
            RowHeaderStyle="{StaticResource CrudDataGridRowHeaderStyle}"
            RowStyle="{StaticResource CrudDataGridRowStyle}"
            SelectionMode="Single"
            SelectionUnit="FullRow">
            <DataGrid.Columns>
                <DataGridTemplateColumn>
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <CheckBox IsChecked="{Binding Selected, Mode=TwoWay}" Style="{StaticResource CrudIsSelectedCheckBoxStyle}" />
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>
                <DataGridTextColumn
                    Width="*"
                    Binding="{Binding Name}"
                    Header="姓名" />
                <DataGridTextColumn
                    Width="Auto"
                    Binding="{Binding Age}"
                    Header="年齡" />
                <DataGridTemplateColumn Width="Auto" Header="編輯">
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <Button Style="{StaticResource CrudEditButtonStyle}">
                                <materialDesign:PackIcon Kind="Edit" />
                            </Button>
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>
            </DataGrid.Columns>
        </DataGrid>
    </Grid>
</Window>
View Code

場景三:消息界面

編輯彈出框

相關代碼:

<Window
    x:Class="WpfMaterial.Core.Views.ListView"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
    xmlns:prism="http://prismlibrary.com/"
    xmlns:system="clr-namespace:System;assembly=mscorlib"
    xmlns:vm="clr-namespace:WpfMaterial.Core.ViewModels"
    Background="{DynamicResource MaterialDesignPaper}"
    FontFamily="{DynamicResource MaterialDesignFont}"
    FontSize="16">
    <Window.DataContext>
        <vm:ListViewViewModel />
    </Window.DataContext>
    <Window.Resources>
        <Style
            x:Key="CrudIsSelectedCheckBoxStyle"
            BasedOn="{StaticResource {x:Type CheckBox}}"
            TargetType="{x:Type CheckBox}">
            <Setter Property="HorizontalAlignment" Value="Center" />
            <Setter Property="VerticalAlignment" Value="Center" />
        </Style>

        <Style
            x:Key="CrudDataGridColumnHeaderStyle"
            BasedOn="{StaticResource {x:Type DataGridColumnHeader}}"
            TargetType="{x:Type DataGridColumnHeader}">
            <Setter Property="Background" Value="{DynamicResource PrimaryHueMidBrush}" />
            <Setter Property="BorderBrush" Value="LightGray" />
            <Setter Property="BorderThickness" Value="1" />
            <Setter Property="IsEnabled" Value="False" />
            <Setter Property="Padding" Value="2" />
            <Setter Property="Height" Value="30" />
            <Setter Property="Foreground" Value="{DynamicResource PrimaryHueMidForegroundBrush}" />
        </Style>
        <Style
            x:Key="CrudDataGridRowHeaderStyle"
            BasedOn="{StaticResource {x:Type DataGridRowHeader}}"
            TargetType="{x:Type DataGridRowHeader}">
            <Setter Property="BorderThickness" Value="0" />
            <Setter Property="Width" Value="0" />
        </Style>
        <Style
            x:Key="CrudDataGridRowStyle"
            BasedOn="{StaticResource {x:Type DataGridRow}}"
            TargetType="{x:Type DataGridRow}">
            <Setter Property="VerticalContentAlignment" Value="Stretch" />
            <Setter Property="Height" Value="30" />
            <Style.Triggers>
                <Trigger Property="IsSelected" Value="True">
                    <Setter Property="Background" Value="{DynamicResource PrimaryHueLightBrush}" />
                    <Setter Property="Foreground" Value="{DynamicResource PrimaryHueLightForegroundBrush}" />
                </Trigger>
            </Style.Triggers>
        </Style>
        <Style
            x:Key="CrudDataGridCellStyle"
            BasedOn="{StaticResource {x:Type DataGridCell}}"
            TargetType="{x:Type DataGridCell}">
            <Setter Property="Foreground" Value="{DynamicResource PrimaryHueLightForegroundBrush}" />
            <Setter Property="BorderBrush" Value="LightGray" />
            <Setter Property="BorderThickness" Value="1" />
            <Setter Property="Padding" Value="0" />
            <Style.Triggers>
                <Trigger Property="IsSelected" Value="True">
                    <Setter Property="Background" Value="{DynamicResource PrimaryHueLightBrush}" />
                    <Setter Property="Foreground" Value="{DynamicResource PrimaryHueLightForegroundBrush}" />
                    <Setter Property="BorderBrush" Value="LightGray" />
                </Trigger>
            </Style.Triggers>
        </Style>
        <Style
            x:Key="CrudEditButtonStyle"
            BasedOn="{StaticResource MaterialDesignFlatButton}"
            TargetType="{x:Type Button}">
            <Setter Property="HorizontalAlignment" Value="Center" />
            <Setter Property="Cursor" Value="Hand" />
            <Setter Property="ToolTip" Value="編輯" />
            <Setter Property="Content" Value="編輯" />
        </Style>
    </Window.Resources>
    <materialDesign:DialogHost DialogMargin="8" Style="{StaticResource MaterialDesignEmbeddedDialogHost}">
        <materialDesign:DialogHost.DialogContent>
            <StackPanel Margin="20">
                <TextBlock
                    FontSize="20"
                    FontWeight="Bold"
                    Text="添加用戶" />
                <TextBox
                    Width="200"
                    Margin="0,8,0,0"
                    HorizontalAlignment="Stretch"
                    materialDesign:HintAssist.Hint="姓名"
                    Style="{StaticResource MaterialDesignFloatingHintTextBox}" />
                <TextBox
                    Width="200"
                    Margin="0,8,0,0"
                    HorizontalAlignment="Stretch"
                    materialDesign:HintAssist.Hint="年齡"
                    Style="{StaticResource MaterialDesignFloatingHintTextBox}" />
                <StackPanel HorizontalAlignment="Right" Orientation="Horizontal">
                    <Button
                        Margin="0,8,8,0"
                        Command="materialDesign:DialogHost.CloseDialogCommand"
                        IsDefault="True"
                        Style="{StaticResource MaterialDesignFlatButton}">
                        <Button.CommandParameter>
                            <system:Boolean xmlns:system="clr-namespace:System;assembly=mscorlib">
                                True
                            </system:Boolean>
                        </Button.CommandParameter>
                        確定
                    </Button>
                    <Button
                        Margin="0,8,8,0"
                        Command="materialDesign:DialogHost.CloseDialogCommand"
                        IsCancel="True"
                        Style="{StaticResource MaterialDesignFlatButton}">
                        <Button.CommandParameter>
                            <system:Boolean xmlns:system="clr-namespace:System;assembly=mscorlib">
                                False
                            </system:Boolean>
                        </Button.CommandParameter>
                        取消
                    </Button>
                </StackPanel>
            </StackPanel>
        </materialDesign:DialogHost.DialogContent>
        <Grid>
            <DataGrid
                Margin="5"
                AutoGenerateColumns="False"
                CanUserAddRows="False"
                CanUserDeleteRows="False"
                CanUserResizeColumns="False"
                CanUserResizeRows="False"
                CellStyle="{StaticResource CrudDataGridCellStyle}"
                ColumnHeaderStyle="{StaticResource CrudDataGridColumnHeaderStyle}"
                ItemsSource="{Binding Items}"
                RowHeaderStyle="{StaticResource CrudDataGridRowHeaderStyle}"
                RowStyle="{StaticResource CrudDataGridRowStyle}"
                SelectionMode="Single"
                SelectionUnit="FullRow">
                <DataGrid.Columns>
                    <DataGridTemplateColumn>
                        <DataGridTemplateColumn.CellTemplate>
                            <DataTemplate>
                                <CheckBox IsChecked="{Binding Selected, Mode=TwoWay}" Style="{StaticResource CrudIsSelectedCheckBoxStyle}" />
                            </DataTemplate>
                        </DataGridTemplateColumn.CellTemplate>
                    </DataGridTemplateColumn>
                    <DataGridTextColumn
                        Width="*"
                        Binding="{Binding Name}"
                        Header="姓名" />
                    <DataGridTextColumn
                        Width="Auto"
                        Binding="{Binding Age}"
                        Header="年齡" />
                    <DataGridTemplateColumn Width="Auto" Header="編輯">
                        <DataGridTemplateColumn.CellTemplate>
                            <DataTemplate>
                                <Button Style="{StaticResource CrudEditButtonStyle}">
                                    <materialDesign:PackIcon Kind="Edit" />
                                </Button>
                            </DataTemplate>
                        </DataGridTemplateColumn.CellTemplate>
                    </DataGridTemplateColumn>
                </DataGrid.Columns>
            </DataGrid>
            <Button
                Margin="0,0,28,20"
                HorizontalAlignment="Right"
                VerticalAlignment="Bottom"
                Command="{x:Static materialDesign:DialogHost.OpenDialogCommand}"
                Style="{StaticResource MaterialDesignFloatingActionMiniAccentButton}">
                <materialDesign:PackIcon
                    Width="22"
                    Height="22"
                    Kind="Plus" />
            </Button>
        </Grid>
    </materialDesign:DialogHost>
</Window>
View Code

總結

以上效果有沒有覺得很炫,用MaterialDesign設計界面簡單又美觀,這也是我推薦的原因。

其他顯示效果可以參考Github上的模擬程序:https://github.com/MaterialDesignInXAML/MaterialDesignInXamlToolkit/releases

 

 模擬程序主題配色一覽如下:

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM