How to resize a borderless window from top only? - c#

I am creating a WPF application and want my window to be borderless, and also possible to be resized only from the top.
What I have tried so far
I initially thought this would work:
<Window x:Class="WpfApplication3.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Width="200" Height="150"
WindowStyle="None"
ResizeMode="CanResize"
AllowsTransparency="True"
BorderThickness="0,5,0,0"
BorderBrush="Black">
<Grid Background="Gray" />
</Window>
I do get a window with top border only, but I cannot resize it.
Then I tried WindowChrome.ResizeGripDirection="Top" with ResizeMode="CanResizeWithGrip".
<Window ...
WindowStyle="None"
ResizeMode="CanResizeWithGrip"
AllowsTransparency="True"
WindowChrome.ResizeGripDirection="Top"
BorderThickness="0,5,0,0"
BorderBrush="Black">
...
</Window>
This does not work either (unable to resize from top border), and the grip does not even appear on top. It stays on the bottom-right corner (I can resize with the grip, though).
This answer seems like the answerer may initially have done this, but the code is unavailable.
This answer has a link to a blog post, I am not too eager to try it because I would like a solution without code behind.
And then there is this answer:
I get an error with this approach:
<Window ...
WindowStyle="None"
ResizeMode="CanResizeWithGrip"
AllowsTransparency="False">
<Grid Background="Gray" />
<Setter Property="WindowChrome.WindowChrome">
<Setter.Value>
<WindowChrome CornerRadius="0"
GlassFrameThickness="1"
UseAeroCaptionButtons="False"/>
</Setter.Value>
</Setter>
</Window>
The property 'Content' is set more than once.
With code behind:
<Window ...
WindowStyle="None"
ResizeMode="CanResize"
AllowsTransparency="False">
<Grid Background="Gray" />
</Window>
In constructor:
WindowChrome chrome = new WindowChrome();
chrome.CornerRadius = new CornerRadius(0);
chrome.GlassFrameThickness = new Thickness(0, 1, 0, 0);
chrome.UseAeroCaptionButtons = false;
Which gives me:
And this could be resized from all directions. And I only want it to be able to resize from top. (Surprise: I did not even assign the new chrome object to anything. How did that work? That's another question I guess).
Question
How do I make a borderless window which can only be resized with the top border? (It's best if I can do this with only a top border whose color could be changed).

You may have success setting the WindowChrome.ResizeBorderThickness property to remove all borders except the top, e.g. ResizeBorderThickness="0, 5, 0, 0".
It may not be the cleanest way to achieve your result, but I've had some success adapting the answer here: http://www.eidias.com/blog/2014/1/27/restyle-your-window (it was the easiest way I found to get WindowChrome working):
Create a custom window style in a ResourceDictionary:
<ResourceDictionary x:Class="WpfApplication.WindowStyle"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Style x:Key="CustomWindowStyle" TargetType="{x:Type Window}">
<Setter Property="WindowChrome.WindowChrome">
<Setter.Value>
<WindowChrome CaptionHeight="30"
CornerRadius="4"
GlassFrameThickness="0"
ResizeBorderThickness="0, 5, 0, 0"
UseAeroCaptionButtons="False" />
</Setter.Value>
</Setter>
<Setter Property="Window.BorderThickness" Value="0, 5, 0, 0" /
</Style>
</ResourceDictionary>
Reference the dictionary where required (I put it in App.xaml):
<Application x:Class="WpfApplication1.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApplication1"
StartupUri="MainWindow.xaml">
<Application.Resources>
<ResourceDictionary Source="WindowStyle.xaml" />
</Application.Resources>
</Application>
Reference the Style in the required Window:
<Window x:Class="WpfApplication1.MainWindow"
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:WpfApplication1"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525"
Style="{StaticResource ResourceKey=CustomWindowStyle}">
<Grid>
</Grid>
</Window>
That should produce a window that looks like your final one, but can only be resized from the top (only the top resize handle can be grabbed).

Related

WPF Custom Fonts is not showing on the Design Window

I'm working on a WPF application using C#. So far, I have added a custom font using a ResourceDictionary on my application. When I run the app I can see the font works fine, but on the Design tab of my XAML it always shows the default font. Could I be missing something to set my designer correctly?
App.xaml
<Application x:Class="Bali.Chat.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:Bali.Chat"
StartupUri="MainWindow.xaml">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Styles/Fonts.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>
Fonts.xaml
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<FontFamily x:Key="LatoRegular">pack://application;,,,/Fonts/#Lato Regular</FontFamily>
<FontFamily x:Key="LatoThin">pack://application;,,,/Fonts/#Lato Thin</FontFamily>
</ResourceDictionary>
MainWindow.xaml
<Window x:Class="Bali.Chat.MainWindow"
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:Bali.Chat"
mc:Ignorable="d"
Icon="Images/Logo/logo-small.png"
WindowStyle="None"
AllowsTransparency="True"
Title="Bali Chat"
Height="250" Width="400">
<StackPanel>
<TextBlock Text="Default Font!" FontSize="40" />
<TextBlock Text="Thin Font" FontSize="40" FontFamily="{StaticResource LatoThin}" />
<TextBlock Text="Regular Font" FontSize="40" FontFamily="{StaticResource LatoRegular}" />
</StackPanel>
</Window>
This is what I get on my designer
And this is what I get if I run the application
I really would like to preview what I'm trying to render without having to start the application or check it on the live preview. The tutorial I am following does show the presenter seeing the proper font in the designer, so I know there are some issues. Thanks in advance.

Ugly white border at top of window [duplicate]

Is it possible to remove the white strip on top of WPF window with Window Style=None. XAML and Window is shown in the screenshot:
What you are seeing in white is the re-size border. You can remove that and still make the window resizable by setting ResizeMode="CanResizeWithGrip" AllowsTransparency="True"
If you dont want to resize at all then do this - ResizeMode="NoResize", again you wont see the border but you cant resize.
<Window x:Class="HandsOnSolution.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525" Background="Green" WindowStyle="None" ResizeMode="CanResizeWithGrip" AllowsTransparency="True">
<Grid>
</Grid>
</Window>
Edit
Good point by #devuxer, if you are interested in dragging you can add this piece of code to the window mouse down event
<Window MouseLeftButtonDown="Window_MouseLeftButtonDown"/>
//code behind
private void Window_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
DragMove();
}
I had been hunting for a solution for a couple of days now, in simple words this link held the answer to my queries
though the code snippet that did the magic was:
<Setter Property="WindowChrome.WindowChrome">
<Setter.Value>
<WindowChrome CaptionHeight="0"
CornerRadius="2"
GlassFrameThickness="0"
NonClientFrameEdges="None"
ResizeBorderThickness="3"/>
</Setter.Value>
</Setter>
I just added the above property setter to the custom Window Style.
Hope that helped :)
A much simplified code, acting on only one property:
<WindowChrome.WindowChrome>
<WindowChrome CaptionHeight="0"/>
</WindowChrome.WindowChrome>
I added this piece of code:
<WindowChrome.WindowChrome>
<WindowChrome GlassFrameThickness="0,0,0,1" CornerRadius="0" />
</WindowChrome.WindowChrome>
inside <Window> paste here <Window/> and it helped :)

Why is there extra space on WPF?

this is in XAML Designer
Expected:
Actual:
This is my window's XAML:
<Window
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:WpfApp2"
xmlns:Wpf="clr-namespace:Microsoft.Web.WebView2.Wpf;assembly=Microsoft.Web.WebView2.Wpf" x:Class="WpfApp2.MainWindow"
mc:Ignorable="d"
ResizeMode="NoResize"
Title="MainWindow" SizeToContent="WidthAndHeight" AllowsTransparency="True" WindowStyle="None" Loaded="Window_Loaded">
<StackPanel>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
<StackPanel.Resources>
<Style TargetType="Button">
<Setter Property="Margin" Value="5, 0, 5, 0"></Setter>
<Setter Property="Height" Value="30"></Setter>
</Style>
</StackPanel.Resources>
<Button>测试</Button>
<Button>测试</Button>
<Button>测试</Button>
</StackPanel>
<Canvas Height="2" Background="Red" />
</StackPanel>
There is extra space around the window.
I found that as long as the height is less than 40, there will be extra space.But I didn't set minHeight.
this is my app.xaml:
<Application x:Class="WpfApp2.App" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApp2"
StartupUri="MainWindow.xaml">
<Application.Resources>
</Application.Resources>
my environmental information:
Windows 11
Visual Studio 2022
.net framework 4.8
In WPF SizeToContent does not work very well with WindowStyle=None. It seems the renderer is still taking a non-existant border into account when initially drawing the Window.
A simple hack to overcome this: set Height="1" on the Window to force its initial size to something smaller than the eventual size. Then when the content is rendered, SizeToContent="WidthAndHeight" will cause the window to resize itself to the correct size.

Adding a Usercontrol with a transparent Background to a Window

I have created a UserControl with some rounded edged Border as first real element. The actuall Background is transparent.
<UserControl
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:QP_WPF" x:Class="GUI_WPF_Interior"
xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"
xmlns:themes="clr-namespace:Xceed.Wpf.Toolkit.Themes;assembly=Xceed.Wpf.Toolkit"
mc:Ignorable="d"
DataContext="{Binding RelativeSource={RelativeSource Self}}"
d:DesignWidth="600
" Background="transparent">
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="ColorsAndBrushes.xaml" />
<ResourceDictionary Source="ControlTemplates.xaml"/>
</ResourceDictionary.MergedDictionaries>
</UserControl.Resources>
<Border Margin="10" Background="{StaticResource BG_GradientBrush_2}" CornerRadius="12,12,12,12">
....
(the Margin is only to provide a better visual for the problem)
Now I want to display this UserControl in a window. But the area that is used by the margin and the rounded edges stays white.
<Window x:Class="MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:qp="clr-namespace:QP_WPF;assembly=QP_WPF"
Title="MainWindow" Height="680" Width="600"
WindowStyle="None"
AllowsTransparency="True"
MouseLeftButtonDown="Window_MouseLeftButtonDown">
<Grid Background="Transparent">
<qp:GUI_WPF_Interior x:Name="GUIInterior" Background="Transparent"/>
</Grid>
</Window>
What do I need to doe so that the Window only displays my UserControls parts that are not transparent?
Try to add also background=transparent to the window besides AllowTransparency

Set padding of UserControl with assigned ControlTemplate?

I recently created an UserControl for my WrapPanel to visualize some data.
I applied a Padding to it in order to get some space between each element.
The first version looked like this:
<UserControl x:Class="IFCS.EntityOverviewPanel"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:l="clr-namespace:IFCS"
mc:Ignorable="d"
Padding="5, 5, 5, 5"
d:DesignHeight="300" d:DesignWidth="300">
<!-- Code -->
</UserControl>
Now I just applied a ControlTemplate to it which overrides my Padding setting.
The current version looks like this:
<UserControl x:Class="IFCS.EntityOverviewPanel"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:l="clr-namespace:IFCS"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<UserControl.Template>
<ControlTemplate TargetType="UserControl">
<!-- Code -->
</ControlTemplate>
</UserControl.Template>
</UserControl>
I would like to apply Padding to my UserControl again but everything I tried didn't work.
I tried to apply a Style using
<UserControl.Style>
<Style TargetType="{x:Type UserControl}">
<Setter Property="Padding" Value="5, 5, 5, 5"/>
</Style>
</UserControl.Style>
but this didn't work.
Setting the Padding in the "header" isn't working too.
Where do I have to set the Padding value in order to achieve the same result as in the first version?
<UserControl Padding="5,5,5,5">
<UserControl.Template>
<ControlTemplate TargetType="UserControl">
<ContentPresenter Margin="{TemplateBinding Padding}" />
<!-- Code -->
</ControlTemplate>
</UserControl.Template>
<!-- Content -->
</UserControl>

Categories