0

I'm curious if anyone knows of a way to easily get a double border effect in WPF similar to what you see in the selected items in Windows Explorer in Windows 7.

Example of what I'm looking for

If you look closely, you'll notice that the selected item has a dark border, a lighter, inner-border, and then a gradient background.

Currently, I'm using two borders around an object any time I want to achieve this effect. Doing it that way is ugly syntactically and really muddies my view xaml. Being a web developer at heart I'd like to separate the xaml structure from the style as much as possible. So, I've started putting this into Styles and Content Templates in order to pull it out of my view xaml.

However, I'm curious if there may be a better way to go about this.

I played around for a while using a VisualBrush as a background to try to get the effect. However, I want to be able to apply the background to elements that can be any size and the way the VisualBrush stretched the visual to fit the element background didn't work the way I wanted it to. Essentially, I'd really just like it to stretch the visual the way the WPF layout system would do it.

Any ideas would be greatly appreciated.

-- Dusty

Community
  • 1
  • 1
dustyburwell
  • 5,755
  • 2
  • 27
  • 34
  • If the region's drawn with two nested borders, what's ugly about the syntax saying so? And if you're using a template to generate it, what's getting muddied? I don't understand. – Robert Rossney Mar 12 '10 at 19:06
  • The reason it's ugly is that semantically, borders and backgrounds mean nothing. If I want to change the "skin" of my app 6 months from now I don't want to have to find all of the places I put those borders in for a look so I can change them. I agree that using a template to generate it is better, I was just curious if it's possible to use a VisualBrush in this way. – dustyburwell Mar 13 '10 at 18:01

1 Answers1

1

A VisualBrush is probably not what you want to do in this scenario, as it's pretty heavy.

You can solve the problem with some Xaml without nesting borders.

For example,

<Border BorderBrush="#FF00B5C5" BorderThickness="1" CornerRadius="2" Background="White">
   <Grid Background="#FF00B5C5" Margin="1">
     <Rectangle Fill="#FFA2F2FE" />
     <TextBlock Text="This is some text" VerticalAlignment="Center"/>
   </Grid>
</Border>

You can, of course, tweak the properties to get the look you need.

EDIT: If you want to create a style, so you can reskin the look-and-feel, you can do something like this:

<Window.Resources>
    <Style x:Key="BorderedTextBlock" TargetType="ContentControl">
        <Setter Property="ContentTemplate">
            <Setter.Value>
                <DataTemplate>
                    <Border BorderBrush="#FF00B5C5" BorderThickness="1" CornerRadius="2" Background="White"> 
                       <Grid Background="#FF00B5C5" Margin="1"> 
                         <Rectangle Fill="#FFA2F2FE" /> 
                         <TextBlock Text="{Binding}" VerticalAlignment="Center"/> 
                       </Grid> 
                    </Border>
                </DataTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</Window.Resources>

<Grid x:Name="LayoutRoot">
    <ContentControl Style="{StaticResource BorderedTextBlock}" Content="This is some text" Width="200" Height="24"/>
</Grid>

Additionally, turn this into a custom control with all the styling and theming parameters that you need.

Hope that helps,

Sergio

SergioL
  • 4,905
  • 3
  • 26
  • 30
  • While not exactly what I was looking for, your advice is sound. I suppose using a VisualBrush probably isn't all that performant. – dustyburwell Mar 15 '10 at 18:16
  • I don't think you'd ever get the VisualBrush to look exactly how you want because of the stretching factor. As scales up to fill an element, the "fake" border will scale up too, so you won't get that nice 1 pixel white border on the inside. Styles and Themes (and possibly a custom control) are the way to go here to eliminate the redundancy and mess. – SergioL Mar 16 '10 at 21:30
  • I appreciate that advice, SergioL. I hadn't really given it much thought, but that's exactly what a lot of the standard ControlTemplates do. For instance, Button uses ButtonChrome in Luna and Aero for it's border. Thanks for jogging my brain on that one. – dustyburwell Mar 19 '10 at 13:25