WPF根据自定义属性的值设置CustomControl样式

时间:2013-10-27 16:57:09

标签: wpf xaml styles custom-controls

我有CustomControl个自定义属性(DependencyProperty),称为“SingleRow”。
如果属性设置为true,我需要使用特定的样式 如果属性设置为false,我需要使用默认样式 - 因为我不需要做任何特殊的事情。

这是我的风格:

<Style TargetType="{x:Type local:MetroTabControl}">
...
</Style>

<Style x:Key="MetroTabControlSingleRow" TargetType="{x:Type local:MetroTabControl}">
...
</Style>

当SingleRow属性为true时,如何设置CustomControl使用“MetroTabControlSingleRow”?

我试过了:

public static DependencyProperty SingleRowPropertyKey = DependencyProperty.Register("SingleRow", typeof(bool), typeof(MetroTabControl), new PropertyMetadata(true));
public bool SingleRow
{
    get { return (bool)GetValue(SingleRowPropertyKey); }
    set { base.SetValue(SingleRowPropertyKey, value); }
}

public override void OnApplyTemplate()
{
    if (SingleRow)
    {
        ResourceDictionary rd = new ResourceDictionary();
        rd.Source = new Uri("/MetroControls;component/Generic.xaml", System.UriKind.Relative);
        Resources.MergedDictionaries.Add(rd);
        SetResourceReference(MetroTabControl.StyleProperty, "MetroTabControlSingleRow");

        Style = (Style)this.FindResource("MetroTabControlSingleRow");
    }
}

但它一直在崩溃。

修改 另外,根据开发hedgehog的评论,我试过了:

<Style TargetType="{x:Type local:MetroTabControl}">
    <Style.Triggers>
        <Trigger Property="SingleRow" Value="True">
            <Setter Property="Template" Value="{StaticResource MetroTabControlSingleRow}" />
        </Trigger>
        <Trigger Property="SingleRow" Value="False">
            <Setter Property="Template" Value="{StaticResource MetroTabControlMultiRows}" />
        </Trigger>
    </Style.Triggers>
</Style>

<ControlTemplate x:Key="MetroTabControlSingleRow" TargetType="{x:Type local:MetroTabControl}">
...
</ControlTemplate>

<ControlTemplate x:Key="MetroTabControlMultiRows" TargetType="{x:Type local:MetroTabControl}">
...
</ControlTemplate>

仍然崩溃。

非常感谢您的帮助。

2 个答案:

答案 0 :(得分:2)

只需使用触发器。

以下是IsFocused属性的示例。

<ControlTemplate x:Key="NotFocused" TargetType="{x:Type TextBox}">  
    . . .
</ControlTemplate>  

<ControlTemplate x:Key="Focused" TargetType="{x:Type TextBox}">   
    . . .
</ControlTemplate>


<Style TargetType="{x:Type TextBox}">   
    <Style.Triggers>
        <Trigger Property="IsFocused" Value="True">
            <Setter Property="Template" Value="{StaticResource Focused}" />
        </Trigger>
        <Trigger Property="IsFocused" Value="False">
            <Setter Property="Template" Value="{StaticResource NotFocused}" />
        </Trigger>
    </Style.Triggers>
</Style>

答案 1 :(得分:1)

这就是我使用它的方式,它对我有用。

代码:

public class MyConverter : IValueConverter
{
    public DataTemplate First { get; set; }
    public DataTemplate Second { get; set; }

    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        if ((bool)value)
            return First;
        else
            return Second;
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

XAML:

<DataTemplate x:Key="first">
    <Button>one</Button>
</DataTemplate>

<DataTemplate x:Key="second">
    <CheckBox/>
</DataTemplate>

<local:MyConverter x:Key="myConverter"
                   First="{StaticResource first}"
                   Second="{StaticResource second}" />

<Style TargetType="{x:Type local:MyCustomControl1}">
    <Setter Property="Template" >
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type local:MyCustomControl1}">
                <Border Background="{TemplateBinding Background}"
                        BorderBrush="{TemplateBinding BorderBrush}"
                        BorderThickness="{TemplateBinding BorderThickness}">
                    <ContentPresenter ContentTemplate="{Binding SingleRow, Converter={StaticResource myConverter}, RelativeSource={RelativeSource TemplatedParent}}" />
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>