Posto qui la risposta al post di Igor cosicchè possa essere utile anche ad altri…
Problema: Volendo definire un DataTemplateSelector e relativi DataTemplates in una class library, come risalgo ai DataTemplates definiti nel ResourceDictionary contenuto nella stessa assembly?.
Quando si usa XAML spesso ci si dimentica che si ha a che fare con una classe parziale e che quindi è possibile aggiungere del codice semplicemente usando la direttiva x:Class, questo significa che riscrivendo il classico ResourceDictionary in questo modo:

MyRd.xaml

<ResourceDictionary
    x:Class="WpfLib.MyRd"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" >
  <DataTemplate x:Key="InternetTemplate">
    <StackPanel Orientation="Horizontal">
      <Image Margin="4" Source="Images\InternetTagLogo.png" />
      <Label VerticalContentAlignment="Center" 
             Content="{Binding Path=Identifier}" FontSize="10pt"
             Padding="4" Width="110">
      </Label>
    </StackPanel>
  </DataTemplate>

  <DataTemplate x:Key="LocalTemplate">
    <StackPanel Orientation="Horizontal">
      <Image Margin="4" Source="Images\LocalTagLogo.png" />
      <Label VerticalContentAlignment="Center" Content="{Binding Path=Identifier}"
                           FontSize="10pt" Padding="4" Width="110">
      </Label>
    </StackPanel>
  </DataTemplate>
</ResourceDictionary>

posso associare una classe parziale come quella che segue:

MyRd.xaml.cs

public partial class MyRd:ResourceDictionary
  {
    public MyRd()
    {
      InitializeComponent();
    }
    
    public DataTemplate Internet
    {
      get { return base["InternetTemplate"] as DataTemplate; }
    }

    public DataTemplate Local
    {
      get { return base["LocalTemplate"] as DataTemplate; }
    }    
  }

a patto di chiamare esplicitamente il metodo InitializeComponent() il cui compito è quello di caricare quanto definito via XAML.

A questo punto recuperare i datatemplates si riduce nell’utilizzo della classe MyRd:

public class MyDataTemplate:DataTemplateSelector
  {
    private MyRd rd = new MyRd(); 
   
    public override System.Windows.DataTemplate SelectTemplate(object item, System.Windows.DependencyObject container)
    {      
      if (...)
        return rd.Local;
      else
        return rd.Internet;
    }
  }

Enjoy!

Technorati Tags: ,