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!