2

I need to bind a button to a Control Template. The XAML looks something like this:

Button Template="{Binding Status, Converter={StaticResource StatustoTemplate}}" 

The converter (StatustoTemplate) runs fine as the status (which is an integer, but happy for it to be a string) changes:

public class StatustoTemplate : IValueConverter { public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { if (value==1) { return ControlTemplateName1; } if (value==2) { return ControlTemplateName2; } } } 

Now, in what format can I send back ControlTemplate1, or ControlTemplate2? Let us assume that ControlTemplate1 and ControlTemplate2 are valid Control Templates as defined in the XAML. I now that it needs to return a ControlTemplate - but how to set it up?

3 Answers 3

1

my preferred approach is to use a Style with DataTriggers to switch Template, without converters

<Style TargetType="Button" x:Key="StatusButton"> <!--set BasedOn if there is a base Style--> <Style.Triggers> <DataTrigger Binding="{Binding Status}" Value="1"> <Setter Property="Template" Value="{StaticResource ControlTemplateName1}"/> </DataTrigger> <DataTrigger Binding="{Binding Status}" Value="2"> <Setter Property="Template" Value="{StaticResource ControlTemplateName2}"/> </DataTrigger> </Style.Triggers> </Style> 

and then apply this Style:

<Button Style="{StaticResource StatusButton}"/> 
Sign up to request clarification or add additional context in comments.

1 Comment

For those who are here for Xamarin , you have to specify the TargetType of the DataTrigger, in this example case Button type. <DataTrigger TargetType="Button" Binding="{Binding Status}" Value="1">
0

It is not easy for converter to find resource defined in XAML. I usually define one control template which has both definitions and switch them using Visibility. The code is just a short sample.

XAML

<Window> <Window.DataContext> <local:MainWindowViewModel/> </Window.DataContext> <Window.Resources> <ResourceDictionary> <local:MyConverter x:Key="MyConverter"/> <ControlTemplate x:Key="template"> <Grid> <Grid Visibility="{Binding Status, Converter={StaticResource MyConverter}, ConverterParameter=1}"> <TextBox Text="1"/> </Grid> <Grid Visibility="{Binding Status, Converter={StaticResource MyConverter}, ConverterParameter=2}"> <TextBox Text="2"/> </Grid> </Grid> </ControlTemplate> </ResourceDictionary> </Window.Resources> <Grid> <Button Template="{StaticResource template}"/> </Grid> </Window> 

Converter

public class MyConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { return ((string)parameter == "1") ? Visibility.Visible : Visibility.Collapsed; } // ConvertBack } 

Comments

0

I have a MarkupExtension that might work for you. It is getting xaml defined Resources by ResourceKey.

First: abstract class StyleRefExtension:

public abstract class StyleRefExtension : MarkupExtension { protected static ResourceDictionary RD; public string ResourceKey { get; set; } public override object ProvideValue(IServiceProvider serviceProvider) { return ProvideValue(); } public object ProvideValue() { if (RD == null) throw new Exception( @"You should define RD before usage. Please make it in static constructor of extending class!"); return RD[ResourceKey]; } } 

Second: class implementation as StyleRefExt

public class StyleRefExt : StyleRefExtension { static StyleRefExt() { RD = new ResourceDictionary { Source = new Uri("pack://application:,,,/##YOUR_ASSEMBLYNAME##;component/Styles/##YOUR_RESOURCE_DICTIONARY_FILE##.xaml") }; } } 

Just replace ##YOUR_ASSEMBLYNAME## with the name of your assembly and ##YOUR_RESOURCE_DICTIONARY_FILE## with the filename of your ResourceDictionary (that is located in folder Styles).

Your Converter should look like this:

public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { if (value==1) { StyleRefExt sr = new StyleRefExt {ResourceKey = "ControlTemplateName1"}; return sr.ProvideValue(); } if (value==2) { StyleRefExt sr = new StyleRefExt {ResourceKey = "ControlTemplateName2"}; return sr.ProvideValue(); } } 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.