How can I give a WPF element a rectangular, flat three-dimensional border?

I would like to create a rectangular β€œflat 3D” look at one of my control patterns. In it, the simplest version means that there is a line at the bottom below that is darker than at the top, and possibly some change between the left and right lines.

A more complex version will allow me to provide on or more brushes so that gradients can be applied.

The default <Border> element in WPF allows you to specify a different thickness for each edge, but I cannot find a way to specify multiple brushes.

So, how can I produce the effect that I want as simple as possible?

EDIT was asked to publish an example of how I want to use this. Personally, I would be happy to have style or user control. A user control can be used this way:

 <FourSidedBorder LeftSideBrush="#00f" RightSideBrush="#0f0" ... /> 

Or maybe even simpler:

 <FourSidedBorder BorderBrush="#00f,#0f0,#f00,#fff" BorderThickness="1,2,3,4" ... /> 

These are just ideas. Any reasonable, concise solution is welcome.

+7
wpf border
source share
4 answers

Here is a solution that I developed that achieves most of what I want. It does not give full control over all four sides independently, but it gives the rectangular flat 3D representation that I want.

Here's what it looks like:

http://img62.imageshack.us/img62/9638/flatrectanglebackground.png

Paste this into Kaxaml to see it for yourself:

 <Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Background="#CCC"> <Page.Resources> <!-- A brush for flat 3D panel borders --> <LinearGradientBrush x:Key="Flat3DBorderBrush" StartPoint="0.499,0" EndPoint="0.501,1"> <GradientStop Color="#FFF" Offset="0" /> <GradientStop Color="#DDD" Offset="0.01" /> <GradientStop Color="#AAA" Offset="0.99" /> <GradientStop Color="#888" Offset="1" /> </LinearGradientBrush> </Page.Resources> <Grid> <!-- A flat 3D panel --> <Border HorizontalAlignment="Center" VerticalAlignment="Center" BorderBrush="{StaticResource Flat3DBorderBrush}" BorderThickness="1" Background="#BBB"> <!-- some content here --> <Control Width="100" Height="100"/> </Border> </Grid> </Page> 

Hope this helps someone else. I am still in search of innovative solutions to this problem, so keep publishing and I will accept a better answer than this.

+11
source share

I did something similar, just setting a few borders directly on top of each other. For example:.

 <Border x:Name="TopAndLeft" BorderThickness="3,3,0,0" BorderBrush="{x:Static SystemColors.ControlLightBrush}"> <Border x:Name="BottomAndRight" BorderThickness="0,0,3,3" BorderBrush="{x:Static SystemColors.ControlDarkBrush}"> <ContentPresenter ... /> </Border> </Border> 

This provides an additional advantage of all other functions that the border provides - the radius of the angle, etc.

+13
source share

Honestly, probably the easiest way would be to use layering methods. For example, create a grid as follows:

  <Grid Width="50" Height="50"> <Grid.RowDefinitions> <RowDefinition Height="Auto" /> <RowDefinition Height="*" /> <RowDefinition Height="Auto" /> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width="Auto" /> <ColumnDefinition Width="*" /> <ColumnDefinition Width="Auto" /> </Grid.ColumnDefinitions> <!-- Top Border --> <Border Height="3" Background="LightGray" Grid.Column="0" Grid.Row="0" Grid.ColumnSpan="2" /> <!-- Right Border --> <Border Width="3" Background="DarkGray" Grid.Column="2" Grid.Row="0" Grid.RowSpan="3" /> <!-- Content --> <Border Background="Gray" Grid.Row="1" Grid.Column="1" /> <!-- Left Border --> <Border Width="3" Background="LightGray" Grid.Row="1" Grid.Column="0" Grid.RowSpan="2" /> <!-- Bottom Border --> <Border Height="3" Background="DarkGray" Grid.Row="2" Grid.Column="1" /> </Grid> 

I think you get the point. This is probably the easiest way to do this. You can set this as a template and use it as follows:

 <Template x:Key="My3DBorder" TargetType="ContentControl"> <!-- Put the Grid definition in here from above --> </Template> <ContentControl Template="{StaticResource My3dBorder}"> <!-- My Content Goes Here --> </ContentControl> 
+3
source share

you can reference the assembly PresentationFramework.Classic and then use

 <Window xmlns:mwt="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Classic"> ... <Grid Width="50" Height="50"> <mwt:ClassicBorderDecorator BorderThickness="3,3,3,3"/> </Grid> 

I used this technique to view control templates to see how the default buttons were configured

+1
source share

All Articles