2009-11-02 2 views
10

Wenn Wandler in einer WPF-Anwendung zu erklären, sollte ich:Sollte ich Konverter in App.xaml oder als eine Datei pro Datei deklarieren?

  1. Deklarieren alle meine Wandler im App.xaml (dh in <Application.Resources/>), so ist es
  2. auf die gesamte Anwendung zur Verfügung
  3. Deklarieren nur benötigt Konverter für jedes Page/Window/ResourceDictionary/UserControl usw. in ihrem Resources Abschnitt
  4. etwas völlig andere

In Bezug auf die Lesbarkeit scheint mir Methode 1 das Beste zu sein, aber meine Frage betrifft die Leistung. Welche Methode ist in Bezug auf Leistung, Speicher usw. am effizientesten?

Antwort

37

Nun, ich deklariere sie einfach nicht in XAML. Stattdessen erhalte ich zusätzlich einen Konverter von mir aus MarkupExtension. Wie folgt aus:

public class MyValueConverter : MarkupExtension, IValueConverter 
{ 
    private static MyValueConverter _converter = null; 
    public override object ProvideValue(IServiceProvider serviceProvider) 
    { 
     if (_converter == null) _converter = new MyValueConverter();  
     return _converter; 
    } 

    public object Convert 
    (object value, Type targetType, object parameter, CultureInfo culture) { } 
    public object ConvertBack 
    (object value, Type targetType, object parameter, CultureInfo culture) { } 
} 

Dies ermöglicht es mir meine Konverter überall zu verwenden, wie folgt aus:

Source="{Binding myValue, Converter={converters:MyValueConverter}}" 

wo Konverter ist der Namensraum, in dem ich meine Konverter erklärt.

Dieser Trick wurde nur von einem alten Stapelüberlauf-Thread gelernt.

+2

Ich habe gerade etwas gelernt, sicher wird es nützlich sein! – Shimmy

+2

Und ja, das ist besser in Bezug auf die Leistung, da es nicht jedes Mal, wenn der Konverter benutzt wird, ein neues Objekt instanziiert. Es erstellt nur eine Instanz vor der Rückgabe des ersten Aufrufs der MarkupExtension und gibt jedes Mal dieselbe Instanz zurück. – Yogesh

+0

Danke! Dies erleichtert das Leben. – si618

0

Wenn Sie nur einen Konverter für das eine Fenster benötigen, würde ich es für das eine Fenster (oder sogar nur für das Container-Steuerelement, das das Steuerelement enthält, das es verwendet).

Ich würde argumentieren, dass dies wartungsfreundlicher ist - Sie können die Converter-Deklaration betrachten und in der Lage zu sagen, was es verwendet. Sie wissen, dass wenn Sie die Steuerelemente auf dieser bestimmten Seite ändern, um den Konverter nicht mehr zu verwenden, können Sie es aus den Ressourcen der Seite entfernen, ohne dass irgendetwas anderes beeinflusst wird. Umgekehrt, wenn ein Konverter eine Anwendungsressource ist, ist es nicht so einfach zu bestimmen, was es verwendet, wenn überhaupt.

Wenn der gleiche Konverter von mehr als einer Seite verwendet wird, würde ich noch setzen Sie es unter jeder Seite Ressource. Wirklich, es ist nur eine zusätzliche Zeile im XAML.

Wie auch immer, das ist meine Meinung, ab heute. Ich erwarte einen anderen Beitrag, der genau das Gegenteil behauptet. :-)

+0

Kein solches Glück. Meine Antwort war halb umgekehrt, halb gleich :-P – devuxer

2

Ich habe ein ResourceDictionary, das mehrere häufig benötigte Konverter deklariert, z. B. einen Bool-to-Visibility-Konverter. Ich referenziere dieses Wörterbuch direkt in App.xaml.

Ich erkläre andere Konverter, die für eine bestimmte Situation spezifischer sind, auf der Page/Window-Ebene (oder in einem ResourceDictionary, auf das eine Seite/ein Fenster verweist).

Ich kann die Leistungsfrage definitiv nicht beantworten, aber ich würde sehr überrascht sein, wenn es einen praktischen Unterschied in Ladezeit oder Speichernutzung machen würde. Das Deklarieren eines Konverters ist im Grunde eine Objektinstanziierung, also sollte es sehr effizient sein und sehr wenig Speicher verwenden, aber ich habe kein Profiling durchgeführt, um die Leistung auf App- und Fensterebene zu vergleichen.

+0

Nun, das war meine Frage ... Wenn Sie jemals die Performance-Antwort wissen, vergessen Sie bitte nicht, wieder zu kommen. – Shimmy