Вот что хорошо сработало для меня. Я обнаружил, что закругленные углы добавили некоторые дополнительные проблемы с правильным созданием тени верхней области, но я смог добиться этого, комбинируя несколько приемов.
первая техника предполагает умное использование двух границ. Для внешней границы ClipToBounds
установлено значение true, а для внутренней границы DropShadowEffect
, для ShadowDepth
установлено значение 0 и BlurRadius
около 5. Это дает нам часть того, что нам нужно, но не решает проблему закругленных углов (мы вернемся к этому). Эту технику можно найти на этой статье . Вот суть этого:
<Border BorderBrush="DarkGray" BorderThickness="1" ClipToBounds="True">
<Border BorderBrush="Black" BorderThickness="1" Margin="-1">
<Border.Effect>
<DropShadowEffect ShadowDepth="0" BlurRadius="6">
</Border.Effect>
</Border>
</Border>
Если я правильно помню, в этот момент у нас будет что-то близкое к тому, что вы хотите, за исключением того, что DropShadowEffect
«кровоточит» из закругленных углов (опять же, мы скоро это рассмотрим).
Другая проблема, с которой мы столкнулись бы сейчас, заключается в том, что к любым дочерним элементам, которые мы помещаем во внутренний Border
, также будет применен DropShadowEffect
! Чтобы исправить эту проблему, нам понадобится вторая техника . Поместите два Borders
вместе с другим контейнером (для хранения вашего содержимого) в Grid
, чтобы внешний Border
и новый контейнер были братьями и сестрами. Это заставит братьев и сестер перекрывать друг друга, применяя только DropShadowEffect
к Border
. См. этот ответ .
Теперь обратимся к проблеме «кровотечения», когда DropShadowEffect
не следует контуру закругленных углов, а действует так, как если бы углы были прямыми. Для этого требуется третий метод . Нам нужно использовать пользовательский элемент управления Михаэля ClippingBorder . Нам нужно заменить вышеупомянутый внешний Border
элемент управления его ClippingBorder
, сохраняя для ClipToBounds
значение true. Это урежет кровотечение на закругленных углах.
Мне удалось объединить эти три метода , чтобы создать "утопленный" (или "вставленный") вид границы. Это выглядело примерно так:
<Grid>
<local:ClippingBorder x:Name="TopShadowClippingBorder"
BorderThickness="0"
CornerRadius="5"
ClipToBounds="True">
<Border x:Name="TopShadowBorder"
BorderBrush="#D8333333" BorderThickness=".5,1,.5,0"
Padding="0"
CornerRadius="5"
ClipToBounds="True">
<Border.Effect>
<DropShadowEffect Direction="270" ShadowDepth="0.5"/>
</Border.Effect>
</Border>
</local:ClippingBorder>
<Border x:Name="InsetBorder"
BorderBrush="#99A1A1A1" BorderThickness="0.5,0,0.5,1"
CornerRadius="5" />
<StackPanel x:Name="Contents_StackPanel" Orientation="Horizontal" Margin="5,5,5,5">
(Contents go here...)
</StackPanel>
</Grid>
Обратите внимание, что верхний "свет" (DropShadowEffect) хорошо повторяет контур закругленного угла границы: