程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> 關於.NET >> 《Programming WPF》翻譯 第7章 5.可視化層編程

《Programming WPF》翻譯 第7章 5.可視化層編程

編輯:關於.NET

形狀元素能提供一種便利的方式與圖形一起工作,在一些情形中,添加表示繪圖的元素到UI樹中,可 能是比它的價值更加麻煩。你的數據可能被構造以一種易於編寫代碼的方式——簡單地表現一系列基於數 據的繪圖操作,而不是構造一棵對象樹。

WPF提供一個“可視化層”API,作為一個對形狀元素較低級別的折中。(實際上,形狀元素全都在可 視化層得頂部被實現。)這個API使我們編寫按需生成的代碼。

可視化是一個可見的對象。WPF應用程序的外觀是將它所有的可視化組合到屏幕上形成的。由於WPF生 成在在可視化層的頂級,每個元素都是可視化的。FrameworkElement基類間接派生於Visual。在可視化層 編程,簡單地解決了創建一個可視化和編寫代碼告訴WPF我們想要在可視化中顯示什麼。

即使在這個低的級別,WPF的表現非常不同於Win32。圖形加速的方式是托管的,這意味著你的按需生 成的代碼很少被調用——少於在經典Windows應用程序中。

7.5.1 按需生成

按需生成的關鍵定制為OnRender方法。這個方法被WPF調用在它需要你的組件生成它的外觀時。(這是 內嵌形狀的類生成它們自身的方式。)

OnRender虛方法定義在OnDemandVisual類。大多數元素都間接的通過FrameworkElement派生於此,這 就增加了核心樣式如外觀和輸入處理。

示例7-47顯示了一個字定義的元素,覆寫了OnRender。

示例7-47

public class CustomRender : FrameworkElement
{
    protected override void OnRender(DrawingContext drawingContext)
    {
        Debug.WriteLine("OnRender");

        base.OnRender (drawingContext);

        drawingContext.DrawRectangle(Brushes.Red, null, new Rect(0, 0, 100, 50));

        FormattedText text = new FormattedText("Hello, world",
            CultureInfo.CurrentUICulture, FlowDirection.LeftToRightThenTopToBottom,
            new Typeface("Verdana"), 24, Brushes.Black);
        drawingContext.DrawText(text, new Point(3, 3));
    }

}

OnRender方法傳遞了一個單獨的DrawingContext類型的參數。這是一個WPF中低級別的繪圖API。它提 供了一組基礎繪圖操作,這些都在表7-4中列出。示例7-47使用了DrawRectangle和DrawText方法。

注意到DrawingContext使用了Brush和Pen類來指出形狀是如何填充和畫輪廓的,正如我們之前看到的 高級別形狀對象。我們還可以傳遞同樣的Geometry和Drawing對象——也是在本章前面看到的。

Table 7-4. DrawingContext drawing operations

Operation Usage DrawDrawing Draws a Drawing object. DrawEllipse Draws an ellipse. DrawGeometry Draws any Geometry object. DrawGlyphRun Draws a series of glyphs (i.e., text elements) offering detailed control over typography. DrawImage Draws a bitmap image. DrawLine Draws a line (a single segment). DrawRectangle Draws a rectangle. DrawRoundedRectangle Draws a rectangle with rounded corners. DrawText Draws text. DrawVideo Draws a rectangular region that can display video. PushTransform Sets a transform that will be applied to all subsequent drawing operations until Pop is called; if a transform is already in place, the net effect will be the combination of all the transforms currently pushed. PushClip Sets a clip region that will be applied to all subsequent drawing operations until Pop is called; as with PushTransform, multiple active clip regions will combine.

 

PushOpacity

因為我們的自定義元素派生於FrameworkElement,它自然地集成到任何WPF應用程序中。示例7-48為一 個窗體的標記,其中包含了自定義元素,我們可以使用它就像我們之前使用的任何自定義元素。這個窗體 如圖7-56所示。

示例7-48

<?Mapping XmlNamespace="controls" ClrNamespace="VisualRender" ?>
<Window x:Class="VisualRender.Window1"
    xmlns="http://schemas.microsoft.com/winfx/avalon/2005"
    xmlns:x="http://schemas.microsoft.com/winfx/xaml/2005"
    xmlns:cc="controls"
    Text="Visual Layer Rendering"
    >
    <Canvas>
        <cc:CustomRender Canvas.Top="10" Canvas.Left="10" x:Name="customRender" />
    </Canvas>
</Window>

圖7-56

注意到,示例7-47中的OnRender方法調用了Debug.WriteLine。如果程序運行在VS2008調試器的內部, 這將在每次調用OnRender方法的時候,打印出一條消息到“輸出”窗體。這支持我們看到WPF如何經常要 求我們的自定義可視化來生成它自身。如果你習慣於如何在在標准Win32和Windows Forms中的按需繪制下 工作,你可能希望看到這被規則地調用——無論窗體重新調整大小還是部分模糊或隱藏。實際上,它只會 被調用一次。

結果是按需生成並不相似於Win32的舊有樣式生成,正如你可能想到的。WPF會調用你的OnRender方法 當它需要知道你的可視化顯示什麼內容,但是圖形加速的工作方式意味著這種情況的發生遠遠少於Win32 中等價的重畫。WPF緩存了生成指令。這種緩存的范圍和形式並沒有文本化,但是它清晰的發生了。進一 步而言,這比簡單的基於圖像的緩存要微妙的多。我們可以添加這些代碼到示例7-48的宿主窗體(在後台 代碼文件中可能是這樣的)。

 protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)
 {

         VisualOperations.SetTransform(CustomRender, new ScaleTransform (6, 6));
 }

先前的片斷應用了轉換到我們的元素,以因數6放大。當點擊用戶界面時,自定義可視化會如你想希望 的方式延伸,而且OnRender並沒有被調用。不僅如此,放大的可視化並沒有顯示任何你可以看到的像素化 或模糊化的人造物,通過一個簡單的圖像縮放。它繼續是銳利的,正如你在圖7-57看到的。

圖7-57

這指出了WPF獲取關於可視化內容的縮放信息。它能重繪我們的可視化的屏幕外觀,而不使用我們的 OnRender方法,即使當轉換有所改變。這在局部上取決於加速構架,而且同樣因為轉換支持在大多數基礎 的級別生成在WPF中。

WPF重繪的能力——不使用OnRender,允許用戶界面在屏幕上保持完整,即使我們的應用程序很繁忙。 它同樣支持動畫系統工作而不用很多來自應用程序的干擾,因為所有的基礎繪制操作都被保留了,WPF可 以重建任何部分的UI——當獨立的元素改變的時候。

如果我們對象的狀態必須在某種程度上改變——需要更新外觀,我們可以調用InvalidateVisual方法 。這將導致WPF調用我們的OnRender方法,允許我們重建外觀。

注意到,當你重寫OnRender的時候,你還應該典型地覆寫MeasureOverrid和ArrangeOverride方法。否 則,WPF的外觀系統不會知道你的元素有多大。我們得到的唯一原因,而不用在這裡這麼做,是我們在 Canvas上使用該元素,這將不會關心它的子元素有多大。為了在其它的面板上工作,這是實質的讓外觀系 統知道你的大小。第二章描述了MeasureOverrid和ArrangeOverride方法。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved