绑定到控件模板

时间:2016-10-24 04:15:16

标签: c# wpf xaml binding controltemplates

我需要将按钮绑定到控件模板。 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 - 但是如何设置它?

3 个答案:

答案 0 :(得分:1)

我首选的方法是使用带有DataTriggers的Style来切换模板,而不使用转换器

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

然后应用此样式:

{{1}}

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

答案 2 :(得分:0)

我有MarkupExtension可能适合您。它是由Resources定义ResourceKey的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];
    }
}

第二个:类实现为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 ## 替换为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();
    }
}