天天看點

【WPF學習】第九章 使用Canvas面闆進行基于坐标的布局

  Canvas面闆允許使用精确的坐标放置元素,如果設定資料驅動的富窗體和标準對話框,這并非好的選擇;但如果需要建構其他一些不同的内容(例如,為圖形工具建立建立繪圖表面),Canvas面闆可能是個有用的工具。Canvas面闆還是最輕量級的布局容器。這是因為Canvas面闆沒有包含任何複雜的布局邏輯,用以改變其子元素的首選尺寸。Canvas面闆隻是在指定的位置放置其子元素,并且子元素具有所希望的精确尺寸。

  為在Canvas面闆中定位元素,需要設定Canvas.Left和Canvas.Top附加屬性。Canvas.Left屬性設定元素左邊和Canvas面闆左邊之間的機關數。Canvas.Top屬性設定子元素頂部和Canvas面闆頂邊之間的機關數。同樣,這些數值也是以裝置無關機關設定的。當将系統DPI設定為96dpi時,裝置無關機關恰好等于通常的像素。

  可使用Width和Height屬性明确設定子元素的尺寸。與使用其他面闆相比,使用Canvas面闆時這種設定更普遍,因為Canvas面闆沒有自己的布局邏輯(并且當需要精确控制組合元素如何排列時,經常會使用Canvas面闆)。如果沒有設定Width和Height屬性,元素會擷取它所期望的尺寸——換句話說,它将變得足夠大以适應其内容。

  下面是一個使用Canvas的示例:

<Window x:Class="CanvasLayout.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Canvas>
        <Button Canvas.Left="10" Canvas.Top="10">(10,10)</Button>
        <Button Canvas.Left="120" Canvas.Top="30">(120,30)</Button>
        <Button Canvas.Left="60" Canvas.Top="80" Width="80" Height="60">(60,80)</Button>
        <Button Canvas.Left="180" Canvas.Top="150" Width="100" Height="60">(180,150)</Button>
    </Canvas>
</Window>      

  最終效果如下圖所示:

【WPF學習】第九章 使用Canvas面闆進行基于坐标的布局

  如果改變視窗的大小,Canvas面闆就會拉伸以填滿可用空間,但Canvas面闆上的控件不會改變其尺寸和位置。Canvas面闆不包含任何錨定和停靠功能,這兩個功能是在Windows窗體中使用坐标布局提供的。造成該問題的部分原因是為了保持Canvas面闆的輕量級,另一個原因是為了防止以不當目的使用Canvas面闆(例如,确定标準使用者界面的布局)。

  與其他所有布局容器一樣,可在使用者界面中嵌套Canvas面闆。這意味着可使用Canvas面闆在視窗的一部分繪制一些細節内容,而在視窗的其餘部分使用更合乎标準的WPF面闆。

一、Z順序

  如果Canvas面闆中有多個互相重疊的元素,可通過設定Canvas.ZIndex附加屬性來控制他們的層疊方式。

  添加的所有元素通常都具有相同的ZIndex指——0。如果元素具有相同的ZIndex值,就按他們在Canvas.Children集合中的順序進行顯示,這個順序依賴于元素在XAML标記中定義的順序。在标記靠後位置聲明的元素會顯示在前面聲明的元素的上面。

  然而,可通過增加任何子元素的ZIndex值來提高層次級别。因為具有更高ZIndex值的元素始終顯示在較低ZIndex值得元素的上面。如下代碼所示:

<Window x:Class="CanvasLayout.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Canvas>
        <Button Canvas.Left="10" Canvas.Top="10">(10,10)</Button>
        <Button Canvas.Left="120" Canvas.Top="30">(120,30)</Button>
        <Button Canvas.Left="180" Canvas.Top="110" Canvas.ZIndex="1"  Width="80" Height="60">(180,110)</Button>
        <Button Canvas.Left="180" Canvas.Top="150" Width="100" Height="60">(180,150)</Button>
    </Canvas>
</Window>      

  效果如下圖所示:

【WPF學習】第九章 使用Canvas面闆進行基于坐标的布局

   如果需要通過代碼來改變元素的位置,ZIndex屬性是非常有用的。隻需要調用Canvas.SetZIndex()方法,并傳遞希望修改的元素和希望使用的新ZIndex值即可。遺憾的是,并不存在BringToFront()或SendToBack()方法——要實作這一行為,需要跟蹤最高和最低的ZIndex值。

二、InkCanvas元素

  WPF還提供了InkCanvas元素,它與Canvas面闆在某些方法是類似的(而在其他方面卻完全不同)。和Canvas面闆一樣,InkCanvas元素定義了4個附加屬性(Top、Left、Bottom和Right),可将這4個附加屬性應用于子元素,以根據坐标進行定位。然而,基本的内容差別很大——實際上,InkCanvas類不是派生自Canvas類,甚至也不是派生自Panel基類,而是直接派生自FrameworkElement類。

  InkCanvas元素的主要目的用于接收手寫筆輸入。手寫筆是一種在平闆PC中使用的類似鋼筆的輸入裝置,然而,InkCanvas元素同僚也可使用滑鼠進行工作,就像使用手寫筆一樣。是以,使用者可使用滑鼠在InkCanvas元素上繪制線條,或者選擇以及操作InkCanvas中的元素。

  InkCanvas元素實際上包含兩個子内容集合。一個是為人熟知的Children集合,它儲存任意元素,就像Canvas面闆一樣。每個子元素可根據Top、Left、Bottom和Right屬性進行定位。另一個是Strokes結合,它儲存System.Windows.Ink.Stroke對象,該對象表示使用者在InkCanvas元素上繪制的圖形輸入。使用者繪制的每條直線或曲線都變成獨立的Stroke對象。得益于這兩個集合,可使用InkCanvas讓使用者使用存儲在Strokes集合中的筆畫(Stroke)為儲存在Children集合中的内容添加注釋。

  下面的這個示例中包含一副圖檔的InkCanvas元素,這幅圖檔已經使用附加的筆畫注釋過。

<Window x:Class="CanvasLayout.InkCanvasWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="InkCanvasWindow" Height="300" Width="385.714">
    <InkCanvas Name="inkCanvas" Background="LightYellow" EditingMode="Ink">
        <Image Source="背景.jpg" Width="300" Height="240"  Stretch="Fill" InkCanvas.Top="10" InkCanvas.Left="10"></Image>
    </InkCanvas>
</Window>      

   效果圖如下所示:

【WPF學習】第九章 使用Canvas面闆進行基于坐标的布局

  筆畫是在使用者在運作時繪制的。

  根據為InkCanvas.EditingMode屬性設定的值,可以采用截然不同的方式使用InkCanvas元素,下表列出了所有選項:

【WPF學習】第九章 使用Canvas面闆進行基于坐标的布局

   InkCanvas元素會引發多種事件,當編輯模式改變時會引發ActiveEditingModeChanged事件,在GestureOnly或InkAndGesture模式下删除姿勢時會引發Gesture事件,在Select模式下選擇元素或改變元素時會引發SelectionChanging事件、SelectionChanged事件、SelectionMoving事件、SelectionMoved事件、SelectionResizing事件和SelectionResized事件。其中,名稱以"ing"結尾的事件表示動作将要發生,但可以通過設定EventArgs對象的Cancel屬性取消事件。

  後期還會進行更詳細的介紹。

作者:Peter Luo

出處:https://www.cnblogs.com/Peter-Luo/

本文版權歸作者和部落格園共有,歡迎轉載,但必須給出原文連結,并保留此段聲明,否則保留追究法律責任的權利。