2011-01-18 41 views
0

我目前陷入了一个问题,通过转换器将不同的模板分配给控件。如何从转换器引用xaml模板?

所以我有2个模板。

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

,我必须使用该转换器这个控制:

<ControlA x:Name="_controlA" > 
    <Control Template="{Binding Converter={StaticResource templateConverters}}" /> 
</ControlA> 

我的转换器:

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

在我的转换器,我怎么能得到参考我的XAML文件,以便它允许我将它分配给我想要的模板?

感谢和问候, 千电子伏

+0

太多的问号。 – 2011-01-18 20:47:23

回答

10

也许你应该考虑在其他一些实施但这里是你问的:

您的转换代码:

public class MyConverter : IValueConverter 
{ 
    public ControlTemplate TemplateA { get; set; } 
    public ControlTemplate TemplateB { get; set; } 

    ... Convert methods using TemplateA and TemplateB properties... 
} 

使用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> 
+0

感谢这工作。我想尝试使用其他用户所建议的数据触发器,但我需要弄清楚如何才能正常工作。非常感谢。 – Kev84 2011-01-18 21:17:52

0

把你的模板在一些控制的资源,让他们X:键和拨打:

ControlTemplate template = someControl.FindResource("Key") as ControlTemplate; 
0

我认为你可以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> 

这是从我的头顶,这样的TargetName可能是SOURCENAME等

+0

谢谢,虽然我无法使用触发器工作,但可能我没有实现它。 “价值”是如何与绑定的价值进行比较的,如果匹配,它会使用特定的一组代码? – Kev84 2011-01-18 21:19:26

+0

你的价值是什么类型?当值匹配时它将执行Setter组。根据你的价值的类型,可能会有一些不可思议的情况。 – jonathanpeppers 2011-01-18 22:40:39

1

你正在尝试完成被称为模板选择。例如,您可以在此阅读:http://codingbandit.com/Blog/blog/wpf-data-templates-part-4-template-selectors/

鉴于此,您将定义一个模板选择器(请参阅控件上的ContentTemplateSelector属性)。而其SelectTemplate方法会是这个样子:

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

更新: 对不起,我忽略了你想获得一个控件模板,而模板选择是选择一个DataTemplate。但我相信你的任务也可以通过使用数据模板来实现。

如果你仍然想使用控件模板然后触发是要走的路:

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

你控制:

<ControlA x:Name="_controlA" > 
    <Control Style="{StaticResource MyControlStyle}" /> 
</ControlA>