2010-05-21 101 views
2

我最近一直在使用WPF生成一個圖表的項目。在這裏,我必須顯示與文字相關的信息旁邊的文字。WPF有效地重新使用Xaml

要繪製符號,我最初使用了我生成的一些png圖像。在我的圖表中,這些圖像模糊不清,放大時只能看起來更糟糕。爲了改善這一點,我決定使用矢量而不是拉斯特圖像格式。下面是我用來從文件路徑獲取拉斯特圖像的方法:

protected Image GetSymbolImage(string symbolPath, int symbolHeight) 
{ 
    Image symbol = new Image(); 
    symbol.Height = symbolHeight; 
    BitmapImage bitmapImage = new BitmapImage(); 
    bitmapImage.BeginInit(); 
    bitmapImage.UriSource = new Uri(symbolPath); 
    bitmapImage.DecodePixelHeight = symbolHeight; 
    bitmapImage.EndInit(); 
    symbol.Source = bitmapImage; 
    return symbol; 
} 

不幸的是,這不能識別矢量圖像格式。所以不是我使用的方法類似下面,其中「路徑」是文件路徑格式的.xaml的矢量圖像:

public static Canvas LoadXamlCanvas(string path) 
{ 
    //if a file exists at the specified path 
    if (File.Exists(path)) 
    { 
     //store the text in the file 
     string text = File.ReadAllText(path);     

     //produce a canvas from the text 
     StringReader stringReader = new StringReader(text); 
     XmlReader xmlReader = XmlReader.Create(stringReader); 
     Canvas c = (Canvas)XamlReader.Load(xmlReader); 

     //return the canvas 
     return c; 
    } 

    return null; 
} 

這個工作,但多次打電話時大幅殺性能。

我發現文本到畫布轉換(見上文)所需的邏輯是性能問題的主要原因,因此嵌入.xaml圖像不會單獨解決性能問題。

我試過只在初始加載時使用這種方法,並將結果畫布存儲在字典中,以後可以更快地訪問,但後來我意識到在字典中使用畫布時我必須製作副本他們。我在網上發現的與製作副本相關的所有邏輯都使用了XamlWriter和XamlReader,這又會引發性能問題。

我使用的解決方案是將每個.xaml圖像的內容複製到它自己的用戶控件中,然後在適當的地方使用這些用戶控件。這意味着我現在顯示矢量圖形和性能要好得多。

但是這個解決方案對我來說似乎很笨拙。我對WPF很陌生,想知道是否有一些內置的方式來存儲和重用整個應用程序中的xaml?

道歉的這個問題的長度。我認爲記錄我的嘗試可能會幫助有類似問題的人。

謝謝。

回答

0

你根本做什麼,當你換你的CanvasUserControl,是創造一個FrameworkTemplate。 A FrameworkTemplate是一個抽象類,在文檔中提到「可以實例化樹的FrameworkElement和/或FrameworkContentElement對象」,這是您真正的目標。

有兩個具體的子類FrameworkTemplateControlTemplateDataTemplate。在XAML中創建UserControl將其Content設置爲用於構造其ControlTemplate,以便每次實例化UserControl時,都會實例化該模板中的所有對象。

您可以改爲創建一個ControlTemplate,然後在創建其他類型的控件時使用它。或者 - 這可能是最好的方法 - 您可以創建DataTemplate

例如,考慮這個XAML:

<DataTemplate TargetType="Symbol"> 
    <Canvas Canvas.Top="{Binding Top}" Canvas.Left="{Binding Left}"> 
     <!-- XAML to construct the symbol goes here --> 
    </Canvas> 
</DataTemplate> 

現在你可以這樣做:

<ItemsControl ItemsSource="{StaticResource SomeCollectionOfSymbolObjects}"> 
    <ItemsControl.ItemsPanel> 
     <ItemsPanelTemplate> 
     <Canvas/> 
     </ItemsPanelTemplate> 
    </ItemsControl.ItemsPanel> 
</ItemsControl> 

這將創建一個Canvas(你的符號)在ItemsControlCanvas爲每Symbol在該集合位於Symbol.TopSymbol.Left屬性所說的位置。

用模板選擇器和Symbol類的適當設計,你可以使用數據綁定來構建整個圖。

編輯

還有的FrameworkTemplate其他子類,除了ControlTemplateDataTemplate。一個出現在這個帖子裏。

0

史蒂夫,

雖然這可能不是回答你的全部問題,或者直接解決您的問題,它可以幫助你以「存儲和再利用XAML」:您可以使用XamlReader動態加載XAML或對象寫入XAMLXamlWriter類。我無法估計你是否真的獲得了性能優勢,但也許值得一試。從MSDN

例子:

// Create the Button. 
Button origianlButton = new Button(); 
origianlButton.Height = 50; 
origianlButton.Width = 100; 
origianlButton.Background = Brushes.AliceBlue; 
origianlButton.Content = "Click Me"; 

// Save the Button to a string. 
string savedButton = XamlWriter.Save(origianlButton); 

// Load the button 
StringReader stringReader = new StringReader(savedButton); 
XmlReader xmlReader = XmlReader.Create(stringReader); 
Button readerLoadButton = (Button)XamlReader.Load(xmlReader); 

問候