I've created a borderless WPF window by setting the following window properties in XAML:
... WindowStyle="None" AllowsTransparency="True" ...
This causes a number of issues:
1) Resolved: It no longer has any built-in resize functionality
2) Resolved: It no longer has any built-in drag functionality
3) Resolved: Without the top toolbar, it no longer has minimize/maximize/restore/close buttons
4) Resolved: Maximizing via aero snap or setting WindowState prevents it from unsnapping.
5) Maximizing via aero snap or setting WindowState will use the whole screen as the boundary, overlapping the windows toolbar.
6) Maximizing via aero snap or setting WindowState seems to include a -7 margin, giving the window 7 pixels on each side that are beyond the edges of the window.
1-3 were solved by making a xaml window template. I used invisible rectangles as handle regions, and some code behind that was applied via overriding OnApplyTemplate() to attach functionality via user32.dll SendMessage(...) for resize/move/minimize/maximize/restore/close.
I found the answer to # 4 here
I tried solving 5-6 by intercepting the maximize message via WndProc and setting the size/position manually, but this had the issue of overwriting the RestoreRegion to the maximized size/position, removing the ability to restore the window.
What's really odd is that resizing the window from the top border to the top of the screen triggers the aero full height snap just fine, with no issues at all.
So, I've come a long way, but 5-6 is still an issue... is there a way to manually specify the maximize region? Or, is there a way to set the window size without affecting the restoreregion property?
I just went through this entire thing myself. It was a real chore, because you have to manually account for so much. It's funny, we take so much for granted these days, with something as simple as how a basic window operates. But a look at this sample code that I am providing is a good indication of just how much really goes into this problem.
I hope this helps, as it took me a little time to get here myself.
MainWindow.Xaml
MainWindow.xaml.cs
for all these problems, I can only recommend this:
MahApps.Metro: http://mahapps.com/MahApps.Metro/
Sourcecode: https://github.com/MahApps/MahApps.Metro
it's a nice library with a nice theme and easy to use!
hope that helps
For Point number 5, use this:
This will ensure that the window will not overlap the taskbar when maximized.
You can specify the maximize region by handling the
WM_GETMINMAXINFO
Win32 message. The code here shows how to do that. It will solve issues #5 and #6.Note that there are a few things that I would do differently, such as returning
IntPtr.Zero
instead of (System.IntPtr)0 in WindowProc and makingMONITOR_DEFAULTTONEAREST
a constant. But that's just coding style changes, and doesn't affect the net result.Also make sure to pay attention to the update where the
WindowProc
is hooked during theSourceInitialized
event instead ofOnApplyTemplate
. That's the better place to do it. If you're implementing a class derived from Window, then another option is to overrideOnSourceInitialized
to hook theWindowProc
instead of attaching to the event. That's what I normally do.Hello, The following solution fixes all of the issues detailed in your question in the simplest manner possible, and works on Windows 10 using WPF and the latest version of the C# language and .NET framework. This is as of 3/15/2017. Please let me know if it stops working.
Step 1: To address issues 1, 2, and 4, within your
<Window ... > </Window>
tags in the XAML of your application, paste this in, at the top or bottom:CaptionHeight
is the desired height of your window dragging area.Step 2: To address issue 3, you need to create your title bar and caption as well as the window controls. To do this, you simply need to give the desired title bar elements each a VerticalAlignment of Top, or put them into a grid with it's VerticalAlignment set to Top, which will do it for all of them, but make sure that their heights are not greater than the
CaptionHeight
property on theWindowChrome
element declared in the XAML, from step 1. For all the buttons, you must assign them, or their container, the propertyWindowChrome.IsHitTestVisibleInChrome="True"
. Here is an example:Now, to add proper functionality to the window control buttons, within the
MainWindow()
constructor of your codebehind, the C# source code of your application, paste the following in, after the call toInitializeComponent();
:Step 3: To address issues 5 and 6, you need to hook into WmGetMinMaxInfo. To do this, go to your codebehind, then copy and paste everything from this Pastebin into your Window class. Now, within your
MainWindow()
constructor, paste:Via
Project > Add References
in the file menu, be sure to have references to:The best way to check is to click on the
Assemblies
tab in the top left, then selectFramework
, then use the search box in the top right corner of the window. Now add all of these usings (namespaces) to the top of your codebehind:That should cover everything. I hope this helps!