C# 绑定到控件模板

C# 绑定到控件模板,c#,wpf,xaml,binding,controltemplates,C#,Wpf,Xaml,Binding,Controltemplates,我需要将按钮绑定到控件模板。XAML看起来像这样: Button Template="{Binding Status, Converter={StaticResource StatustoTemplate}}" public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { if (value==1) {

我需要将按钮绑定到控件模板。XAML看起来像这样:

Button Template="{Binding Status, Converter={StaticResource StatustoTemplate}}"
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();
    }
}
转换器(StatustoTemplate)在状态(这是一个整数,但很高兴它是一个字符串)更改时运行良好:


现在,我可以用什么格式发回ControlTemplate1,或者ControlTemplate2?假设ControlTemplate1ControlTemplate2是XAML中定义的有效控制模板。现在我知道它需要返回一个ControlTemplate,但是如何设置它呢?

转换器很难找到XAML中定义的资源。我通常定义一个控件模板,该模板包含两个定义,并使用
可见性
切换它们。代码只是一个简短的示例

XAML


我有一个
MarkupExtension
,可能适合您。它正在通过
ResourceKey
获取定义为
Resources
的xaml

第一个:抽象类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:类实现为StyleRefExt

public class StyleRefExt : StyleRefExtension
{
    static StyleRefExt()
    {
        RD = new ResourceDictionary
             {
                 Source = new Uri("pack://application:,,,/##YOUR_ASSEMBLYNAME##;component/Styles/##YOUR_RESOURCE_DICTIONARY_FILE##.xaml")
             };
    }
}
只需将#######替换为程序集的名称,将###资源字典#文件#替换为
资源字典
的文件名(位于文件夹
style
中)

您的
转换器应如下所示:

Button Template="{Binding Status, Converter={StaticResource StatustoTemplate}}"
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();
    }
}

我首选的方法是使用带有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}"/>

对于这里的Xamarin用户,您必须指定DataTrigger的TargetType,在本例中是
按钮
类型<代码>
<Button Style="{StaticResource StatusButton}"/>