2009-05-27 9 views
5

Sto creando il mio UserControl e ho due DataTemplates diversi nella sezione UserControl.Resources nel mio XAML. Voglio scegliere tra questi due datatemplates in base al valore di una proprietà sugli oggetti visualizzati in un listview. Lo faccio creando una classe personalizzata DataTemplateSelector e sovrascrivendo il metodo SelectTemplate che dovrebbe restituire il DataTemplate che desidero utilizzare. Tuttavia, non ho idea di come "trovare" i miei datatemplates che si trovano nella sezione di risorse UserControls, tutti gli esempi che ho visto recuperano solo datatemplates da Window.Resources. In questo esempio, essi recuperano la corrente MainWindow e quindi utilizzare FindResource per trovare la DataTemplate, come faccio Prendi il mio UserControl in un modo simile ?:Come trovare una risorsa in un UserControl da una classe DataTemplateSelector in WPF?


public override DataTemplate 
      SelectTemplate(object item, DependencyObject container) 
     { 
      if (item != null && item is AuctionItem) 
      { 
       AuctionItem auctionItem = item as AuctionItem; 
       Window window = Application.Current.MainWindow; 

       switch (auctionItem.SpecialFeatures) 
       { 
        case SpecialFeatures.None: 
         return 
          window.FindResource("AuctionItem_None") 
          as DataTemplate; 
        case SpecialFeatures.Color: 
         return 
          window.FindResource("AuctionItem_Color") 
          as DataTemplate; 
       } 
      } 

      return null; 
     } 

L'esempio di cui sopra è da qui : ItemsControl.ItemTemplateSelector Property

risposta

6

solito un'istanza di mia DataTemplateSelector dal codice dietro l'UserControl come parametro nel costruttore della DataTemplateSelector, in questo modo:

public class MyUserControl : UserControl 
{ 
    public MyUserControl() 
    { 
     Resources["MyDataTemplateSelector"] = new MyDataTemplateSelector(this); 
     InitializeComponent(); 
    } 
} 

public class MyDataTemplateSelector : DataTemplateSelector 
{ 
    private MyUserControl parent; 
    public MyDataTemplateSelector(MyUserControl parent) 
    { 
     this.parent = parent; 
    } 

    public override DataTemplate SelectTemplate(object item, DependencyObject container) 
    { 
     parent.DoStuff(); 
    } 
} 

non la più bella ragazza più in città, ma ottenere il lavoro fatto;)

Spero che questo aiuti! solo

+1

Non c'è modo di fare la stessa cosa in XAML? – Joakim

+0

Ok questo funziona bene ... Ma sarebbe bello sapere qual è il modo consigliato per farlo, preferibilmente facendo tutto in XAML. – Joakim

+0

Così vero .. Anch'io vorrei conoscere un modo più carino .. ma non penso che questo problema possa essere risolto con XAML. Avrai bisogno di un qualche tipo di riferimento nel tuo codice, quindi il modo più semplice è quello di darti direttamente;) – Arcturus

2
 <DataTemplate x:Key="addTemplate"> 
     <Button Command="{Binding Path=AddCommand}">Add</Button> 
    </DataTemplate> 

    <DataTemplate x:Key="editTemplate"> 
     <Button Command="{Binding Path=UpdateCommand}">Update</Button> 
    </DataTemplate> 

    <TemplateSelectors:AddEditTemplateSelector 
     AddTemplate="{StaticResource addTemplate}" 
     EditTemplate="{StaticResource editTemplate}" 
     x:Key="addEditTemplateSelector" /> 

XAML!

6

Prova questo:

public override DataTemplate SelectTemplate(object item, DependencyObject container) 
    { 
     if (item != null && item is AuctionItem) 
     { 
      AuctionItem auctionItem = item as AuctionItem; 

      switch (auctionItem.SpecialFeatures) 
      { 
       case SpecialFeatures.None: 
        return 
         ((FrameworkElement)container).FindResource("AuctionItem_None") 
         as DataTemplate; 
       case SpecialFeatures.Color: 
        return 
         ((FrameworkElement)container).FindResource("AuctionItem_Color") 
         as DataTemplate; 
      } 
     } 

     return null; 
    } 
0

Una WinRT & soluzione Windows Phone coinvolge in movimento fino ad albero visuale fino a quando il controllo padre si trova:

protected override Windows.UI.Xaml.DataTemplate SelectTemplateCore(object item, Windows.UI.Xaml.DependencyObject container) 
    { 
     var parent = FindParent<MyParentControlType>(container as FrameworkElement); 

     if(parent != null) 
     { 
      if (item is Something) 
       return parent.Resources["TemplateForSomething"] as DataTemplate; 
      else if(item is SomethingElse) 
       return parent.Resources["TemplateForSomethingElse"] as DataTemplate; 
      else 
       // etc 
     } 
     else 
     { 
      return App.Current.Resources["SomeFallbackResource"] as DataTemplate; 
     } 
    } 

    public static T FindParent<T>(FrameworkElement element) where T : FrameworkElement 
    { 
     FrameworkElement parent = Windows.UI.Xaml.Media.VisualTreeHelper.GetParent(element) as FrameworkElement; 

     while (parent != null) 
     { 
      T correctlyTyped = parent as T; 

      if (correctlyTyped != null) 
       return correctlyTyped; 
      else 
       return FindParent<T>(parent); 
     } 

     return null; 
    } 

Il metodo FindParent si basa sulla risposta accettata qui : How to get a ListView from a ListViewItem?

Problemi correlati