I made a little timer app using WPF and I wanted to put my app on the taskbar, but when I click anywhere on the taskbar, my app loses focus and the taskbar comes on top of my app, even though I have Topmost=True
in the XAML code.
How my app behaves:
And Windows clock app which behaves exactly the way that I want 🥺:
Is there any way to achieve this behavior in my WPF app?
The XAML code:
<Window x:Class="MultiStopwatch.StopwatchWindow"
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:utility="clr-namespace:MultiStopwatch.Utility"
mc:Ignorable="d"
Title="MultiStopwatchWindow"
WindowStyle="None" AllowsTransparency="True" Background="Transparent" ResizeMode="NoResize"
ShowInTaskbar="False" Topmost="True" Height="28" Width="112"
utility:EnableDragHelper.EnableDrag="True">
<Window.Clip>
<RectangleGeometry Rect="0,0,112,28" RadiusX="5.5" RadiusY="5.5" />
</Window.Clip>
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="assets/Icons.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
<Grid>
<Border Background="Black" CornerRadius="4">
<Grid>
<Button x:Name="StartBtn" Margin="0,0,83,0" Width="21" Height="21" Cursor="Hand"
Click="StartBtn_OnClick">
<Button.Template>
<ControlTemplate TargetType="Button">
<Border x:Name="StartBtnBorder" Background="#333333" CornerRadius="3" Padding="3.5"
RenderTransformOrigin="0.5,0.5">
<Border.RenderTransform>
<ScaleTransform />
</Border.RenderTransform>
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation Storyboard.TargetName="StartBtnBorder"
Storyboard.TargetProperty="(Border.Background).(SolidColorBrush.Color)"
To="#454545" Duration="0:0:0.13" />
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation Storyboard.TargetName="StartBtnBorder"
Storyboard.TargetProperty="(Border.Background).(SolidColorBrush.Color)"
To="#333333" Duration="0:0:0.13" />
</Storyboard>
</BeginStoryboard>
</Trigger.ExitActions>
</Trigger>
<EventTrigger RoutedEvent="Button.Click">
<BeginStoryboard>
<Storyboard>
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="StartBtnBorder"
Storyboard.TargetProperty="(Border.RenderTransform).(ScaleTransform.ScaleX)">
<EasingDoubleKeyFrame KeyTime="0:0:0" Value="0.9" />
<EasingDoubleKeyFrame KeyTime="0:0:0.09" Value="1" />
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="StartBtnBorder"
Storyboard.TargetProperty="(Border.RenderTransform).(ScaleTransform.ScaleY)">
<EasingDoubleKeyFrame KeyTime="0:0:0" Value="0.9" />
<EasingDoubleKeyFrame KeyTime="0:0:0.09" Value="1" />
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Button.Template>
<Grid>
<Image x:Name="StartBtnIcon" Source="{StaticResource StartDrawingImage}" />
</Grid>
</Button>
<Button x:Name="ResetButton" Margin="0,0,37,0" Width="21" Height="21" Cursor="Hand"
Click="ResetButton_OnClick">
<Button.Template>
<ControlTemplate TargetType="Button">
<Border x:Name="ResetBtnBorder" Background="#333333" CornerRadius="3" Padding="3"
RenderTransformOrigin="0.5,0.5">
<Border.RenderTransform>
<ScaleTransform />
</Border.RenderTransform>
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation Storyboard.TargetName="ResetBtnBorder"
Storyboard.TargetProperty="(Border.Background).(SolidColorBrush.Color)"
To="#454545" Duration="0:0:0.15" />
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation Storyboard.TargetName="ResetBtnBorder"
Storyboard.TargetProperty="(Border.Background).(SolidColorBrush.Color)"
To="#333333" Duration="0:0:0.13" />
</Storyboard>
</BeginStoryboard>
</Trigger.ExitActions>
</Trigger>
<EventTrigger RoutedEvent="Button.Click">
<BeginStoryboard>
<Storyboard>
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="ResetBtnBorder"
Storyboard.TargetProperty="(Border.RenderTransform).(ScaleTransform.ScaleX)">
<EasingDoubleKeyFrame KeyTime="0:0:0" Value="0.9" />
<EasingDoubleKeyFrame KeyTime="0:0:0.09" Value="1" />
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="ResetBtnBorder"
Storyboard.TargetProperty="(Border.RenderTransform).(ScaleTransform.ScaleY)">
<EasingDoubleKeyFrame KeyTime="0:0:0" Value="0.9" />
<EasingDoubleKeyFrame KeyTime="0:0:0.09" Value="1" />
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Button.Template>
<Grid>
<Image Source="{StaticResource ResetDrawingImage}" />
</Grid>
</Button>
<TextBox x:Name="FirstStopwatchTextBox" IsReadOnly="True" SelectionBrush="Transparent"
FontSize="12" BorderThickness="0" Cursor="SizeAll" TextAlignment="Center"
FontFamily="JetBrains Mono" FontWeight="SemiBold" Foreground="#DCDCDC"
Background="Transparent" Height="15" Margin="48,6,0,6" Text="00:00:00" />
</Grid>
</Border>
</Grid>
</Window>
Edit:
I've tried using the Window.Activate();
but it only works for the first click on the taskbar, and on top of that, it doesn't work nicely... it forces the focus on the app and doesn't allow the focus to be transferred to another app on the first click, which is really bad. In the gif below I tried to show how it behaves. Notice that on the first click, the app is still on top, but on the second click the app goes behind the taskbar again. And notice how the focus doesn't go onto Visual Studio on the first click, but when I click one more time, the text cursor (caret) appears on my code and the focus is now fully on Visual Studio. This doesn't happen with the Windows clock app, if you click outside the app once, the focus is immediately transferred to that other app (while it is still on top of everything).