2009-02-24 7 views
7

Me gustaría crear un aspecto rectangular en "3D plano" para una de mis plantillas de control. En su versión más simple, esto significa tener una línea en la parte inferior que es más oscura que en la parte superior, y tal vez alguna variación entre las líneas izquierda y derecha también.¿Cómo puedo darle a un elemento WPF un borde 3D plano rectangular?

Una versión más compleja me permitiría proporcionar uno o más pinceles para poder aplicar gradientes.

El elemento predeterminado <Border> en WPF le permite especificar un grosor diferente por borde, pero no puedo encontrar la manera de especificar varios pinceles.

Entonces, ¿cómo puedo producir el efecto que quiero tan simple como sea posible?

EDIT se ha sugerido que publique un ejemplo de cómo quiero usar esto. Personalmente, me gustaría tener un estilo o un control de usuario. El control de usuario puede ser utilizado tanto:

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

O quizás aún más simple:

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

Estos son sólo ideas. Cualquier solución sensible y concisa es bienvenida.

Respuesta

11

Aquí es una solución ideé que logra la mayor parte de lo que quiero. No proporciona un control total sobre los cuatro lados de forma independiente, pero sí proporciona la vista rectangular en 3D plana que deseo.

Así es como se ve:

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

pega esto en Kaxaml que verlo por ti mismo:

<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> 

la esperanza de que ayude a alguien más ahí fuera. Todavía estoy buscando soluciones innovadoras para este problema, así que sigue publicando y aceptaré una mejor respuesta que esta.

3

Honestamente, probablemente la forma más fácil sería utilizar técnicas de capas. Por ejemplo crear una cuadrícula de esta manera:

<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> 

creo que usted consigue la idea. Esta es probablemente la forma más fácil de hacerlo. Se podría instalar esto como una plantilla y utilizar de esta manera:

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

<ContentControl Template="{StaticResource My3dBorder}"> 
    <!-- My Content Goes Here --> 
</ContentControl> 
+0

Es probablemente mejor hacer esto con elementos de línea y no Borders 4 – Nir

+0

Esto realmente no es muy concisa. Espero que haya una manera mejor y más simple de hacer esto, incluso después de reemplazar bordes con líneas. –

+0

No estoy seguro de cuánto más simple puede ser. Qué tal si publica un ejemplo de cómo desea usarlo, y trabajaremos hacia atrás desde allí. – Micah

13

He hecho algo así simplemente colocando múltiples bordes directamente uno encima del otro. Por ejemplo:

<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> 

Esto proporciona la ventaja adicional de todas las otras características que proporciona el borde-- radio de la esquina y tal.

+1

Para agregar mi $ 0.02, puede intercambiar los valores cero y no cero en la propiedad 'BorderThickness' anterior para obtener un efecto hundido. – dotNET

1

puede hacer referencia al PresentationFramework.Clásico montaje y luego usar

<Window xmlns:mwt="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Classic"> 
... 

<Grid Width="50" Height="50"> 
    <mwt:ClassicBorderDecorator BorderThickness="3,3,3,3"/> 
</Grid> 

que estaba usando this technique for looking at control templates para ver cómo botones predeterminados fueron labrados

Cuestiones relacionadas