2016-10-24 4 views
2

Мне нужно привязать кнопку к шаблону управления. XAML выглядит примерно так:Связывание с шаблоном управления

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

преобразователь (StatustoTemplate) работает отлично, как статус (который является целым числом, но рад за это будет строка) изменения:

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

Теперь, в каком формате я могу отправить обратно ControlTemplate1, или ControlTemplate2? Предположим, что ControlTemplate1 и ControlTemplate2 являются действительными шаблонами управления, как определено в XAML. Теперь я должен вернуть ControlTemplate, но как его настроить?

ответ

0

Конвертер не просто найти ресурс, определенный в XAML. Обычно я определяю один шаблон управления, который имеет оба определения и переключает их, используя Visibility. Код - всего лишь короткий образец.

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> 

Преобразователь

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

    // ConvertBack 
} 
0

У меня есть MarkupExtension, которые могли бы работать для вас. Он получает значение xaml Resources по ResourceKey.

Первое: абстрактный класс 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]; 
    } 
} 

Второе: реализация класса, как StyleRefExt

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

Просто замените ## YOUR_ASSEMBLYNAME ## с именем вашей сборки и ## YOUR_RESOURCE_DICTIONARY_FILE ## с именем вашего файла r ResourceDictionary (находится в папке Styles).

Ваш Converter должен выглядеть следующим образом:

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

мой предпочтительный подход заключается в использовании стиля с DataTriggers для переключения шаблона, без преобразователей

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

, а затем применить этот стиль:

<Button Style="{StaticResource StatusButton}"/>