2009-02-24 13 views
7

Chciałbym stworzyć prostokątny "płaski 3D" wygląd jednego z moich szablonów sterowania. W jego najprostszej wersji oznacza to, że linia na dole jest ciemniejsza niż na górze, a może także pewna wariacja między lewą i prawą linią.Jak mogę nadać elementowi WPF prostokątną, płaską granicę 3D?

Bardziej złożona wersja pozwalałaby na dostarczenie pędzli lub większej liczby pędzli, aby można było zastosować gradienty.

Domyślny element <Border> w WPF pozwala określić inną grubość na krawędzi, ale nie mogę znaleźć sposobu na określenie wielu pędzli.

Jak więc uzyskać efekt, który chcę, tak prosto, jak to możliwe?

EDIT to sugerowano, że mogę napisać przykład jak chcę to wykorzystać. Osobiście chciałbym mieć styl lub kontrolę użytkownika. Kontrola użytkownika może być wykorzystane w następujący sposób:

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

Albo jeszcze prościej:

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

Są to tylko pomysły. Wszelkie rozsądne, zwięzłe rozwiązanie jest mile widziane.

Odpowiedz

11

Oto rozwiązanie, które opracowałem, które pozwala osiągnąć większość potrzebnych informacji. Nie zapewnia on całkowitej kontroli nad wszystkimi czterema stronami niezależnie, ale daje prostokątny, płaski widok 3D, który chcę.

Oto jak to wygląda:

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

Wklej to pod Kaxaml zobaczyć to na własne oczy:

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

nadzieję, że pomoże ktoś inny się. Wciąż szukam innowacyjnych rozwiązań tego problemu, więc publikuj posty, a ja przyjmuję lepszą odpowiedź niż ta.

3

Szczerze mówiąc najprawdopodobniej najłatwiej byłoby zastosować techniki nakładania warstw. Na przykład utwórz taką siatkę:

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

Myślę, że wpadłeś na pomysł. Jest to prawdopodobnie najłatwiejszy sposób robienia tego. Możesz ustawić to jako szablon i używać go w ten sposób:

<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

jej chyba lepiej zrobić to z elementami Line i nie 4 Granice – Nir

+0

To naprawdę nie jest bardzo zwięzły. Mam nadzieję, że jest lepszy, prostszy sposób robienia tego, nawet po zastąpieniu granic liniami. –

+0

Nie jestem pewien, o ile prostsze może być. Jak możesz opublikować przykład, jak chcesz go użyć, a my zaczniemy od tego miejsca. – Micah

13

Zrobiłem coś takiego, umieszczając wiele ramek bezpośrednio jeden na drugim. Np .:

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

Zapewnia to dodatkową zaletę wszystkich innych funkcji, jakie zapewnia granica - promień naroża i inne.

+1

Aby dodać moje 0,02 USD, możesz zamienić wartości zerowe i niezerowe we właściwości 'BorderThickness' powyżej, aby uzyskać efekt zatopienia. – dotNET

1

można odwołać się do PresentationFramework.Klasyczny montaż, a następnie użyć

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

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

używałem this technique for looking at control templates zobaczyć jak standardowe przyciski zostały urządzone

Powiązane problemy