如何从转换器中引用xaml模板?

时间:2011-01-18 20:42:26

标签: wpf binding datatemplate converter controltemplate

我目前遇到的问题是通过转换器为控件分配不同的模板。

所以我有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文件,以便它允许我为其分配所需的模板???

谢谢和问候, 千电子伏

5 个答案:

答案 0 :(得分: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>

答案 1 :(得分: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;
}

<强>更新 抱歉,我忽略了您正在尝试获取ControlTemplate,而模板选择器则用于选择DataTemplate。但我相信您的任务也可以使用数据模板来实现。

如果您仍想使用ControlTemplate,则可以使用触发器:

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

答案 2 :(得分:0)

将模板放在某些控件的资源中,给它们x:Keys并调用:

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

答案 3 :(得分:0)

答案 4 :(得分: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等。