Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 16 additions & 2 deletions src/Wpf.Ui/Controls/ComboBox/ComboBox.xaml
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -181,10 +181,10 @@
<Border <Border
x:Name="ContentBorder" x:Name="ContentBorder"
Grid.Row="0" Grid.Row="0"
MinWidth="{TemplateBinding MinWidth}"
MinHeight="{TemplateBinding MinHeight}"
Width="{TemplateBinding Width}" Width="{TemplateBinding Width}"
Height="{TemplateBinding Height}" Height="{TemplateBinding Height}"
MinWidth="{TemplateBinding MinWidth}"
MinHeight="{TemplateBinding MinHeight}"
Padding="0" Padding="0"
HorizontalAlignment="Stretch" HorizontalAlignment="Stretch"
VerticalAlignment="Stretch" VerticalAlignment="Stretch"
Expand Down Expand Up @@ -262,6 +262,10 @@
Placement="{TemplateBinding Popup.Placement}" Placement="{TemplateBinding Popup.Placement}"
PopupAnimation="{TemplateBinding Popup.PopupAnimation}" PopupAnimation="{TemplateBinding Popup.PopupAnimation}"
VerticalOffset="1"> VerticalOffset="1">
<controls:EffectThicknessDecorator
AnimationDelay="00:00:00.167"
AnimationElement="{Binding ElementName=DropDownBorder}"
Thickness="30,0,30,30">
<Border <Border
x:Name="DropDownBorder" x:Name="DropDownBorder"
MinWidth="{TemplateBinding ActualWidth}" MinWidth="{TemplateBinding ActualWidth}"
Expand All @@ -275,6 +279,15 @@
<Border.RenderTransform> <Border.RenderTransform>
<TranslateTransform /> <TranslateTransform />
</Border.RenderTransform> </Border.RenderTransform>
<Border.Effect>
<DropShadowEffect
BlurRadius="20"
Direction="270"
Opacity="0.135"
ShadowDepth="10"
Color="#202020" />
</Border.Effect>

<Grid> <Grid>
<controls:DynamicScrollViewer <controls:DynamicScrollViewer
MaxHeight="{TemplateBinding MaxDropDownHeight}" MaxHeight="{TemplateBinding MaxDropDownHeight}"
Expand All @@ -292,6 +305,7 @@
</controls:DynamicScrollViewer> </controls:DynamicScrollViewer>
</Grid> </Grid>
</Border> </Border>
</controls:EffectThicknessDecorator>
</Popup> </Popup>
</Grid> </Grid>
</Border> </Border>
Expand Down
15 changes: 14 additions & 1 deletion src/Wpf.Ui/Controls/ContextMenu/ContextMenu.xaml
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@
All Rights Reserved. All Rights Reserved.
--> -->


<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> <ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="clr-namespace:Wpf.Ui.Controls">


<Style x:Key="UiContextMenu" TargetType="{x:Type ContextMenu}"> <Style x:Key="UiContextMenu" TargetType="{x:Type ContextMenu}">
<Setter Property="TextElement.Foreground" Value="{DynamicResource ContextMenuForeground}" /> <Setter Property="TextElement.Foreground" Value="{DynamicResource ContextMenuForeground}" />
Expand All @@ -23,13 +26,22 @@
<Setter Property="Template"> <Setter Property="Template">
<Setter.Value> <Setter.Value>
<ControlTemplate TargetType="{x:Type ContextMenu}"> <ControlTemplate TargetType="{x:Type ContextMenu}">
<controls:EffectThicknessDecorator Thickness="30">
<Border <Border
x:Name="Border" x:Name="Border"
Padding="0,3,0,3" Padding="0,3,0,3"
Background="{TemplateBinding Background}" Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}" BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="1" BorderThickness="1"
CornerRadius="8"> CornerRadius="8">
<Border.Effect>
<DropShadowEffect
BlurRadius="20"
Direction="270"
Opacity="0.135"
ShadowDepth="10"
Color="#202020" />
</Border.Effect>
<Border.RenderTransform> <Border.RenderTransform>
<TranslateTransform /> <TranslateTransform />
</Border.RenderTransform> </Border.RenderTransform>
Expand All @@ -39,6 +51,7 @@
KeyboardNavigation.DirectionalNavigation="Cycle" KeyboardNavigation.DirectionalNavigation="Cycle"
Orientation="Vertical" /> Orientation="Vertical" />
</Border> </Border>
</controls:EffectThicknessDecorator>
<ControlTemplate.Triggers> <ControlTemplate.Triggers>
<Trigger Property="IsOpen" Value="True"> <Trigger Property="IsOpen" Value="True">
<Trigger.EnterActions> <Trigger.EnterActions>
Expand Down
191 changes: 191 additions & 0 deletions src/Wpf.Ui/Controls/EffectThicknessDecorator.cs
Original file line number Original file line Diff line number Diff line change
@@ -0,0 +1,191 @@
// This Source Code Form is subject to the terms of the MIT License.
// If a copy of the MIT was not distributed with this file, You can obtain one at https://opensource.org/licenses/MIT.
// Copyright (C) Leszek Pomianowski and WPF UI Contributors.
// All Rights Reserved.

using System.Windows.Controls;
using System.Windows.Controls.Primitives;

namespace Wpf.Ui.Controls;

public class EffectThicknessDecorator : Decorator
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider giving this class a doc block (explaining the purpose) that effectively repeats this part from the PR:

This is because effects get clipped. [..] The solution is to add a decorator that wraps around it.

{
public static readonly DependencyProperty ThicknessProperty =
DependencyProperty.Register(nameof(Thickness), typeof(Thickness), typeof(EffectThicknessDecorator), new PropertyMetadata(new Thickness(35), OnThicknessChanged));

public static readonly DependencyProperty AnimationDelayProperty =
DependencyProperty.Register(nameof(AnimationDelay), typeof(TimeSpan), typeof(EffectThicknessDecorator), new PropertyMetadata(TimeSpan.Zero));

public static readonly DependencyProperty AnimationElementProperty =
DependencyProperty.Register(nameof(AnimationElement), typeof(UIElement), typeof(EffectThicknessDecorator), new PropertyMetadata(default(UIElement)));

private PopupContainer? _popupContainer;

public EffectThicknessDecorator()
{
SizeChanged += (_, _) => UpdateLayout();
}

public TimeSpan AnimationDelay
{
get { return (TimeSpan)GetValue(AnimationDelayProperty); }
set { SetValue(AnimationDelayProperty, value); }
}

public UIElement? AnimationElement
{
get { return (UIElement?)GetValue(AnimationElementProperty); }
set { SetValue(AnimationElementProperty, value); }
}

/// <summary>
/// Gets or sets the thickness of the effect around the containing element.
/// </summary>
public Thickness Thickness
{
get { return (Thickness)GetValue(ThicknessProperty); }
set { SetValue(ThicknessProperty, value); }
}

/// <inheritdoc />
protected override int VisualChildrenCount => 1;

/// <inheritdoc />
protected override void OnVisualParentChanged(DependencyObject oldParent)
{
base.OnVisualParentChanged(oldParent);

if (IsInitialized)
{
SetPopupContainer();
}
}

/// <inheritdoc />
protected override Visual GetVisualChild(int index)
{
// Only 1 child...
return Child;
}

/// <inheritdoc />
protected override void OnInitialized(EventArgs e)
{
base.OnInitialized(e);

SetPopupContainer();
}

private void SetPopupContainer()
{
PopupContainer? popupContainer = null;

switch (VisualParent)
{
case ContextMenu contextMenu:
popupContainer = new PopupContainer(contextMenu);
break;
case ToolTip toolTip:
popupContainer = new PopupContainer(toolTip);
break;
default:
if (GetParentPopup(this) is { } parentPopup)
{
popupContainer = new PopupContainer(parentPopup);
}

break;
}

if (popupContainer == null || _popupContainer?.FrameworkElement == popupContainer.FrameworkElement)
{
return;
}

popupContainer.Opened += (_, _) =>
{
if (AnimationElement is { Effect: { } effect } animationElement && AnimationDelay.Ticks > 0)
{
animationElement.Effect = null;

Task.Delay(AnimationDelay).ContinueWith(_ => Dispatcher.Invoke(() => animationElement.Effect = effect));
}
};

_popupContainer = popupContainer;
ApplyMargin();
}

private static Popup? GetParentPopup(FrameworkElement element)
{
while (true)
{
switch (element.Parent)
{
case Popup popup:
return popup;
case FrameworkElement frameworkElement:
element = frameworkElement;
continue;
}

if (VisualTreeHelper.GetParent(element) is FrameworkElement parent)
{
element = parent;
continue;
}

return null;
}
}

private static void OnThicknessChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (d is EffectThicknessDecorator decorator)
{
decorator.ApplyMargin();
}
}

private void ApplyMargin()
{
_popupContainer?.SetMargin(Thickness);
}

private class PopupContainer
{
private readonly ContextMenu? _contextMenu;
private readonly Popup? _popup;
private readonly ToolTip? _toolTip;

public PopupContainer(ContextMenu contextMenu)
{
_contextMenu = contextMenu;
contextMenu.Opened += (sender, args) => Opened?.Invoke(sender, args);
}

public PopupContainer(ToolTip toolTip)
{
_toolTip = toolTip;
toolTip.Opened += (sender, args) => Opened?.Invoke(sender, args);
}

public PopupContainer(Popup popup)
{
_popup = popup;
popup.Opened += (sender, args) => Opened?.Invoke(sender, args);
}

public event EventHandler Opened;

public FrameworkElement? FrameworkElement => _contextMenu ?? _toolTip ?? _popup?.Child as FrameworkElement;

public void SetMargin(Thickness margin)
{
if (FrameworkElement is { } frameworkElement)
{
frameworkElement.Margin = margin;
}
}
}
}
22 changes: 13 additions & 9 deletions src/Wpf.Ui/Controls/Menu/MenuItem.xaml
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -108,8 +108,9 @@
<DropShadowEffect <DropShadowEffect
BlurRadius="20" BlurRadius="20"
Direction="270" Direction="270"
Opacity="0.25" Opacity="0.135"
ShadowDepth="6" /> ShadowDepth="10"
Color="#202020" />
</Border.Effect> </Border.Effect>
</Border> </Border>
</Grid> </Grid>
Expand Down Expand Up @@ -399,7 +400,7 @@
<Grid> <Grid>
<Border <Border
x:Name="SubmenuBorder" x:Name="SubmenuBorder"
Margin="12,10,12,18" Margin="12,10,12,30"
Padding="0,3,0,3" Padding="0,3,0,3"
Background="{DynamicResource FlyoutBackground}" Background="{DynamicResource FlyoutBackground}"
BorderBrush="{DynamicResource FlyoutBorderBrush}" BorderBrush="{DynamicResource FlyoutBorderBrush}"
Expand All @@ -416,8 +417,9 @@
<DropShadowEffect <DropShadowEffect
BlurRadius="20" BlurRadius="20"
Direction="270" Direction="270"
Opacity="0.5" Opacity="0.135"
ShadowDepth="6" /> ShadowDepth="10"
Color="#202020" />
</Border.Effect> </Border.Effect>
</Border> </Border>
</Grid> </Grid>
Expand Down Expand Up @@ -584,8 +586,9 @@
<DropShadowEffect <DropShadowEffect
BlurRadius="20" BlurRadius="20"
Direction="270" Direction="270"
Opacity="0.25" Opacity="0.135"
ShadowDepth="6" /> ShadowDepth="10"
Color="#202020" />
</Border.Effect> </Border.Effect>
</Border> </Border>
</Grid> </Grid>
Expand Down Expand Up @@ -906,8 +909,9 @@
<DropShadowEffect <DropShadowEffect
BlurRadius="20" BlurRadius="20"
Direction="270" Direction="270"
Opacity="0.5" Opacity="0.135"
ShadowDepth="6" /> ShadowDepth="10"
Color="#202020" />
</Border.Effect> </Border.Effect>
</Border> </Border>
</Grid> </Grid>
Expand Down
15 changes: 10 additions & 5 deletions src/Wpf.Ui/Controls/ToolTip/ToolTip.xaml
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@
All Rights Reserved. All Rights Reserved.
--> -->


<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> <ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="clr-namespace:Wpf.Ui.Controls">


<Style x:Key="DefaultToolTipStyle" TargetType="{x:Type ToolTip}"> <Style x:Key="DefaultToolTipStyle" TargetType="{x:Type ToolTip}">
<Setter Property="MaxWidth" Value="260" /> <Setter Property="MaxWidth" Value="260" />
Expand All @@ -22,6 +25,7 @@
<Setter Property="Template"> <Setter Property="Template">
<Setter.Value> <Setter.Value>
<ControlTemplate TargetType="ToolTip"> <ControlTemplate TargetType="ToolTip">
<controls:EffectThicknessDecorator Thickness="15">
<Border <Border
Name="Border" Name="Border"
Width="{TemplateBinding Width}" Width="{TemplateBinding Width}"
Expand All @@ -35,10 +39,10 @@
SnapsToDevicePixels="True"> SnapsToDevicePixels="True">
<Border.Effect> <Border.Effect>
<DropShadowEffect <DropShadowEffect
BlurRadius="30" BlurRadius="10"
Direction="0" Direction="270"
Opacity="0.4" Opacity="0.135"
ShadowDepth="0" ShadowDepth="5"
Color="#202020" /> Color="#202020" />
</Border.Effect> </Border.Effect>
<ContentPresenter <ContentPresenter
Expand All @@ -52,6 +56,7 @@
</ContentPresenter.Resources> </ContentPresenter.Resources>
</ContentPresenter> </ContentPresenter>
</Border> </Border>
</controls:EffectThicknessDecorator>
</ControlTemplate> </ControlTemplate>
</Setter.Value> </Setter.Value>
</Setter> </Setter>
Expand Down