WPF Binding from the CornerRadius of a Border

Ok, after posing this question over at .NET Blog it took me all of about 30 seconds to realize what I needed to do.

Is it possible to do Binding on separate corners of the CornerRadius. I would like to have a slider that the top corners on the Border increase/decrease radius as the slider is moved. But I don’t want the bottom to corners to be affected.

I had used the tutorial over at Martin Grayson: Adventures of a ‘Designer’ to create a glass button for a project I am working on. This was a great starting point for my buttons, but there were a few things I needed to modify. I am only going to show you how I was able to bind to a slider to change the radius of the button.

The first thing I did was create the control template, notice though that where the corner radius is, I have binded it to a slider that I have added. But on the one corner, the corners originally were set to 4,4,0,0, which will mean that if we use the value from the slider, it will end up looking looking distorted like Figure 1.

Distorted Buttons
Figure 1

<ControlTemplate x:Key=”GlassButton” TargetType=”{x:Type Button}”>
<ControlTemplate.Resources>
<Storyboard x:Key=”Storyboard1″>
<DoubleAnimationUsingKeyFrames BeginTime=”00:00:00″ Storyboard.TargetName=”glow” Storyboard.TargetProperty=”(UIElement.Opacity)”>
<SplineDoubleKeyFrame KeyTime=”00:00:00.3000000″ Value=”1″/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Key=”Storyboard2″>
<DoubleAnimationUsingKeyFrames BeginTime=”00:00:00″ Storyboard.TargetName=”glow” Storyboard.TargetProperty=”(UIElement.Opacity)”>
<SplineDoubleKeyFrame KeyTime=”00:00:00.3000000″ Value=”0″/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</ControlTemplate.Resources>
<Border BorderBrush=”#FFFFFFFF” BorderThickness=”1,1,1,1″ CornerRadius=”{Binding ElementName=slider1, Path=Value}”>
<Border Background=”#7F000000″ BorderBrush=”#FF000000″ BorderThickness=”1,1,1,1″ CornerRadius=”{Binding ElementName=slider1, Path=Value}” x:Name=”border”>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height=”0.500*”/>
<RowDefinition Height=”0.500*”/>
</Grid.RowDefinitions>
<Border HorizontalAlignment=”Stretch” Width=”Auto” Grid.RowSpan=”2″ CornerRadius=”{Binding ElementName=slider1, Path=Value}” x:Name=”glow” Opacity=”0″>
<Border.Background>
<RadialGradientBrush>
<RadialGradientBrush.RelativeTransform>
<TransformGroup>
<ScaleTransform CenterX=”0.5″ CenterY=”0.5″ ScaleX=”1.633″ ScaleY=”2.509″/>
<SkewTransform AngleX=”0″ AngleY=”0″ CenterX=”0.5″ CenterY=”0.5″/>
<RotateTransform Angle=”0″ CenterX=”0.5″ CenterY=”0.5″/>
<TranslateTransform X=”0.013″ Y=”0.424″/>
</TransformGroup>
</RadialGradientBrush.RelativeTransform>
<GradientStop Color=”#B28DBDFF” Offset=”0″/>
<GradientStop Color=”#008DC6FF” Offset=”0.996″/>
</RadialGradientBrush>
</Border.Background>
</Border>
<ContentPresenter HorizontalAlignment=”Center” VerticalAlignment=”Center” Width=”Auto” Grid.RowSpan=”2″/>
<Border Margin=”0,0,0,0″ VerticalAlignment=”Stretch” Height=”Auto” CornerRadius=”{Binding ElementName=slider1, Path=Value, Converter={StaticResource cornerConverter}}” x:Name=”shine”>
<Border.Background>
<LinearGradientBrush EndPoint=”0.5,1″ StartPoint=”0.5,0″>
<GradientStop Color=”#99FFFFFF” Offset=”0″/>
<GradientStop Color=”#33FFFFFF” Offset=”1″/>
</LinearGradientBrush>
</Border.Background>
</Border>
</Grid>
</Border>
</Border>
<ControlTemplate.Triggers>
<Trigger Property=”IsPressed” Value=”True”>
<Setter Property=”Visibility” TargetName=”glow” Value=”Hidden”/>
<Setter Property=”Opacity” TargetName=”shine” Value=”0.4″/>
<Setter Property=”Background” TargetName=”border” Value=”#CC000000″/>
</Trigger>
<Trigger Property=”IsMouseOver” Value=”True”>
<Trigger.EnterActions>
<BeginStoryboard Storyboard=”{StaticResource Storyboard1}”/>
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard x:Name=”Storyboard2_BeginStoryboard” Storyboard=”{StaticResource Storyboard2}”/>
</Trigger.ExitActions>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>

Here is the converter that I used which returns the radius as a string and leaves the bottom corners set to 0.

public class CornerRadiusConverter : IValueConverter
{
#region IValueConverter Members
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
string rad = value.ToString();
return rad + “,” + rad + “,0,0″;
}

public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return “”;
}
#endregion
}

Figure 2 shows the buttons after the converter.
Corrected image
Figure 2

No comments yet

Leave a reply