Q1: As far as I know
Q2: I would say that styles are the way to go and you can of course make your own class that comes from the button and selects the right corner radius based on if it is left, middle, right.
Q3: Must be done using a custom value converter and your own style.
Turning on. In this case, I might be tempted to place a background gradient and an angular radius on an adjacent stack panel. The buttons will be transparent with text. Then you do not have to deal with the angular radius on the individual buttons.
Edit: Added code and style for Q3 answer above. To OP; I'm not sure if this is exactly what you need, but maybe there is something interesting here.
The way I interpreted you is that you wanted to set the button background to a specific color, but it should display as a linear gradient based on that color. Other posters mentioned opacity masks, and that's not a bad idea at all. It seemed to me that I was showing how to do this using custom value converters.
The idea is that I create a converted user value that converts a solid brush to a linear gradient brush. Then I use this converter to convert the button background color from a solid color brush to a linear gradient brush.
Here is a custom value converter:
class SolidColorBrushToGradientConverter : IValueConverter { const float DefaultLowColorScale = 0.95F; public object Convert (object value, Type targetType, object parameter, CultureInfo culture) { var solidColorBrush = value as SolidColorBrush; if (!targetType.IsAssignableFrom (typeof (LinearGradientBrush)) || solidColorBrush == null) { return Binding.DoNothing; } var lowColorScale = ParseParameterAsDouble (parameter); var highColor = solidColorBrush.Color; var lowColor = Color.Multiply (highColor, lowColorScale); lowColor.A = highColor.A; return new LinearGradientBrush ( highColor, lowColor, new Point (0, 0), new Point (0, 1) ); } static float ParseParameterAsDouble (object parameter) { if (parameter is float) { return (float)parameter; } else if (parameter is string) { float result; return float.TryParse( (string) parameter, NumberStyles.Float, CultureInfo.InvariantCulture, out result ) ? result : DefaultLowColorScale ; } else { return DefaultLowColorScale; } } public object ConvertBack (object value, Type targetType, object parameter, CultureInfo culture) { return Binding.DoNothing; } }
Then I refer to this in the style that I copied from you (basically the same, but changed it a bit), the important part of the line is this:
Background="{Binding Path=Background,Mode=OneWay,RelativeSource={RelativeSource Mode=TemplatedParent}, Converter={StaticResource SolidColorBrushToGradientConverter}, ConverterParameter=0.95}"
This means that we are attached to the parent background template (for example, Button.Background), we use the SolidColorBrushToGradientConverter with the parameter 0.95 (this determines how much darker the βlowβ color should be compared with the βhighβ color).
Full style:
<local:SolidColorBrushToGradientConverter x:Key="SolidColorBrushToGradientConverter" /> <Style x:Key="GoogleMiddleButton" TargetType="{x:Type Button}"> <Setter Property="Background" Value="#F5F5F5" /> <Setter Property="Foreground" Value="#666666"/> <Setter Property="FontFamily" Value="Arial"/> <Setter Property="FontSize" Value="13"/> <Setter Property="FontWeight" Value="Bold"/> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="Button"> <Border Name="dropShadowBorder" BorderThickness="0,0,0,1" CornerRadius="1" > <Border.BorderBrush> <SolidColorBrush Color="#00000000"/> </Border.BorderBrush> <Border Name="border" BorderThickness="{TemplateBinding BorderThickness}" Padding="{TemplateBinding Padding}" CornerRadius="0" Background="{Binding Path=Background,Mode=OneWay,RelativeSource={RelativeSource Mode=TemplatedParent}, Converter={StaticResource SolidColorBrushToGradientConverter}, ConverterParameter=0.95}" > <Border.BorderBrush> <SolidColorBrush Color="#D8D8D8"/> </Border.BorderBrush> <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" /> </Border> </Border> <ControlTemplate.Triggers> <Trigger Property="IsMouseOver" Value="True"> <Setter Property="BorderBrush" TargetName="border"> <Setter.Value> <SolidColorBrush Color="#939393"/> </Setter.Value> </Setter> <Setter Property="BorderBrush" TargetName="dropShadowBorder"> <Setter.Value> <SolidColorBrush Color="#EBEBEB"/> </Setter.Value> </Setter> </Trigger> <Trigger Property="IsPressed" Value="True"> <Setter Property="Background" Value="#4A8FF7" /> <Setter Property="Foreground" Value="#F5F5F5" /> <Setter Property="BorderBrush" TargetName="border"> <Setter.Value> <SolidColorBrush Color="#5185D8"/> </Setter.Value> </Setter> </Trigger> </ControlTemplate.Triggers> </ControlTemplate> </Setter.Value> </Setter> </Style>