2009-05-27 9 views
5

Je crée mon propre UserControl et j'ai deux DataTemplates différents sous la section UserControl.Resources dans mon XAML. Je veux choisir entre ces deux datatemplates en fonction de la valeur d'une propriété sur les objets affichés dans une listview. Je fais cela en créant une classe DataTemplateSelector personnalisée et en remplaçant la méthode SelectTemplate qui est supposée renvoyer le DataTemplate que je souhaite utiliser. Cependant, je n'ai aucune idée comment "trouver" mes datatemplates qui sont situés dans la section de ressource UserControls, tous les exemples que j'ai vus seulement récupèrent des datatemplates de Window.Resources. Dans cet exemple, ils vont chercher le courant MainWindow puis utilisez FindResource pour trouver le DataTemplate, comment puis-je chercher mon UserControl de manière similaire ?:Comment trouver une ressource dans un UserControl à partir d'une classe DataTemplateSelector dans 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'exemple ci-dessus est d'ici : ItemsControl.ItemTemplateSelector Property

Répondre

6

J'instancier habituellement mon DataTemplateSelector de code derrière avec le UserControl comme paramètre dans le constructeur de la DataTemplateSelector, comme ceci:

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(); 
    } 
} 

Pas la plus jolie fille en ville, mais faire le travail;)

Hope this helps!

+1

Est-il impossible de faire la même chose dans XAML? – Joakim

+0

Ok cela fonctionne bien ... Mais ce serait bien de savoir quelle est la manière recommandée de le faire, de préférence en XAML. – Joakim

+0

Tellement vrai .. Je voudrais aussi savoir une manière plus jolie .. mais je ne pense pas que ce problème peut être résolu avec XAML réellement. Vous aurez besoin d'une sorte de référence dans votre code, donc le plus simple est de donner directement;) – 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 seulement!

6

Essayez ceci:

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

A WinRT & solution Windows Phone consiste à déplacer l'arbre visuel jusqu'à ce que le contrôle parent se trouve:

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; 
    } 

La méthode FindParent est basée ici sur la réponse acceptée : How to get a ListView from a ListViewItem?

Questions connexes