WPF學習(14)-效果和視覺化物件
前面學過的形狀,包括Path構建複雜的圖形,當然可以完成我們的需求,可是有一個問題,當我們的內容元素又成百上千的形狀等組合起來的時候,這個會顯得非常讓人不可接受,特別是效能方面,所以自然而然就出現了視覺化物件。
視覺化物件(Visual)這是一個抽象類,所以一般構建例項使用DrawingVisual這個類,特別需要說明的是,DrawingVisual必須提供宿主,不然他是沒有辦法顯示的,而這個宿主必須繼承自UIElement,這個就有很多了,比如Panel等都是他的子類,我們就可以去實現自己的宿主,宿主換句話解釋就是容器,視覺化物件,他是一個物件,要在前臺顯示,就需要一個容器。
比如下面這個類就是我們實現的一個可以裝DrawingVisual物件的容器。
class dwvisual:Panel { private List<Visual> visuals=new List<Visual>(); protected override int VisualChildrenCount { get { // return base.VisualChildrenCount; return visuals.Count; } } protected override Visual GetVisualChild(int index) { // return base.GetVisualChild(index); return visuals[index]; } public void AddVisual(Visual visual) { visuals.Add(visual); base.AddVisualChild(visual); base.AddLogicalChild(visual); } public void DeleteVisual(Visual visual) { visuals.Remove(visual); base.RemoveVisualChild(visual); base.RemoveLogicalChild(visual); } public DrawingVisual GetVisual(Point point) { HitTestResult hitResualt = VisualTreeHelper.HitTest(this, point); return hitResualt.VisualHit as DrawingVisual; } }
裡面有幾個基本的方法和過載的欄位,其實也很好理解,就是加 DrawingVisual,刪DrawingVisual,找DrawingVisual,其中特別需要注意的是VisualChildrenCount和GetVisualChild,裡面有兩行被註釋掉的是VS給我們自動生成的,一定要自己寫完,不然前臺是顯示不了的。
現在前臺就可以放一些物件啦,為了對比,我放一些普通控制元件然後普通形狀對比下視覺化控制元件。
<Grid> <StackPanel> <DockPanel> <Button DockPanel.Dock="Left" Width="50" Content="Button" Click="Button_Click"/> <Button Content="Button" Width="50" Click="Button_Click_1"/> </DockPanel> <local:dwvisual x:Name="cvs" Height="200" ClipToBounds="True" Background="White" Visibility="Visible" ></local:dwvisual> <Canvas Name="cvs2" ></Canvas> </StackPanel> </Grid>
點選按鈕畫圖,效果如下
框框是DrawingVisual物件,線條是普通形狀。後臺程式碼如下
private void Button_Click_1(object sender, RoutedEventArgs e)
{
DrawingVisual visual = new DrawingVisual();
Brush brush = Brushes.LightGoldenrodYellow;
using (DrawingContext dc = visual.RenderOpen())
{
Pen drawingPen = new Pen(Brushes.Red, 3);
dc.DrawRectangle(brush, drawingPen,
new Rect(new Point(100, 100), new Size(50, 50)));
dc.DrawText(new FormattedText("Hello, World!", CultureInfo.CurrentCulture, FlowDirection.LeftToRight, new Typeface("Arial"), 10, Brushes.CornflowerBlue), new Point(0, 0));
}
cvs.AddVisual(visual);
}
private void Button_Click(object sender, RoutedEventArgs e)
{
Line l = new Line();
l.X1 = 20;
l.Y1 = 0;
l.X2 = 100;
l.Y2 = 100;
l.Stroke = Brushes.Red;
l.StrokeThickness = 10;
cvs2.Children.Add(l);
}
對於普通的圖形介面,我覺得還是用形狀繪圖,然後封裝成控制元件使用,在裡面定義依賴屬性,封裝行為,基本已經夠用了,而有大量元素組成的圖形,包括需要數學運算的或者其他複雜需求的,那麼就用視覺化影象,比較效率在那。
接下來就是效果,舉兩個例子,書裡面的。
<Button Content="Button" Width="50" >
<Button.Effect>
<BlurEffect Radius="2"></BlurEffect>
</Button.Effect>
</Button>
<TextBlock>
<TextBlock.Effect>
<DropShadowEffect></DropShadowEffect>
</TextBlock.Effect>
奔騮科技真棒
</TextBlock>
一個是模糊效果,一個是陰影效果,很好理解,調他的引數就可以設定不同的效果了
至於其他更復雜的效果,需要使用高階著色語言去弄了,這個就屬於DirectX的範疇了