WPF入門教程系列六——佈局介紹與Canvas(一)

       從這篇文章開始是對WPF中的界面如何佈局作一個較簡單的介紹,你們都知道:UI是作好一個軟件很重要的因素,若是沒有一個漂亮的UI,功能作的再好也沒法吸引不少用戶使用,並且沒有漂亮的界面,那麼普通用戶會感受這個軟件沒有多少使用價值。ide

一. 整體介紹工具

        WPF的佈局控件都在System.Windows.Controls.Panel這個基類下面,使用 WPF提供的各類控件在WPF應用程序中界面進行佈局,同時對各類子控件(如按鈕、文本框,下拉框等)進行排列組合。佈局

 

Pane類的公共屬性太多了。就簡單介紹幾個常見的屬性以下表。性能

  

名稱字體

說明this

 

Cursorspa

獲取或設置在鼠標指針位於此元素上時顯示的光標。 3d

 

DataContext指針

獲取或設置元素參與數據綁定時的數據上下文。 code

 

Dispatcher

獲取與此 DispatcherObject 關聯的 Dispatcher。 

 

FontFamily

獲取或設置控件的字體系列。 

 

FontSize

獲取或設置字號。 

 

FontWeight

獲取或設置指定的字體的權重或粗細。 

 

Foreground

獲取或設置描述前景色的畫筆。 

 

HandlesScrolling

獲取一個值控件是否支持滾動。

 

Height

獲取或設置元素的建議高度。 

 

HorizontalContentAlignment

獲取或設置控件內容的水平對齊。 

 

IsLoaded

獲取一個值,該值指示是否已加載此元素以供呈現。 

 

IsMouseOver

獲取一個值,該值指示鼠標指針是否位於此元素(包括可視樹上的子元素)上。這是一個依賴項屬性。 

 

IsTabStop

獲取或設置一個值控制是否在選項卡上導航包含。 

 

IsVisible

獲取一個值,該值指示此元素在用戶界面 (UI) 中是否可見。這是一個依賴項屬性。 

 

LayoutTransform

獲取或設置在執行佈局時應該應用於此元素的圖形轉換方式。 

 

Margin

獲取或設置元素的外邊距。 

 

Name

獲取或設置元素的標識名稱。 該名稱提供一個引用,以便當 XAML 處理器在處理過程當中構造標記元素以後,代碼隱藏(如事件處理程序代碼)能夠對該元素進行引用。

 

Opacity

獲取或設置當 UIElement 在用戶界面 (UI) 中呈現時爲其總體應用的不透明度因子。這是一個依賴項屬性。 

 

Padding

獲取或設置控件中的空白。 

 

RenderTransform

獲取或設置影響此元素的呈現位置的轉換信息。這是一個依賴項屬性。 

 

TabIndex

獲取或設置使用 tab 鍵時,肯定順序接收焦點的元素的值,當用戶將控件定位。 

 

Tag

獲取或設置任意對象值,該值可用於存儲關於此元素的自定義信息。 

 

ToolTip

獲取或設置在用戶界面 (UI) 中爲此元素顯示的工具提示對象。 

 

TouchesCaptured

獲取在此元素上捕獲的全部觸摸設備。 

 

TouchesCapturedWithin

獲取在此元素或其可視化樹中的任何子元素上捕獲的全部觸摸設備。 

 

VerticalContentAlignment

獲取或設置控件內容的垂直對齊方式。 

 

Visibility

獲取或設置此元素的用戶界面 (UI) 可見性。這是一個依賴項屬性。 

 

VisualOpacityMask

獲取或設置 Brush 值,該值表示 Visual 的不透明蒙板。 

 

Width

獲取或設置元素的寬度。 

 

       一個Panel 的呈現就是測量和排列子控件,而後在屏幕上繪製它們。因此在佈局的過程當中會通過一系列的計算,那麼子控件越多,執行的計算次數就越多,則性能就會變差。若是不須要進行復雜的佈局,則儘可能少用複雜佈局控件(如 Grid和自定義複雜的Panel);若是能簡單佈局實現就儘可能使用構造相對簡單的佈局(如 Canvas、UniformGrid等),這種佈局可帶來更好的性能。 若是有可能,咱們應儘可能避免調用 UpdateLayout方法。 
      每當Panel內的子控件改變其位置時,佈局系統就可能觸發一個新的處理過程。對此,瞭解哪些事件會調用佈局系統就很重要,由於沒必要要的調用可能致使應用程序性能變差。 
       換句話說,佈局是一個遞歸系統,實如今屏幕上對控件進行大小調整、定位和繪製,而後進行呈現。具體以下圖,要實現控件0的佈局,那麼先要實現0的子控件 01,02...的佈局,要實現01的佈局,那麼得實現01的子控件001,002...的佈局,如此循環直到子控件的佈局完成後,再完成父控件的佈局, 最後遞歸回去直到遞歸結束,這樣整個佈局過程就完成了.

 

      佈局系統爲Panel中的每一個子控件完成兩個處理過程:測量處理過程(Measure)和排列處理過程(Arrange)。每一個子 Panel 均提供本身的 MeasureOverride 和 ArrangeOverride 方法,以實現本身特定的佈局行爲。

二. Canvas 

      Canvas是最基本的面板,只是一個存儲控件的容器,它不會自動調整內部元素的排列及大小,它僅支持用顯式座標定位控件,它也容許指定相對任何角的座標,而不單單是左上角。可使用Left、Top、Right、 Bottom附加屬性在Canvas中定位控件。經過設置Left和Right屬性的值表示元素最靠近的那條邊,應該與Canvas左邊緣或右邊緣保持一個固定的距離,設置Top和Bottom的值也是相似的意思。實質上,你在選擇每一個控件停靠的角時,附加屬性的值是做爲外邊距使用的。若是一個控件沒有使 用任何附加屬性,它會被放在Canvas的左上方(等同於設置Left和Top爲0)。

      Canvas的主要用途是用來畫圖。Canvas默認不會自動裁減超過自身範圍的內容,即溢出的內容會顯示在Canvas外面,這是由於默認 ClipToBounds=」False」;咱們能夠經過設置ClipToBounds=」True」來裁剪多出的內容。

 

接下來咱們來看兩個實例,第一個實例使用XAML代碼實現:

<Window x:Class="WpfApp1.WindowCanvas"

        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

        Title="WindowCanvas" Height="400" Width="500">

    <Grid>

        <Canvas Margin="0,0,0,0" Background="White">

            <Rectangle Fill="Blue" 

                Stroke="Azure" 

                Width="250" 

                Height="200" 

                Canvas.Left="210" Canvas.Top="101"/>

            <Ellipse Fill="Red" 

                Stroke="Green" 

                Width="250" Height="100" 

                Panel.ZIndex="1" 

                Canvas.Left="65" Canvas.Top="45"/>

        </Canvas>

        <Canvas>

            <Button Name="btnByCode" Click="btnByCode_Click">後臺代碼實現</Button>

        </Canvas>

    </Grid>

</Window>

 

 

實例後的效果以下圖。

 

第二個實例,咱們使用後臺代碼來實現。我使用C#來實現

 

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

using System.Windows;

using System.Windows.Controls;

using System.Windows.Data;

using System.Windows.Documents;

using System.Windows.Input;

using System.Windows.Media;

using System.Windows.Media.Imaging;

using System.Windows.Shapes;

 

namespace WpfApp1

{

    /// <summary>

    /// WindowCanvas.xaml 的交互邏輯

    /// </summary>

    public partial class WindowCanvas : Window

    {

        public WindowCanvas()

        {

            InitializeComponent();

            

        }

 

        public void DisplayCanvas()

        {

            Canvas canv = new Canvas();

            //把canv添加爲窗體的子控件

            this.Content = canv;

            canv.Margin = new Thickness(0, 0, 0, 0);

            canv.Background = new SolidColorBrush(Colors.White);

 

            //Rectangle

            Rectangle r = new Rectangle();

            r.Fill = new SolidColorBrush(Colors.Red);

            r.Stroke = new SolidColorBrush(Colors.Red);

            r.Width = 200;

            r.Height = 140;

            r.SetValue(Canvas.LeftProperty, (double)200);

            r.SetValue(Canvas.TopProperty, (double)120);

            canv.Children.Add(r);

            //Ellipse

            Ellipse el = new Ellipse();

            el.Fill = new SolidColorBrush(Colors.Blue);

            el.Stroke = new SolidColorBrush(Colors.Blue);

            el.Width = 240;

            el.Height = 80;

            el.SetValue(Canvas.ZIndexProperty, 1);

            el.SetValue(Canvas.LeftProperty, (double)100);

            el.SetValue(Canvas.TopProperty, (double)80);

            canv.Children.Add(el);

 

        }

 

        private void btnByCode_Click(object sender, RoutedEventArgs e)

        {

            DisplayCanvas();

        }

    }

}

 

 

 實現後的效果以下圖。

 

最後 要說明一點Canvas內的子控件不能使用兩個以上的Canvas附加屬性,若是同時設置Canvas.LeftCanvas.Right屬性,那麼後者將會被忽略。

相關文章
相關標籤/搜索