1

我的想法是使用 WPF 默认按钮,使用图像作为不透明蒙版,并让前景画笔更改其颜色。然而,我仍然想拥有背景,这就是问题所在,因为无论我如何设计风格,背景总是会消失。要么这是不可能的,因为不透明蒙版无法更改其目标,只能作用于整个控件,要么我错过了一些东西。

这是我的风格。我试图保持它相当基本。

<Style x:Key="ButtonStyle" TargetType="Button">

    <Setter Property="OverridesDefaultStyle" Value="True"/>
    <Setter Property="Background" Value="{DynamicResource Mono_Darkest}"/>
    <Setter Property="Foreground" Value="{DynamicResource Mono_Light}"/>
    <Setter Property="BorderBrush" Value="{StaticResource Button_BorderBrush_Normal}"/>
    <Setter Property="BorderThickness" Value="{StaticResource Button_BorderThickness_Normal}"/>
    <Setter Property="FontFamily" Value="{StaticResource Button_FontFamily_Normal}"/>
    <Setter Property="FontWeight" Value="{StaticResource Button_FontWeight_Normal}"/>
    <Setter Property="FontSize" Value="{StaticResource Button_FontSize_Normal}"/>
    <Setter Property="HorizontalContentAlignment" Value="{StaticResource Button_HorizontalContentAlignment_Normal}"/>
    <Setter Property="VerticalContentAlignment" Value="{StaticResource Button_VerticalContentAlignment_Normal}"/>
    <Setter Property="Padding" Value="{StaticResource Button_Padding_Normal}"/>

    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type Button}">
                <Border x:Name="Border_Part" 
                        Background="{TemplateBinding Background}" 
                        BorderBrush="{TemplateBinding BorderBrush}" 
                        BorderThickness="{TemplateBinding BorderThickness}">
                        <Label OpacityMask="{TemplateBinding OpacityMask}" 
                               Foreground="{TemplateBinding Foreground}" 
                               HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" 
                               VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}" 
                               Content="{TemplateBinding Content}" FontFamily="{TemplateBinding FontFamily}" 
                               FontSize="{TemplateBinding FontSize}" FontWeight="{TemplateBinding FontWeight}">
                            <Label.Style>
                                <Style TargetType="Label">
                                    <Setter Property="Background" Value="Transparent"/>
                                    <Style.Triggers>
                                        <DataTrigger Binding="{Binding Path=OpacityMask, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Button}}, Converter={StaticResource isNull}}" 
                                                     Value="false">
                                            <Setter Property="Background" 
                                                    Value="{Binding Path=Foreground, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Button}}}"/>
                                        </DataTrigger>
                                    </Style.Triggers>
                                </Style>
                            </Label.Style>
                        </Label>
                    </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

我所拥有的只是在边框内嵌套一个标签。我想要的是模板(按钮)控件的 opacity 属性只影响标签的 opacity 属性。但这似乎并没有发生。相反,它似乎会像默认按钮样式一样影响所有内容。

我尝试将 OverridesDefaultStyle 设置为 True,但这并没有改变任何东西。

我知道我已经可以通过其他方式做到这一点。但我的目标是制作一个可以使用文本或图像作为前景的快速按钮。图像颜色来自前景画笔。如果我在这里无法得到答案,我很可能只是使用附加属性并将标签不透明蒙版绑定到该属性,但我还是宁愿完全以这种风格来做。

欢迎任何建议。谢谢你。

4

1 回答 1

0

因为Opacity我使用Converter. 有了这个,我可以将 a 绑定SolidColorBrushForegroundor BackgroundConverter获取Parameter目标并返回opacOpacity颜色。

转换器:

public class ColorToOpacityConverter : IValueConverter
{
    // Takes a SolidColorBrush as value and double as parameter
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (!(value is SolidColorBrush)) return value;
        SolidColorBrush scb = new SolidColorBrush(((SolidColorBrush) value).Color);
        scb.Opacity = parameter as double? ?? 0.5;
        return scb;
    }

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

xml:

<Style.Resources>
    <namespace:ColorToOpacityConverter x:Key="ColorToOpacityConverter" />
    <system:Double x:Key="TargetOpacity">0.3</system:Double>
</Style.Resources>

<Label Foreground="{Binding Path=Foreground, StaticResource={StaticResource TemplatedParent}, Converter={StaticResource ColorToOpacityConverter}, ConverterParameter={StaticResource TargetOpacity}"

绑定不透明度的第二种方法(不是 as StaticResource)我使用MultiValueConverter

对于绑定不透明度:

public class ColorToDynOpacityConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        if (values.Any(v => v == DependencyProperty.UnsetValue)) return new SolidColorBrush();
        if (!(values[0] is SolidColorBrush) || !(values[1] is double)) {
            //Fake for DesignMode-Display
            if (DesignerProperties.GetIsInDesignMode(new DependencyObject())) return new SolidColorBrush(Colors.Aqua);
            throw new ArgumentException("expect values[0] as SolidColorBrush and values[1] as double.");
        }
        SolidColorBrush scb = new SolidColorBrush(((SolidColorBrush) values[0]).Color);
        scb.Opacity = (double) values[1];
        return scb;
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

xml:

<namespace:ColorToDynOpacityConverter x:Key="ColorToDynOpacityConverter" />

<Label>
    <Label.Foreground>
        <MultiBinding Converter="{StaticResource ColorToDynOpacityConverter}">
            <Binding Path="Foreground" RelativeSource="{RelativeSource TemplatedParent}" />
            <Binding Path="Opacity" RelativeSource="{RelativeSource TemplatedParent}" />
        </MultiBinding>
    </Label.Foreground>
</Label>

希望对您有所帮助并为您工作。

于 2016-10-20T06:08:35.990 回答