2012-10-25 28 views
1

我有一個GUI,它使用樹形視圖將數據對象呈現到行中,包括圖標以表示每行的對象類型等。我注意到,圖標文件添加到每一行減緩了負載和渲染很多,所以我想到了將圖標重寫爲圖紙的想法。香港專業教育學院做了概念的一個檢驗和模仿與以下將WPF中的ICON轉換爲圖紙

<Border Width="15" Height="15" BorderThickness="0" CornerRadius="4,4,4,4" Background="#22bb22" VerticalAlignment="Center"> 
      <Path StrokeThickness="1.5" Stroke="#FFFFFFFF" Data="M 2,4 C 2,4 10,4 9,12 M 2,7 C 2,7 7,7 6,12 M 2,10.5 L 4,10.5"/> 
     </Border> 

圖標不過,我不能看到如何將這個作爲我的XAML的靜態資源。我想一次加載這個圖形,並在整個應用程序中重新使用它,而不必每次重繪。我做了一些與圖像類似的東西,創建一個資源字典,然後讓StaticResourceExtension類通過該字典中的鍵查找高速緩存中的圖像,並將其綁定到圖像標記的源。例如

<Image Source="{y:ImageStaticResource {Binding IconString}}" Margin="0,0,0,0"></Image> 

ImageStaticResource是我的自定義類,並在DataContext的IconString屬性是查找在字典中,返回圖像的位置的字符串的關鍵。這工作和工作得很好。但我想用這些圖畫做一些類似的事情,但無法完全弄清楚。香港專業教育學院創建了一個新的靜態資源擴展,不完全一樣,但加載不同的資源字典,第一個條目這是如下

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"      
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> 

     <Border x:Key="Default" Width="15" Height="15" BorderThickness="0"></Border> 

     <Border x:Key="..\Resources\Images\AccountOnly.ico" Width="15" Height="15" BorderThickness="0" CornerRadius="4,4,4,4" Background="#22bb22" VerticalAlignment="Center"> 
      <Path StrokeThickness="1.5" Stroke="#FFFFFFFF" Data="M 2,4 C 2,4 10,4 9,12 M 2,7 C 2,7 7,7 6,12 M 2,10.5 L 4,10.5"/> 
     </Border> 

    </ResourceDictionary> 

所以我希望能查找此接壤的關鍵圖紙(如所有圖標可以用圖形邊框來表示,但不知道該怎麼辦,有人可以提供建議嗎?

回答

0

您可以通過填充被定義爲資源DrawingBrush的Rectangle控制實現相同的視覺效果:

<Window.Resources> 
    <DrawingBrush x:Key="SomeIcon" Stretch="None"> 
     <DrawingBrush.Drawing> 
      <DrawingGroup> 
       <GeometryDrawing Brush="#22bb22"> 
        <GeometryDrawing.Geometry> 
         <RectangleGeometry Rect="0,0,15,15" RadiusX="4" RadiusY="4"/> 
        </GeometryDrawing.Geometry> 
       </GeometryDrawing> 
       <GeometryDrawing Geometry="M 2,4 C 2,4 10,4 9,12 M 2,7 C 2,7 7,7 6,12 M 2,10.5 L 4,10.5"> 
        <GeometryDrawing.Pen> 
         <Pen Brush="#FFFFFFFF" Thickness="1.5"/> 
        </GeometryDrawing.Pen> 
       </GeometryDrawing> 
      </DrawingGroup> 
     </DrawingBrush.Drawing> 
    </DrawingBrush> 
</Window.Resources> 

... 

<Rectangle Width="15" Height="15" Fill="{StaticResource SomeIcon}"/> 
+0

這會比Path方法密集得多嗎?我原來選擇非幾何方法來保持它的輕量級,因爲一次可以在treeview控件中顯示多達5000個這樣的圖標。我也玩弄了將它作爲數據模板的想法,但不太清楚可以使用哪個父級UI控件來設置數據模板。我試過按鈕,但是我只能設置contenttemplate,因爲你得到圍繞它的按鈕。 – NZJames

+0

恰恰相反。與每個圖標使用一個Border控件的方法相比,這樣做的資源密集程度要低得多。與Border控件相比,DrawingBrush是輕量級的。事實上,這是我能想到的最輕量級的解決方案,除了可能的位圖。 – Clemens

0

要將位於資源中的邊框「置於」可視化樹中的某個位置....使用ContentControl,或ContentPresenter ...並引用您的密鑰資源。

<ContentControl Content="{StaticResource Default}"/> 

<ContentControl Content="{StaticResource ..\Resources\Images\AccountOnly.ico}"/> 

(注意:您已經在第二邊框使用的密鑰名字有點標新立異)

但是,你會碰到一個問題,這樣做,一旦你嘗試使用邊框更比一次,即「指定的元素已經是另一個元素的邏輯子元素」。

您可以用x:Shared="False"標記資源,以便爲每個引用創建一個新實例...但是您可能會回到原點,即無效的渲染。

你也可以考慮創建你自己的FrameworkElement派生類,專門定製渲染你的「圖標」所需的最低限度,並優化任何共享數據。

如果可能的話,儘量避免使用較重的「Control」派生類,如果不需要模板的靈活性。

+0

我也許可以利用這一點。我考慮將整個邊框結構放在數據模板中,將所有數據模板放入資源字典中,使用StaticResourceExtension類將某個UI對象的Template屬性動態綁定到匹配鏈接到依賴項屬性的模板上數據對象。我嘗試了這一點,它的工作原理,但我只嘗試過使用按鈕UI對象,設置ContentTemplate,只是把圖形放在一個按鈕。什麼是我可以用來綁定模板的輕量級UI控件? – NZJames