tags:

views:

5013

answers:

2

I would like to create a rectangular 'flat 3D' look for one of my control templates. In it's most simple version this means having a line at the bottom that is darker than that at the top, and maybe some variation between the left and right lines too.

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

The default <Border> element in WPF lets you specify a different thickness per edge, but I can't find a way to specify multiple brushes.

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

EDIT it's been suggested that I post an example of how I want to use this. Personally I'd be happy to have a style or a user control. The user control might be used thus:

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

Or perhaps even simpler:

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

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

+1  A: 

Honestly probably the easiest way would be to use layering techniques. For instance create a grid like this:

  <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 idea. This is probably the easiest way of doing it. You could set this up as a template and use it like this:

<Template x:Key="My3DBorder" TargetType="ContentControl">
    <!-- Put the Grid definition in here from above -->
</Template>

<ContentControl Template="{StaticResource My3dBorder}">
   <!-- My Content Goes Here -->
</ContentControl>
Micah
Its probably better to do this with Line elements and and not 4 Borders
Nir
This really isn't very concise. I'm hoping there's a better, simpler way of doing this, even after replacing borders with lines.
Drew Noakes
I'm not sure how much simpler it can be. How about you post an example of how you want to use it, and we'll work backwards from there.
Micah
Throw it into a user control and it will be really simple to use.
Bryan Anderson
Imagine I wanted to have several of these in my UI. Laying this XAML around every instance would really obscure the logical tree. How could this visual tree specification be separated?
Drew Noakes
+2  A: 

Here is a solution I devised that achieves most of what I want. It doesn't give complete control over all four sides independently, but it does give the rectangular flat 3D view that I want.

Here's how it looks:

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 that helps someone else out. I'm still on the lookout for innovative solutions to this problem, so keep posting and I'll accept a better answer than this one.

Drew Noakes