Skip to content

fix(controls): Tooltips, context menu, and comboboxes drop shadow#1472

Merged
pomianowski merged 6 commits into
lepoco:mainfrom
Nuklon:branch-7
Nov 7, 2025
Merged

fix(controls): Tooltips, context menu, and comboboxes drop shadow#1472
pomianowski merged 6 commits into
lepoco:mainfrom
Nuklon:branch-7

Conversation

@Nuklon
Copy link
Copy Markdown
Collaborator

@Nuklon Nuklon commented Jul 3, 2025

Pull request type

Please check the type of change your PR introduces:

  • Update
  • Bugfix
  • Feature
  • Code style update (formatting, renaming)
  • Refactoring (no functional changes, no api changes)
  • Build related changes
  • Documentation content changes

What is the current behavior?

Currently, the drop shadow used by tooltips and context menus are broken. This is because effects get clipped.
image

What is the new behavior?

The solution is to add a decorator that wraps around it. I also updated the dropshadows to follow original colors (they were far too dark). The tooltips have less shadow than context menus in WinUI.

image
image

@Nuklon Nuklon requested a review from pomianowski as a code owner July 3, 2025 11:51
@github-actions github-actions Bot added controls Changes to the appearance or logic of custom controls. styles Topic is related to styles PR Pull request dotnet release labels Jul 3, 2025
@Nuklon
Copy link
Copy Markdown
Collaborator Author

Nuklon commented Jul 3, 2025

@pomianowski best viewed without whitespace changes:
https://github.com/lepoco/wpfui/pull/1472/files?diff=split&w=1

@Difegue
Copy link
Copy Markdown
Contributor

Difegue commented Jul 7, 2025

Have you considered adding this change to ComboBoxes as well?
image

I believe all you need is the following:
wpfui-12-20-21.patch

EDIT: Seems like wrapping the ComboBox popup in EffectThicknessDecorator breaks its animation a bit for some reason.. Might need some additional changes so feel free to ignore me 😓

@Nuklon
Copy link
Copy Markdown
Collaborator Author

Nuklon commented Jul 7, 2025

Have you considered adding this change to ComboBoxes as well? image

I believe all you need is the following: wpfui-12-20-21.patch

EDIT: Seems like wrapping the ComboBox popup in EffectThicknessDecorator breaks its animation a bit for some reason.. Might need some additional changes so feel free to ignore me 😓

Yes, with animations there are some issues due to added margins, and the translation gets rendered above the combobox. There are some possibilities:

  1. Remove TranslateTransform of dropdown.
  2. Change TranslateTransform to ScaleTransform (looks OK, but with very long comboboxes it's not as similar to WinUI).
  3. Accept a slight UI clipping issue. If you use EffectThicknessDecorator with Thickness="30,0,30,30" (the shadow is only added below and to the sides of the element) the shadow clips a little below the combobox until the animation is done. This might be acceptable. This is very simple and you can basically keep all code as-is.
  4. 3 and then delay adding the dropshadow. This is also done by WinUI, which only adds shadow when it's fully expanded, so I think this is the best solution.

I'll commit some changes for this.

@Nuklon Nuklon changed the title Fix tooltips and context menu drop shadow Fix tooltips, context menu, and comboboxes drop shadow Jul 7, 2025
@Nuklon Nuklon mentioned this pull request Aug 23, 2025
7 tasks

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.

@github-actions github-actions Bot added the ⭐ top pull request Top pull request. label Aug 26, 2025
@pomianowski pomianowski changed the title Fix tooltips, context menu, and comboboxes drop shadow fix(controls): Tooltips, context menu, and comboboxes drop shadow Nov 7, 2025
@pomianowski pomianowski merged commit 3139927 into lepoco:main Nov 7, 2025
1 check passed
@Paper-Folding
Copy link
Copy Markdown

Is it because of this PR that makes context menu's text looks blurry?

@Nuklon Nuklon deleted the branch-7 branch April 17, 2026 11:22
@Nuklon
Copy link
Copy Markdown
Collaborator Author

Nuklon commented Apr 17, 2026

Is it because of this PR that makes context menu's text looks blurry?

No.

@Paper-Folding
Copy link
Copy Markdown

Yes, it is.
Previous Commit 9db01ba:
ok

Commit 3139927
blur

@Paper-Folding
Copy link
Copy Markdown

Paper-Folding commented Apr 18, 2026

Looks like the DropShadowEffect will make text and icon blurry: 3139927#diff-c2ffce67d872f01fafcce3aead9cab9d620c14ef6610958fb8fc19729e446665R38
Can we add an option to disable that?

@Nuklon
Copy link
Copy Markdown
Collaborator Author

Nuklon commented Apr 18, 2026

Not on any of my PCs.

image image

FWIW, this DropShadowEffect was already present in previous code, the only difference is that it now adds a margin around the element to show the entire effect.

If you can create a reproducible sample, I'm happy to investigate.

@Nuklon
Copy link
Copy Markdown
Collaborator Author

Nuklon commented Apr 18, 2026

Have you changed UseLayoutRounding or SnapsToDevicePixels somewhere?
You can try experimenting with this code in ContextMenu.xaml (Line 48) in WPF UI:

                            <StackPanel
                                ClipToBounds="True"
                                IsItemsHost="True"
                                KeyboardNavigation.DirectionalNavigation="Cycle"
                                Orientation="Vertical"
                                SnapsToDevicePixels="True"
                                UseLayoutRounding="True" />

@Nuklon
Copy link
Copy Markdown
Collaborator Author

Nuklon commented Apr 18, 2026

Alternative idea in ContextMenu.xaml:

        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type ContextMenu}">
                    <controls:EffectThicknessDecorator Thickness="30">
                        <Grid x:Name="Grid">
                            <Grid.RenderTransform>
                                <TranslateTransform />
                            </Grid.RenderTransform>
                            <Border
                                x:Name="Border"
                                Padding="0,3,0,3"
                                Background="{TemplateBinding Background}"
                                BorderBrush="{TemplateBinding BorderBrush}"
                                BorderThickness="1"
                                CornerRadius="8">
                                <Border.Effect>
                                    <DropShadowEffect
                                        BlurRadius="20"
                                        Direction="270"
                                        Opacity="0.135"
                                        ShadowDepth="10"
                                        Color="#202020" />
                                </Border.Effect>
                            </Border>
                            <StackPanel
                                Margin="1,4,1,4"
                                ClipToBounds="True"
                                IsItemsHost="True"
                                KeyboardNavigation.DirectionalNavigation="Cycle"
                                Orientation="Vertical" />
                        </Grid>
                    </controls:EffectThicknessDecorator>
                    <ControlTemplate.Triggers>
                        <Trigger Property="IsOpen" Value="True">
                            <Trigger.EnterActions>
                                <BeginStoryboard>
                                    <Storyboard>
                                        <DoubleAnimation
                                            Storyboard.TargetName="Grid"
                                            Storyboard.TargetProperty="(Grid.RenderTransform).(TranslateTransform.Y)"
                                            From="-90"
                                            To="0"
                                            Duration="00:00:00.167">
                                            <DoubleAnimation.EasingFunction>
                                                <CircleEase EasingMode="EaseOut" />
                                            </DoubleAnimation.EasingFunction>
                                        </DoubleAnimation>
                                    </Storyboard>
                                </BeginStoryboard>
                            </Trigger.EnterActions>
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>

@Paper-Folding
Copy link
Copy Markdown

Paper-Folding commented Apr 18, 2026

Not on any of my PCs.

image image
FWIW, this DropShadowEffect was already present in previous code, the only difference is that it now adds a margin around the element to show the entire effect.

If you can create a reproducible sample, I'm happy to investigate.

Sure, you don't know how easy it is to re-produce, here is code:

TempWindow.xaml

<Window x:Class="Sample.TempWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:Sample"
        xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml"
        mc:Ignorable="d"
        Title="TempWindow" Height="450" Width="800">
    <Window.ContextMenu>
        <ContextMenu>
            <MenuItem Header="File"/>
            <ui:MenuItem
                 Header="Hello World"
                 Icon="{ui:SymbolIcon ArrowReset24, Filled=False}" />
            <ui:MenuItem
                 Header="Hello WPF.UI"
                 Icon="{ui:SymbolIcon ArrowReset24, Filled=False}" />
        </ContextMenu>
    </Window.ContextMenu>
    <Grid>
    </Grid>
</Window>

TempWindow.xaml.cs

using System.Windows;

namespace Sample{
    public partial class TempWindow: Window {
        public TempWindow() {
            InitializeComponent();
        }
    }
}

App.xaml

<Application x:Class="Sample.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:local="clr-namespace:Sample"
             xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml"
             StartupUri="TempWindow.xaml">
    <Application.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ui:ThemesDictionary Theme="Dark" />
                <ui:ControlsDictionary />
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Application.Resources>
</Application>

@Paper-Folding
Copy link
Copy Markdown

Paper-Folding commented Apr 18, 2026

As I explore further, I found the issue happens only on a WPF window that is NOT extending FluentWindow.

@Nuklon
Copy link
Copy Markdown
Collaborator Author

Nuklon commented Apr 18, 2026

As I explore further, I found the issue happens only on a WPF window that is NOT extending FluentWindow.

Try setting this in your Window:

SnapsToDevicePixels="True"
UseLayoutRounding="True"

@Paper-Folding
Copy link
Copy Markdown

As I explore further, I found the issue happens only on a WPF window that is NOT extending FluentWindow.

Try setting this in your Window:

SnapsToDevicePixels="True"
UseLayoutRounding="True"

Thanks, this did solve the problem.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

controls Changes to the appearance or logic of custom controls. dotnet PR Pull request release ⭐ top pull request Top pull request. styles Topic is related to styles

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants