Using Screen Space Optimally with WPF Data Triggers and Stack

This article will discuss how to use WPF Data Triggers in the Stack monitor splitting scheme in order to fully give the application all the desktop space when other applications are not running. Stack is a windows tile manager that uses WPF XAML as the screen layout language.

The screen splitting scheme for large monitors that comes out of the box (see under the cut) breaks the desktop into 2 main zones - the central (I usually use it for browsers and IDEs) and the side (RSS Reader, messengers and terminal windows get there). This circuit is fixed. Those. if you only have a browser open, Stack will leave an empty space to the left of it. In this article, I will show how to use WPF Data Triggers and Data Binding to dig this area automatically when it is empty.

Where do we start?

This is how the partition scheme looks before starting work on it:

Here you can take the source code of the latest version.

First you’ll have to create a copy with a different name, because the original has a note
This file is overwritten after every update. Please modify a copy!
I named my scheme Large Horizontal Left Autocollapse.

Actually, you will have to work mainly with the most external Grid, because it defines the left column and everything else.

As you can see, the columns are fixed in size as 1: 3. We don’t need this, and we will try to compress the left column if there is nothing in it.

Data trigger

Fortunately, we already have tabs in the left column, which should show all the windows that are in it. And that means we can use their Items.Count as a source for a DataTrigger.

To do this, you have to give them a name (they are defined at the beginning of the diagram inside the first column):


Here comes the magic of DataTriggers. We take the definition of the first column (see above) and change the fixed Width to the style with a DataTrigger:

Please note that 1 * is used as the default value, and the trigger turns on at 0 elements. It would be more logical to specify a trigger for> 0 elements, but WPF XAML does not know how.

So, save, select a new scheme in Stack and see ... that we can no longer put anything on the left side, because it collapses at startup due to the fact that there is nothing in it (we wrote it ourselves), which means that you can’t move the mouse there. Win + arrow, by the way, is already working, so if you don’t use the mouse, you can skip the next part.

What to do with the mouse

If you previously made custom schemes for Stack, you already know that the zone where you can put the window does not have to coincide with the zone where this window will be. Therefore, we will do it very simply - add a zone to the left, which will be visible even when the column is minimized. This can be done if you put the Canvas left column in the Grid - Canvas does not cut off elements that cannot fit into it.

This Canvas will replace Border, which in the original layout scheme was used to stretch elements to the entire left column. Here's how it would look:

Since Canvas is generally intended for drawing, there is no easy way to stretch elements to its full width. Therefore, the sizes of the elements in it are screwed to the sizes of the Canvas itself through data-bindings:

Width="{Binding ActualWidth, ElementName=DropOverlay}"

Also, they all have MinWidth so that when the column with the Canvas are minimized, the elements would still have a non-zero width.

In general, it already looks as it should, but if you save now and try to drag something to the left with your mouse, you won’t succeed. Due to the order of the elements in the XAML file, the main zone is located above our DropOverlay in the z-order, turning it into a useless “DropUnderlay” :)

To fix this it is very simple - swap the Grids describing the columns. It was:





It became:





Now the left column will be higher in z-order than the central part, and DropOverlay will be able to accept the mouse.

Here's what we will see:

Full code for the splitting scheme here: pastebin


With such a layout, the screen layout is much more convenient than with a fixed one. However, additional improvements would not hurt. For example, it is not convenient that when you drag the first window with the mouse, it does not show to the left where exactly it will move, because the corresponding zone is minimized. This problem can be solved using the MouseOver trigger, which would expand the entire left column when you hover the mouse.

In general, I have not tried it yet, but it would be possible to use data obtained from external sources in triggers and markup elements. It would be something like custom widgets on the desktop, for example, with quotes for courses. The only problem is that WPF is not able to update data from the source by timer.

In general, it is very cool that you can use XAML to customize your desktop on Windows. It opens up many possibilities.

Also popular now: