vs2019實現WPF程序

一 .NET Core桌面應用

  主要介紹關於桌面開發四個方面:Windows平臺、.NET Core 3 平臺上的WPF,Winform, 應用打包解決方案 MSIX 和 XAML 羣島訪問原來UWP的控件,讓我們的應用程序迅速現代化。

1 Windows平臺應用開發

  Windows平臺上的應用開發,我們通常會選擇以下三個技術:Windows FormsWindows Presentation FoundationUniversal Windows Platform (UWP)。這些選項只是我們針對 Windows 開發應用時所擁有的不同 UI 框架選項。更重要的是, 當你優化你的應用針對Windows 10時, 你會得到更多的創新、Api 和windows 10操作系統爲您提供的好處。
  個UI 框架現在都是開源的:
  Windows Presentation Foundation: https://github.com/dotnet/wpf
  Windows Forms: https://github.com/dotnet/winforms
  Windows 10 XAML: https://github.com/Microsoft/microsoft-ui-xaml

2 WPF,Winform(基於.NET Core 3 平臺)

  .NET Framework 4.8 已經發布,.NET 4.8 已經幫助我們解決了很多問題, WPF和Windows Forms的高DPI更好的至此,Windows 10 中最新的瀏覽器和媒體播放器的新控件,並支持最新的標準。.NET Core 3的主要特點是支持 Windows 桌面應用,包括 Windows 窗體和 WPF 應用。 你將能夠在 .NET Core 3 上運行新的和現有的 Windows 桌面應用並體驗 .NET Core 具有的所有優勢。 託管在 XAML 島中的 UWP 控件也可在面向 .NET Core 3 的 Windows 窗體和 WPF 應用中使用。
  .NET Core 的性能更好,速度更快,.NET Core的並行安裝的特性可以幫助你在發佈應用程序中獲取顯而易見的方便,更好的打包方案MSIX, 開源,支持.NET Standard 2.1, 支持C# 8.0等還有很多新特性。
  使用.NET Core 3 升級Windows 桌面應用開發的好處還有很多,下面簡要的列幾條:
  現代運行時、BCL 和語言功能
  更容易訪問平臺和設備的API
  現代化 且可訪問的的UI和輸入
  針對 DevOps 進行無縫的應用程序部署、更新和優化
  開發人員更好進行敏捷創新
  .NET可移植性分析器可幫助您識別代碼中可移植或不可移植到. net Core 的部分, 爲您提供完整的 Excel 報告。 第一步是從package.json遷移到 PackageReference。
  最簡單的方法是創建一個運行 “dotnet new wpf” 或 “dotnet new winforms” 的空 csproj。
  您可以使用生成的 csproj 作爲起點, 從舊 csproj 遷移您的 PackageReferences , 然後從那裏開始。
  大多數項目都應該是相當超前的。
  如果您需要更多信息, 請按照博客文章中的步驟操作。它是非常完整的。https://devblogs.microsoft.com/dotnet/porting-desktop-apps-to-net-core/

3 MSIX

  MSIX是一種Windows應用包格式,可以爲所有Windows應用程序提供現代化打包體驗。MSIX 是一種基於.msi, appx、 app-V和 ClickOnce 安裝技術的組合構建的一種安全可靠的打包格式。
  能夠在不對計算機構成風險或引起“計算機腐爛”的情況下安裝和卸載
  開箱即用的自動更新
  更容易分發,可以通過微軟商店,企業自己的微軟商店,文件共享,HTTP URL分發

4 UWP

  從 Windows 10 版本 1903 開始,可以將 UWP XAML 控件直接添加到與窗口句柄 (HWND) 關聯的 WPF、Windows 窗體或 C++ Win32 應用中的任何 UI 元素。 這意味着,你可以將最新的 UWP 功能(例如 Windows Ink 和支持 Fluent Design System 的控件完全集成到 Windows 以及桌面應用的其他顯示錶面中去。 此開發人員方案有時稱爲“XAML 島”。
  關於Windows開發,其中一個最大的抱怨是微軟在Winforms和wpf的投入少;Windows10提供的大部分新特性都只是針對UWP構建的。雖然我們現在可以從.NET Framework 調用UWP API,但僅適用於不涉及UI的情況。爲了解決這個問題,微軟創建了兩個新控件:WinForms XAML Host和WPF XAML Host,使開發人員可以把UWP編寫的UI嵌入到現有WinForms/WPF應用程序。

二 創建

在這裏插入圖片描述
  從工具箱中拖拽一個Button控件,修改顯示名稱並添加事件,如下圖所示:
在這裏插入圖片描述
  雙擊按鈕,進入事件代碼區域,簡單添加一個彈出顯示提示文字的對話框代碼,如下圖所示:
在這裏插入圖片描述
  運行,程序創建完畢。

三 XAML

1 概述

  XAML是微軟創造的一種開發語言,即可拓展應用程序標記語言。扮演了HTML+CSS+JavaScript的角色。

2 剖析XAML代碼

  一個.xaml下會有一個.xaml.cs,.xaml.cs文件會有對應的分部類。XAML標籤聲明一個元素時對應的內存中的一個對象,最外層的標籤元素就是後臺代碼的分部類。
  在XAML中對象之間的層級關係,要麼是並列要麼是包含,全部體現在標籤的關係上。那在後臺類裏,我們可以通過using引用其它名稱空間,而在XAML代碼裏,我們通過xmlns特徵來定義名稱空間,格式如下:
  xmlns:[可選的映射前綴]="名稱空間"。看下默認的XAML代碼:

<Window x:Class="PLCSerialPortRecv.MainWindow"
        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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:PLCSerialPortRecv"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        
    </Grid>
</Window>

  可以發現我們有5行代碼以xmlns開頭,也就是“引用了5個默認的名稱空間”。其中x:和mc:開頭表示調用上面聲明引用的名稱空間。
  x:它包含的類都是與解析XAML語言相關。x:Class="MyFirstWpfApplication.MainWindow"表示將當前這個Window這個標籤解析成C#類的類名。這也和我們開始驗證的其爲後臺分部類一樣。它是x:下的Attribute,只能用於根節點,且根節點的類型要與x:Class所指示的類型(且爲分部類)一致。
  補充 x名稱空間下的其它Attribute:x:Name:告訴編譯器爲這個標籤生成對應的實例外還要爲這個實例聲明一個引用變量,變量名就是x:Name的值。還有將XAML標籤所對應的對象的Name屬性也設爲x:Name的值,並註冊到UI樹上,方便查找。x:FieldModeifer 設置元素可訪問級別。x:key 採用鍵值對等。

3 XAML語法

  xaml文檔是一個樹形結構。
  xaml中爲對象屬性賦值的語法:首先xaml代碼不能編寫程序的運行邏輯,當我們創建標籤對象的時候對其屬性進行必要的初始化纔有使用意義。爲對象屬性賦值有兩種方法
  1.使用字符串進行簡單賦值。即簡單的Attribute=Value語法賦值,由於xaml語法限制,Value只能是字符串的值。
  2.使用屬性元素進行復雜賦值。屬性元素指的是某個標籤的一個元素對應這個標籤的一個屬性,即以元素的形式來表達一個實例的屬性。

4 XAML對名稱空間引用的語法

  xmlns:[映射名]=“clr-namespace:類庫中名稱空間的名字;assembly=類庫文件名”

5 窗體的關閉事件Closing 和Closed

  當窗口關閉時,它會引發兩個事件:Closing 和 Closed。
  Closing 在窗口關閉之前引發,它提供一種機制,可以通過這種機制來阻止窗口關閉。 系統會向Closing 事件處理程序傳遞一個 CancelEventArgs e,該參數實現 Boolean Cancel 屬性,將該屬性設置爲 true 可以阻止窗口關閉。

 private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
 {
     MessageBoxResult result = MessageBox.Show("確定是退出嗎?", "詢問", MessageBoxButton.YesNo, MessageBoxImage.Question);
     //關閉窗口
     if (result == MessageBoxResult.Yes)
         e.Cancel = false;
     //不關閉窗口
     if (result == MessageBoxResult.No)
         e.Cancel = true;
 }

  如果未處理Closing,或者處理但未取消,則窗口將關閉。 在窗口真正關閉之前,會引發 Closed,這時無法阻止窗口關閉。

四 控件

1 Grid

  Grid和其他各個Panel比較起來,功能最多也最爲複雜。要使用Grid,首先要向RowDefinitions和ColumnDefinitions屬性中添加一定數量的RowDefinitions和 ColumnDefinitions元素,從而定義行數和列數;而放置在Grid面板中的控件元素都必須顯示採用Row和Column附加屬性定義其放置所在的行和列,這兩個屬性的值都是從0開始的索引數,如果沒有顯式設置任何行或列,Grid將會隱式地將控件加入在第0行第0列。
  注意:儘管Grid面板被設計成不可見的,但可將Grid.ShowGridLines屬性設置爲True,從而更清晰的觀察Grid面板,方便調試,可以更準確地控制Grid面板如何選擇列寬和行高。
  https://www.cnblogs.com/dotnet261010/p/6281915.html

1 ScrollViewer控件

  內容超過空間,出現滾動條。
  TextWrapping=“Wrap”,超出寬度,自動換行。

2 Panel分組類控件

3 groupBox分組框控件

4 TabControl選項卡控件

6 StackPanel(堆佈局)

  這個佈局是比較簡單的佈局模式,在這個StackPanel容器,控件都是以一列,或者一行的方式來順序排列。
  StackPanel默認是垂直一列排列,通過設置Orientation這個屬性來設置水平一行排序
在這裏插入圖片描述
  水平
在這裏插入圖片描述
  默認情況下,容器內的控件都是被拉伸的,和容易一樣高或者一樣寬
  在垂直模式下,按鈕都是和屏幕的寬帶一樣被拉伸,垂直排列,並且是居中顯示。
  垂直模式下HorizontalAlignment可以設置“Center,left,right,stretch”4個屬性
  如果設置center,那麼容器的寬度會和按鈕的寬度一樣(按鈕的寬度默認就是字符內容的長度),並且居中顯示
  如果設置Left,那麼容器就會顯示在屏幕的左側,寬度和按鈕寬度一樣,如圖示:
在這裏插入圖片描述
  在容器內的各個按鈕上也可以設置自己的水平排列方式,如果設置Left,那麼按鈕排列在容器左側,如果是right,按鈕牌子在容器右側,如果是stretch這個按鈕仍然是拉伸顯示

<StackPanel x:Name="StackPanel1" Orientation="Vertical">
        <Button x:Name="btn1" Content="Button1"  HorizontalAlignment="Left"></Button>
        <Button x:Name="btn2" Content="Button2" HorizontalAlignment="Center"></Button>
        <Button x:Name="btn3" Content="Button3" HorizontalAlignment="Stretch"></Button>
        <Button x:Name="btn4" Content="Button4" HorizontalAlignment="Right"></Button>
</StackPanel>

在這裏插入圖片描述
  

7 DockPanel停靠面板

  DockPanel定義一個區域,在此區域中,您可以使子元素通過描點的形式排列,這些對象位於 Children 屬性中。停靠面板類似於WinForm中控件的Dock屬性。DockPanel會對每個子元素進行排序,並將根據指定的邊進行停靠,多個停靠在同側的元素則按順序排序。在DockPanel中,指定停靠邊的控件,會根據定義的順序佔領邊角,所有控件絕不會交疊。
  默認情況下,後添加的元素只能使用剩餘空間,無論對DockPanel的最後一個子元素設置任何停靠值,該子元素都將始終填滿剩餘的空間。如果不希望最後一個元素填充剩餘區域,可以將DockPanel屬性LastChildFill設置爲false,還必須爲最後一個子元素顯式指定停靠方向。
  填充整個剩餘空間
在這裏插入圖片描述

<Window x:Class="WpfDemo.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="DockPanel面板" Height="237" Width="525" WindowStartupLocation="CenterScreen">
    <DockPanel>
        <Button DockPanel.Dock="Left" Content="ButtonLeft"></Button>
        <Button DockPanel.Dock="Top" Content="ButtonTop"></Button>
        <Button DockPanel.Dock="Right" Content="ButtonRight"></Button>
        <Button DockPanel.Dock="Bottom" Content="ButtonBottom"></Button>
        <Button  Content="ButtonTop"></Button>
    </DockPanel>
</Window>

  最後元素不填充剩餘空間
在這裏插入圖片描述

<Window x:Class="WpfDemo.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="DockPanel面板" Height="237" Width="525" WindowStartupLocation="CenterScreen">
    <DockPanel LastChildFill="False">
        <Button DockPanel.Dock="Left" Content="ButtonLeft"></Button>
        <Button DockPanel.Dock="Top" Content="ButtonTop"></Button>
        <Button DockPanel.Dock="Right" Content="ButtonRight"></Button>
        <Button DockPanel.Dock="Bottom" Content="ButtonBottom"></Button>
        <Button  DockPanel.Dock="Top" Content="最後一個Button不填充剩餘空間"></Button>
    </DockPanel>
</Window>

五 屬性

1 窗體初始位置WindowStartupLocation

  當窗口打開時,窗口在相對於桌面的 x 和 y 維度有一個位置。 可以通過分別檢查 Left 和 Top 屬性來確定此位置。 可以設置這些屬性以更改窗口的位置。
  通過將 WindowStartupLocation 屬性設置爲下面的 WindowStartupLocation 枚舉值之一,還可以指定 Window 第一次出現時的初始位置:Manual(默認值)、CenterScreen、CenterOwner。
  如果將起始位置指定爲 Manual,並且未設置 Left 和 Top 屬性,則 Window 將向 Windows 請求顯示的位置。

2 Margin and Padding

  在界面設計時,Margin 和Padding都是對邊距進行限制的,其區別在於“一個主外,一個主內”。
  <font size=3Margin (邊緣)是約束控件與容器控件的邊距,設置值分別代表左上右下,使用 Margin=“20” 同時指定四個值。
  <font size=3Padding (襯墊)是約束控件內部輸入邊距的,只有部分控件有此屬性。

3 Grid.ColumnDefinitions和Grid.RowDefinitions

  Grid.RowDefinitions屬性將Grid控件分行,屬性值爲RowDefinition標籤,每一個RowDefinition標籤將該Grid對象分爲一行;

Grid.ColumnDefinitions屬性將Grid控件分列,屬性值爲ColumnDefinition標籤,每一個ColumnDefinition標籤將該Grid對象分爲一列;
  在給每個方塊添加空間時只需指定該控件的Grid.Column和Grid.Row附加屬性值,前提是該控件要定義在Grid空間中,否則將找不到這兩個屬性,也就無法將該控件添加到指定方格中。
  當指定的行或列的值大於Grid的單元格數量時,系統默認爲最後一個,比如:

<Grid x:Name="LayoutRoot" Background="Blue">  
    <Grid.ColumnDefinitions>  
        <ColumnDefinition></ColumnDefinition>  
        <ColumnDefinition></ColumnDefinition>  
    </Grid.ColumnDefinitions>  
    <Grid.RowDefinitions>  
        <RowDefinition></RowDefinition>  
        <RowDefinition></RowDefinition>  
        <RowDefinition></RowDefinition>  
    </Grid.RowDefinitions>  
  
    <Button Grid.Column="0" Grid.Row="0" Content=" 0  , 0"></Button>  
    <Button Grid.Column="1" Grid.Row="1" Content=" 1  , 1"></Button>  
    <Button Grid.Column="2" Grid.Row="2" Content=" 2  , 2"></Button>  
</Grid>

  在該示例中,我們將Grid控件分爲3行2列,而添加Button時我們卻設定其位置分別爲(0,0),(1,1),(2,2)。很明顯,該Grid並不包含(2,2)–因爲它只有2列,但是調試運行時系統並不會報錯,而是出現下面的結果:
在這裏插入圖片描述

六 將 WPF 應用遷移到 .NET Core

  官方文檔:https://docs.microsoft.com/zh-cn/dotnet/desktop-wpf/migration/convert-project-from-net-framework
  
  
  
  

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章