9

Bir ViewModel içindeki type özelliğine dayalı bir editör görüntüleyen genel bir kontrolüm var. DataTemplateSelector olduğu kullanarak, DataTrigger Vs. ile ControlTemplate. DataTemplateSelector ile DataTemplate

<local:EditorTemplateSelector 
    BoolEditorTemplate="{StaticResource boolTemplate}" 
    TextEditorTemplate="{StaticResource textTemplate}" 
    IntegerEditorTemplate="{StaticResource integerTemplate}" 
    ... 
    .... 
    x:Key="EditorTemplateSelector"> 
</local:EditorTemplateSelector> 

<ContentPresenter 
    ContentTemplateSelector="{Binding Source={StaticResource EditorTemplateSelector}}" 
    Content="{Binding}" 
    TargetUpdated="OnTargetUpdated"> 
</ContentPresenter> 

// Template selector returning appropriate template based on type 

Ben ikinci yaklaşım hissediyorum - Aynı böyle ContentPresenter, DataTemplate ve DataTemplateSelector kullanılarak elde edilebilir, Şimdi

<Control 
    x:Name="MainControl" 
    Grid.Column="1" 
    TargetUpdated="OnTargetUpdated"> 
     <Control.Style> 
      <Style> 
       <Style.Triggers> 
        <DataTrigger 
         Binding="{Binding Path=EditorType}" 
         Value="{x:Static view:EditorType.Bool}"> 
         <Setter 
          Property="Control.Template" 
          Value="{StaticResource boolTemplate}" /> 
        </DataTrigger> 
        <DataTrigger 
         Binding="{Binding Path=EditorType}" 
         Value="{x:Static view:EditorType.Text}"> 
         <Setter 
          Property="Control.Template" 
          Value="{StaticResource textTemplate}" /> 
        </DataTrigger> 
        <DataTrigger 
         Binding="{Binding Path=EditorType}" 
         Value="{x:Static view:EditorType.Integer}"> 
         <Setter 
          Property="Control.Template" 
          Value="{StaticResource integerTemplate}" /> 
        </DataTrigger> 
        ... 
        .... 
       </Style.Triggers> 
      </Style> 
    </Control.Style> 
</Control> 

- Şu anda böyle Control, ControlTemplate ve DataTrigger kullanılarak uygulanır oluyor daha iyi ama sizden bilmek istersiniz -

  • Hangisi daha iyi ve neden?

  • İkide herhangi bir performans farkı olacak mı?

+0

Topladığımdan, ikinci yol en iyi uygulama olarak kabul edilir. Ayrıca seçim mantığını (her zaman C# olarak tanımlanmalıdır) tutmadığı için çok daha okunabilir. Ancak performans noktasında da ilgileniyorum. –

cevap

9

Ben değeri onlar değişikliklere göre eğer DataTemplateSelectors şablonu güncellemek yoktur ve bu nedenle genellikle bunları kullanmayın duydum.

Tercih ettiğim yöntem aslında DataTemplates'leri kullanmaktır. Ben bir özellik yerine nesne türüne göre şablonunu değiştirmek isterseniz

<MyControl.Resources> 
    <DataTemplate TargetType="{x:Type local:BooleanModel}"> 
     <local:BooleanView /> 
    </DataTemplate> 
    <DataTemplate TargetType="{x:Type local:IntegerModel}"> 
     <local:IntegerView /> 
    </DataTemplate> 
    ... 
</MyControl.Resources> 

İkincisi, ben DataTriggers kullanma eğilimindedir. Bunun nedeni, eğer bu özellik hiç değişmezse, PropertyChange bildirimi otomatik olarak UI'ye değiştiğini ve şablonu güncellemesini söyleyecektir. DataTemplateSelectors'un bunu otomatik olarak yaptığına inanmıyorum. Ayrıca, XAML'de şablon seçim mantığını görmeyi, bir TemplateSelector dosyasında saklamamayı tercih ediyorum, ancak bu sadece kişisel tercihtir.

Son seçimim DataTemplateSelector kullanmaktır. Bir WPF uygulamasında neredeyse hiç kullanmıyorum, sık sık Silverlight'ta kullandığım tercih edilen yöntemi kullanmamasına rağmen, örtük DataTemplates (henüz)

Her ikisi arasında önemli bir performans farkının farkında değilim. Biri bana başka türlü söyleyebilirse ilgilenirim.

+0

İlginç, WPF ile ilgili soruların neredeyse tamamen merak ettiğimden eminim. SL4/5'deki örtük şablonları düzelttiklerinden, önceki sürümlerde bulunmadıklarını biliyorum. –

+0

@Dmitry Yaptığım son Silverlight projesinin 4.0'da olduğuna inanıyorum ve örtülü DataTemplates o zaman işe yaramadı. 5.0'da çalıştıklarını duydum, ama henüz yapmadım. 'DataTemplateSelectors' için – Rachel

+0

+1, değiştikleri değere dayanıyorsa şablonu güncelleştirmez '. Bunu kontrol ettim ve değer değişirse şablon güncellenmez. Teşekkürler. – akjoshi

3

Burada iki soru :) XAML (DataTriggers) bir decsion yapmak

  1. veya kod TemplateSelector Eğer bütün Style ya da sadece DataTemplate geçersiz kılma Ne
  2. yılında ettik. İlk örneğinizde, ikinci bir - DataTemplate - Style'u geçersiz kılarsınız.

Here're benim 2c:

onlarla yenilmez bir esneklik seviyesini alırsınız gibi ben Tetikleyiciler ile sopa - yeni kaynağın fiyatı ve tetikleyici tüm yeni düzenleyici XAML - daha iyi ne olabilir? DataTrigger kullanımıyla ilgili bir potansiyel uyarı var - veri sızıntılarına neden olabilir.

Style ile ilgili DataTemplate numaralı telefonu kullanıyorum Style numaralı telefonu tekrar kullanıyorum. Biraz daha agir görsel agaci olabilir, ama editörlerin açilmasi üzerinde size en üst düzey kontrolü saglar. Özellikle, bazı özellikler sadece Style düzeyinde, StyleSetters 's kullanılarak tanımlanabilir. DataTemplate seviyesinin tanımlanması, DataTemplate içeriğinizin kontrol kabınızın hemen bir çocuğu olmadığı için çalışmayacaktır (ekstra bir seviye var - actula Kontrolü). Bu tür özellikleriniz yoksa, ControlTemplates da iyi ve muhtemelen daha hızlıdır (?).

+0

Teşekkürler Dmitry, 'DataTrigger hakkında daha fazla bilgi verebilir misiniz veri sızmasına neden oluyor '? – akjoshi

+0

@akjoshi - Maalesef tam bir repro ile gelemeyeceğim, bu bir gözlem niteliğinde, tetikleyicilerin sayısını azalttıktan sonra ciddi fayda sağlayan birkaç proje gördüm. –

0

Cevabın daha fazla olması gerektiğini düşündüğünüzden biri control gereklidir. control ile bir DataTemplate gerçekten kullanışlı olmayan bir sürü işlevsellik elde edersiniz. DependencyProperties, events, functions vb. Ekleyebilirsiniz. Fakat buna ihtiyacınız var mı? Eğer yapmazsanız, bir kontrol aşırı olabilir.

İlgili konular