下圖來自 <<Wpf控件開發>>express
DispatcherObject 類緩存
- 位於System.Windows.Threading 名字空間中
- 爲WPF 的全部對象提供了基本的消息與多線程支持
- 主要須要關注其Dispatcher 屬性,它容許你訪問對象相關的Dispatcher(調度者,譯註:與多線程訪問相關)。顧名思義,該類所引入的調度系統負責監聽各類消息,在界面所在的線程中將消息發送給相應的對象
DependencyObject 類markdown
- 用於支持WPF 中的依賴屬性系統,依賴屬性系統的主要用途是計算屬性的值,在屬性值改變時,該系統負責提供通知.
- WPF 依賴屬性系統與標準屬性的主要區別是依賴屬性能夠經過數據綁定與其它屬性相關聯;同時當因爲各類緣由使得屬性值須要發生變化時,依賴屬性會自動重算。
- 爲了實現上述功能,須要爲每一個依賴屬性維護各自的**元數據(metadata)**以及相應的處理邏輯。
- DependencyObject 同時支持附加屬性與屬性繼承。
Visual 與DrawingVisual 類
System.Windows.Media.Visual 是個抽象類,它是WPF 中全部繪圖相關活動的樞紐。WPF 中,全部具備可視性質的類都直接或間接地繼承自Visual 類。這個類提供了顯示所需的基本服務,如渲染,緩存繪製命令,變換,裁剪,固然也包括了邊框設置與命中測試(HitTest)
操做。
雖然Visual 類中包含了大量實用的功能,但咱們通常不直接使用該類,而是使用其間接子類DrawingVisual.DrawingVisual 繼承自ContainerVisual。ContainerVisual 用於包含可視對象的集合。集合中的子元素經過Drawing 屬性(DrawingGroup 類型)設置顯示內容。
DrawingVisual 是個輕量級類,僅用於低級渲染,不涉及高級內容(如佈局、事件、數據綁定等).若是你的任務僅限於繪製圖形,而所涉及的交互也僅限於命中測試,則你能夠用DrawingVisual 完成任務,不須要使用更復雜的類,花費更多成本。
使用DrawingVisual 的典型例子是圖表程序。經過繪製基礎元素:如線條、貝塞爾曲線、弧、文本等,以後使用實心或漸變畫刷填充其內部。你就能夠創建各類圖表了。網絡
FrameworkElement 類
System.Windows.FrameworkElement類繼承自UIElement。UIElement提供了一些核心服務,如佈局、事件、以及用戶輸入等.
雖然UIElement是公有的,但通常來講,不會從UIElement類派生,而是從FrameworkElement類派生,由於這個類提供了用戶須要的服務如 佈局、樣式、觸發器、數據綁定,同時在這個類中,能夠自定義這些服務。
FrameworkElement同時是個輕量級的容器,包含可視元素集合.因爲它繼承自UIElement,所以它能被加到邏輯樹中,做爲容器包含更基礎的視覺元素.
能夠用以下方式使用FrameworkElement:多線程
- 重載其OnRender方法,在該方法內部引入簡單的數據可視化呈現代碼;
- 定義其內部的視覺樹,用這種方法使用FrameworkElement時,實際是將其當作了容器;
- 在其中包含自定義的佈局邏輯,設置包含元素的大小與位置
- 將上述的幾種方式組合使用;
DispatcherObject,DependencyObject,Visual,UIElement 以及FrameworkElement,它們放在一塊兒被稱爲脊 柱(Spine)。
using System.Windows; using System.Windows.Media; namespace Demo.Visual { public class SectorVisual:DrawingVisual { public SectorVisual() { StreamGeometry geometry = new StreamGeometry(); using (StreamGeometryContext c = geometry.Open()) { c.BeginFigure(new Point(200, 200), true, true); c.LineTo(new Point(175, 50), true, true); c.ArcTo(new Point(20, 150), new Size(1, 1), 0, true, SweepDirection.Counterclockwise, true, true); c.LineTo(new Point(200, 200), true, true); } using (DrawingContext context = RenderOpen()) { Pen pen = new Pen(Brushes.Black, 1); context.DrawGeometry(Brushes.CornflowerBlue, pen, geometry); } } } }
using System.Windows; namespace Demo.Visual { public class VisualContainer:FrameworkElement { private readonly SectorVisual _visual = new SectorVisual(); protected override System.Windows.Media.Visual GetVisualChild(int index) { return _visual; } protected override int VisualChildrenCount => 1; } }
<Window x:Class="Demo.Visual.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:Demo.Visual" mc:Ignorable="d" Title="MainWindow" Height="450" Width="800"> <local:VisualContainer/> </Window>
效果圖:
ide
須要指出的是,因爲VisualContainer類中沒有涉及任何自定義的佈局,所以這個類也能夠從UIElement中繼承,而不須要從FrameworkElement中繼承。FrameworkElement更適合於須要自定義元素大小、位置、數據綁定,以及樣式的情形。
Shape 類
Shape類提供了比DrawingVisual更高級的抽象,在Shape類中,你無需使用基本的DrawingContext繪製圖形;取而代之的,咱們使用幾何圖形(geometry)這個概念肯定要繪製的內容。
當創建自定義Shape時,開發者要使用Shape類中的DefiningGeometry屬性定義原始形狀。使用形狀以及該類中的一些其它信息,如筆劃樣式(stroke),筆劃線條粗細(Stroke Thickness),以及填充(fill),就能夠決定如何對其進行渲染。
Shape類繼承自FrameworkElement(FrameworkElement是大多數容器類——如Panel類——的基類),這就使得Shape類的實例能夠參與佈局,同時使其更容易進行事件處理。Shape類同時定義了伸縮屬性(Stretch Property),用於定義在Shape對象的尺寸改變時,其內部的幾何圖形如何相應地變形。佈局
Control 類
在視覺相關類所組成的繼承關係樹中,Control類已經接近樹的頂端了。它提供了一個強大的Template屬性(ControlTemplate類型),用於改變控件的外觀與用戶體驗測試
Image 類
Image 類繼承自FrameworkElement,所以它能夠被加入到邏輯樹中,同時提供了豐富的事件處理接口與佈局支持。它包含Source 屬性,能夠設定爲ImageSource 對象的實例,Image 依據這個實例進行渲染。ImageSource 類能夠表示一個矢量圖(DrawingImage 從ImageSource 派生,用於繪製矢量圖);也能夠表示一個柵格圖或位圖(BitmapSource 從ImageSource 派生,用於表示位圖)。
當須要顯示大量的數據,而顯示結果與用戶的交互頗有限時,Image 可能會頗有用。這些狀況包括:要顯示大批的圖形,或者在網絡監控程序中顯示成千上萬的網絡結點。在這樣的狀況下,即便用rawingVisual 繪製複雜度都會很是高。由於採用DrawingVisual 繪製時,每一個條目均是單獨的可視元素,須要單獨處理,所以會耗費大量的CPU 與內存資源。若是數據點根本不須要交互,那麼你就能夠利用圖像進行顯示,無須要佔用計算機主要的資源。
spa