2010-05-21 7 views
2

저는 최근 WPF를 사용하여 다이어그램을 생성하는 프로젝트에서 작업 해 왔습니다. 여기에서는 텍스트와 관련된 정보를 나타내는 기호와 함께 텍스트를 표시해야합니다.WPF Reason 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; 
} 

불행하게도이 벡터 이미지 포맷을 인식하지 않습니다 아래는 내가 파일 경로에서 rastor 이미지를 얻기 위해 사용되는 방법이다. 그래서 그 대신 내가 "경로"형식 .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

. FrameworkTemplate은 실제 클래스 인 FrameworkElement 및/또는 FrameworkContentElement 개체의 트리를 인스턴스화 할 수있는 문서라는 추상 클래스입니다.

두 개의 구체적인 서브 클래스 FrameworkTemplate : ControlTemplateDataTemplate이 있습니다. XAML에 UserControl을 만들면 Content이 설정되어 ControlTemplate을 구성하므로 UserControl을 인스턴스화 할 때마다 해당 템플릿의 모든 개체가 인스턴스화됩니다.

대신 ControlTemplate을 만들고 다른 종류의 컨트롤을 만들 때 사용할 수 있습니다. 또는 - 아마도 이것이 최선의 방법 일 것입니다. DataTemplate을 만들 수 있습니다.

<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에 대한

예를 들어,이 XAML을 고려 컬렉션에 위치해야합니다. 위치는 Symbol.TopSymbol.Left입니다.

템플릿 선택자와 적절한 디자인을 사용하여 Symbol 클래스의 적절한 디자인을 사용하면 데이터 바인딩을 사용하여 다이어그램 전체를 구성 할 수 있습니다.

편집

ControlTemplateDataTemplate 외에 FrameworkTemplate의 다른 서브 클래스가 있습니다. 하나는 바로이 게시물에 나타납니다.

0

스티브,

, 그것은 "저장 및 XAML을 재사용"당신을 도울 수 있습니다 당신은 동적으로 XamlReader를 사용하여 XAML 개체를 XAML을로드하거나 쓸 수 있습니다XamlWriter 클래스. 실제로 성능 이점을 얻을 수 있을지는 예측할 수 없지만 시도해 볼 가치는있을 것입니다. MSDN에서

예 : 당신은 당신이 UserControl에서 Canvas하는 FrameworkTemplate을 만드는 포장은 근본적으로 무슨 일을하는지

// 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); 

안부