Reputation: 837
I am currently stuck on a problem assigning different templates to a control via a converter.
So I have 2 templates.
<ControlTemplate x:Name="_templateA" x:Key="templateA">
<StackPanel Grid.Column="0" Margin="0,0,5,0">
<Blah />
</StackPanel>
</ControlTemplate>
<ControlTemplate x:Name="_templateB" x:Key="templateB">
<StackPanel Grid.Column="0" Margin="0,0,5,0">
<Blah Blah />
</StackPanel>
</ControlTemplate>
and I have this control using this converter:
<ControlA x:Name="_controlA" >
<Control Template="{Binding Converter={StaticResource templateConverters}}" />
</ControlA>
My Converter:
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
Object a;
ControlTemplate template = null;
try
{
a= value as ObjectA;
if (value != null)
template = a.useTemplate1 ? [templateA from xaml] : [templateB from xaml];
}
catch (Exception ex)
{
Debug.Assert(false, ex.ToString());
}
return toolbar;
}
In my Converter, how am I able to get reference to my xaml file so that it allows me to assign it my desired template???
Thanks and Regards, Kev
Upvotes: 0
Views: 3756
Reputation: 20746
What you are trying to accomplish is called a Template Selector. You can read about it, for example, here: http://codingbandit.com/Blog/blog/wpf-data-templates-part-4-template-selectors/
Given that, you will be defining a template selector (see ContentTemplateSelector property on your control). And its SelectTemplate
method will look something like this:
public override System.Windows.DataTemplate SelectTemplate(object item, System.Windows.DependencyObject container)
{
ControlTemplate template = null;
ContentPresenter pres = container as ContentPresenter;
try
{
if (value != null)
template = item.useTemplate1 ? pres.FindResource("_templateA") : pres.FindResource("_templateB");
}
catch (Exception ex)
{
Debug.Assert(false, ex.ToString());
}
return toolbar;
}
Update: Sorry, I overlooked that you are trying to get a ControlTemplate, while template selectors are for selecting a DataTemplate. But I believe that you task can also be achieved using data templates.
If you still want to use ControlTemplate then triggers is the way to go:
<ControlTemplate x:Name="_templateA" x:Key="templateA">
<StackPanel Grid.Column="0" Margin="0,0,5,0">
<Blah />
</StackPanel>
</ControlTemplate>
<ControlTemplate x:Name="_templateB" x:Key="templateB">
<StackPanel Grid.Column="0" Margin="0,0,5,0">
<Blah Blah />
</StackPanel>
</ControlTemplate>
<Style x:Key="MyControlStyle" TargetType="[x:Type Control}">
<Setter Property="Template" Value="{StaticResource templateB}"/>
<Style.Triggers>
<DataTrigger Binding="{Binding useTemplate1}" Value="True">
<Setter Property="Template" Value="{StaticResource templateA}"/>
</DataTrigger>
</Style.Triggers>
</Style>
And you control:
<ControlA x:Name="_controlA" >
<Control Style="{StaticResource MyControlStyle}" />
</ControlA>
Upvotes: 1
Reputation: 17274
Maybe you should think on some other implementation but here is what you're asking for:
your converter code:
public class MyConverter : IValueConverter
{
public ControlTemplate TemplateA { get; set; }
public ControlTemplate TemplateB { get; set; }
... Convert methods using TemplateA and TemplateB properties...
}
usage in XAML:
<UserControl.Resources>
<!-- templates with 'templateA' and 'templateB' keys -->
<Converters:MyConverter x:Key="templateConverters" TemplateA="{StaticResource templateA}" TemplateB="{StaticResource templateB}" />
<UserControl.Resources>
...
<ControlA x:Name="_controlA" >
<Control Template="{Binding Converter={StaticResource templateConverters}}" />
</ControlA>
Upvotes: 10
Reputation: 26495
I think you can accomplish this better with DataTriggers:
<ControlTemplate>
<StackPanel Name="TemplateA" Grid.Column="0" Margin="0,0,5,0">
<Blah />
</StackPanel>
<StackPanel Name="TemplateB" Grid.Column="0" Margin="0,0,5,0">
<Blah Blah />
</StackPanel>
<ControlTemplate.Triggers>
<DataTrigger Binding="{Binding YourProp}" Value="1">
<Setter TargetName="TemplateA" Property="Visibility" Value="Visible" />
<Setter TargetName="TemplateB" Property="Visibility" Value="Collapsed" />
</DataTrigger>
<DataTrigger Binding="{Binding YourProp}" Value="0">
<Setter TargetName="TemplateA" Property="Visibility" Value="Collapsed" />
<Setter TargetName="TemplateB" Property="Visibility" Value="Visible" />
</DataTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
This is off the top of my head, so TargetName might be SourceName, etc.
Upvotes: 0
Reputation: 814
I think you should be able to load the XAML Resource file from the Application Resource dictionaries as described here.
Upvotes: 0
Reputation: 184376
Put your Templates in the resources of some control, give them x:Keys and call:
ControlTemplate template = someControl.FindResource("Key") as ControlTemplate;
Upvotes: 0