0
votes

I have a WPF window declared like this

<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"
    mc:Ignorable="d"
    Title="MyWindow"
    Height="800" Width="200"
    BorderThickness="0"
    WindowStyle="None"
    AllowsTransparency="False"
    ResizeMode="CanResizeWithGrip"
    Topmost="True"
    Background="#fff59d"
    ShowInTaskbar="False">

    <WindowChrome.WindowChrome>
        <WindowChrome CaptionHeight="0" ResizeBorderThickness="5" />
    </WindowChrome.WindowChrome>
</Window>

In this window there are a bunch of aligned buttons, making the window a nice tool bar that sits on top of the other windows.

Now I'd like to snap it to a screen edge (bottom, left, top, right) so that the working area of the screen is reduced by the window's area. Just like what happens with the Windows taskbar: the area covered by the taskbar is not used when other windows are maximized and the taskbar is always on top.

Any help is much appreciated !

EDIT

I'm adding an image to better explain my question:

enter image description here

I'm interested in position my WPF window on an edge so that the area of the window is forbidden to other windows.

2
Just to clarify, you want a "docked" window to reserve space on the desktop so that a separate window, when maximized, will not overlap your application's window? If this is correct, you will have to use pInvoke calls to register an "AppBar" with the window manager, which is not simple. See codeproject.com/Articles/6741/AppBar-using-C for more information.Bradley Uffner
@BradleyUffner I didn't try it but maybe it simplifies the task Github:WpfAppBarCfun
@Cfun That looks like it would remove a lot of the complexity, nice find!Bradley Uffner

2 Answers

1
votes

First use Top="0" Left="0" to snap your "nice tool bar window" to the top and left edges of the screen. Second use the event Window_Loaded to set the window height equal to the screen height minus the taskbar height so that it will not be on top of it.

Side note Title doesn't make sens in your case

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"
    mc:Ignorable="d"
    Width="200"
    BorderThickness="0"
    WindowStyle="None"
    AllowsTransparency="False"
    ResizeMode="CanResizeWithGrip"
    Topmost="True"
    Top="0"
    Left="0"
    Loaded="Window_Loaded"
    Background="#fff59d"
    ShowInTaskbar="False">

    <WindowChrome.WindowChrome>
        <WindowChrome CaptionHeight="0" ResizeBorderThickness="5"/>
    </WindowChrome.WindowChrome>
</Window>

Code-Behind:

private void Window_Loaded(object sender, RoutedEventArgs e)
{
  double TaskBarHeight = SystemParameters.PrimaryScreenHeight - SystemParameters.WorkArea.Height;
  Height = SystemParameters.PrimaryScreenHeight - TaskBarHeight;
}

Edit

As @Bradley_Uffner explained in his comment you need an AppBar, you may want to take a look at Github.WpfAppBar or better check your options in this answer C# Window Docking.

0
votes

You should check the "GridSplitter" control:

https://docs.microsoft.com/en-us/dotnet/framework/wpf/controls/how-to-resize-columns-with-a-gridsplitter

You should change your window(toolbar) to make it a UserControl so you can insert it in another window with GridSplitter on all edges (bottom, left, top, right). As for the "snap" part, I think you will have to handle the drag and drop event and hide/show the gridsplitters accordingly and either show/hide or add/remove the UserControl (your toolbar) behind the GridSplitter.

Sorry that I do not give much detail for the implementation, I believe there is quite a lot to do.

I would be very interested in another solution if someone knows a better way.

I know that the Telerik library(not free) provide a control for that https://docs.telerik.com/devtools/wpf/controls/raddocking/overview2