Jekyll2020-07-12T04:58:44+00:00https://stack.blogs.losttech.software/feed.xmlStack WM BlogAdvanced window managementSpoiler2020-07-11T00:00:00+00:002020-07-11T00:00:00+00:00https://stack.blogs.losttech.software/Spoiler-3D<p>…</p>
<p><img src="/images/Spoiler3D.png" alt="Stereo image of a window in 3D" /></p>
<p>…</p>
<!--more-->
<p>Stay tuned!</p>… …Inline Widgets2018-06-26T00:00:00+00:002018-06-26T00:00:00+00:00https://stack.blogs.losttech.software/Inline-Widgets<p>With the release of The Widgets Update, Stack provides some interesting ways
to display various data on your desktop.</p>
<p>While other documentation is still being updated in the preparation for rollout,
I am going to show how to make a widget, that displays your favorite news feed.
In this case, I will embed <a href="https://www.hanselman.com/blog/">the blog of Scott Hanselman</a>,
famous for his hands-on articles for Windows developers and power users.</p>
<p>The sample is based on the <em>Large Horizontal Left</em> layout. Result will look like this:
<img src="/images/HanselmanWidget.gif" alt="Stack layout with Scott's blog on the side" /></p>
<!--more-->
<h3>Contents</h3>
<ul id="markdown-toc">
<li><a href="#get-the-data" id="markdown-toc-get-the-data">Get the data</a></li>
<li><a href="#parse-the-data" id="markdown-toc-parse-the-data">Parse the data</a></li>
<li><a href="#list-the-articles" id="markdown-toc-list-the-articles">List the articles</a></li>
<li><a href="#make-it-look-nice" id="markdown-toc-make-it-look-nice">Make it look nice</a></li>
<li><a href="#conclusion" id="markdown-toc-conclusion">Conclusion</a></li>
</ul>
<h2 id="get-the-data">Get the data</h2>
<p>Since we want custom UI for the blog, first we need to retrieve its entries in some
machine-readable format. Fortunately, most blogs support at least one of web syndication formats:
<a href="https://en.wikipedia.org/wiki/Atom_(Web_standard)">Atom</a>
and/or
<a href="https://en.wikipedia.org/wiki/RSS">RSS</a>.</p>
<p>Scott’s blog is not an exeption. <span id="getFeed">If you <a href="https://www.hanselman.com/blog/">open it</a></span>, and look at the page source, you will find the following entries, pointing to the feeds:</p>
<div class="language-html highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt"><link</span> <span class="na">rel=</span><span class="s">"alternate"</span> <span class="na">type=</span><span class="s">"application/rss+xml"</span> <span class="na">title=</span><span class="s">"Scott Hanselman"</span>
<span class="na">href=</span><span class="s">"https://www.hanselman.com/blog/SyndicationService.asmx/GetRss"</span><span class="nt">></span>
<span class="nt"><link</span> <span class="na">rel=</span><span class="s">"alternate"</span> <span class="na">type=</span><span class="s">"application/atom+xml"</span> <span class="na">title=</span><span class="s">"Scott Hanselman"</span>
<span class="na">href=</span><span class="s">"https://www.hanselman.com/blog/SyndicationService.asmx/GetAtom"</span><span class="nt">></span>
</code></pre></div></div>
<p>For this example we will use RSS feed. Let’s go ahead and add it to the layout.</p>
<p>First, a reference to the new widget data sources is required,
which needs to be added to the top of the file next to the similar entries:</p>
<div class="language-xml highlighter-rouge"><div class="highlight"><pre class="highlight"><code>xmlns:...
xmlns:sources="clr-namespace:LostTech.Stack.Widgets.DataSources;assembly=LostTech.Stack.Widgets"
xmlns:...
</code></pre></div></div>
<p>Now we can add a data source, that retrieves data from the Atom link above.
This will go into the topmost <code class="language-plaintext highlighter-rouge">ResourceDictionary</code>:</p>
<div class="language-xml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt"><sources:WebDataSource</span> <span class="na">x:Key=</span><span class="s">"RssFeed"</span>
<span class="na">Url=</span><span class="s">"https://www.hanselman.com/blog/SyndicationService.asmx/GetRss"</span><span class="nt">/></span>
</code></pre></div></div>
<p><em>NOTE: You can replace this URL with the URL for your favorite RSS feed,
and most of the code will still work.</em></p>
<h2 id="parse-the-data">Parse the data</h2>
<p>The data from the link above comes as a long machine-formatted string
(check a readable example <a href="https://en.wikipedia.org/wiki/RSS#Example">here</a>).
Before displaying it, we need to parse it into individual pieces.</p>
<p>The format is called <a href="https://en.wikipedia.org/wiki/XML">XML</a>,
and Stack includes a parser for it already.</p>
<p><em>There’s also a JSON parser available, and an HTML parser planned.</em></p>
<p>To add XML parser to your layout, first reference Stack’s data binding:</p>
<div class="language-xml highlighter-rouge"><div class="highlight"><pre class="highlight"><code>xmlns:binding="clr-namespace:LostTech.Stack.Widgets.DataBinding;assembly=LostTech.Stack.Widgets"
</code></pre></div></div>
<p>Then add the parser to the same <code class="language-plaintext highlighter-rouge">ResourceDictionary</code> where you put <code class="language-plaintext highlighter-rouge">WebDataSource</code>:</p>
<div class="language-xml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt"><binding:XmlParser</span> <span class="na">x:Key=</span><span class="s">"XmlParser"</span><span class="nt">/></span>
</code></pre></div></div>
<p>(in the future this step might not be needed).</p>
<p>Now you can use the parser to display some simple information from the feed.</p>
<p>For example, you can add this anywhere to your layout to show blog latest update time:</p>
<div class="language-xml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt"><TextBlock</span> <span class="na">Text=</span><span class="s">"{Binding Content,
Source={StaticResource RssFeed},
Converter={StaticResource XmlParser},
ConverterParameter=rss.channel.lastBuildDate,
IsAsync=True}"</span><span class="nt">/></span>
</code></pre></div></div>
<p>A couple of things to note here:</p>
<ul>
<li><code class="language-plaintext highlighter-rouge">ConverterParameter</code> specifies which part of the document to use</li>
<li><code class="language-plaintext highlighter-rouge">IsAsync=True</code> enables Stack to not block your mouse and keyboard while data is parsed</li>
<li><code class="language-plaintext highlighter-rouge">Binding Content</code> tells the binding to use text inside <code class="language-plaintext highlighter-rouge"><lastBuildDate>2018</lastBuildDate></code></li>
</ul>
<p>Go ahead and try it, before we go ahead with more complex part, which is creating an
actual custom UI to display blog entries.</p>
<h2 id="list-the-articles">List the articles</h2>
<p>It will be very easy to simply list article titles. Standard XAML already provides
a way to build a simple list: <a href="https://msdn.microsoft.com/en-us/library/system.windows.controls.listview_properties"><code class="language-plaintext highlighter-rouge">ListView</code> control</a>:</p>
<div class="language-xml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt"><ListView</span>
<span class="na">ItemsSource=</span><span class="s">"{Binding Content,
Source={StaticResource RssFeed},
Converter={StaticResource XmlParser},
ConverterParameter=rss.channel.item, IsAsync=True}"</span>
<span class="na">DisplayMemberPath=</span><span class="s">"title"</span>
<span class="nt">/></span>
</code></pre></div></div>
<p>Now if you’ve done everything correctly, when your reload the layout, you’ll see:</p>
<p><img src="/images/FeedTitles.png" alt="Feed titles in the layout" /></p>
<h2 id="make-it-look-nice">Make it look nice</h2>
<p>I am not a design expert, so instead of trying to make one myself, I will adapt
an existing good looking
<a href="https://github.com/Microsoft/Windows-appsample-rssreader">RSS reader</a>
from Microsoft XAML samples and tweak it a bit.</p>
<p><img src="https://raw.githubusercontent.com/Microsoft/Windows-appsample-rssreader/master/RssReader.png" alt="Sample RSS Reader" /></p>
<p>The original layout for a single entry is here:
<a href="https://github.com/Microsoft/Windows-appsample-rssreader/blob/master/RssReader/Views/FeedView.xaml">link</a>. However, it is written in a Windows 10+ only version of XAML,
so I had to adapt it to work with Stack, and change bindings to show relevant feed elements.</p>
<p>I also had to add Stack’s <code class="language-plaintext highlighter-rouge">HtmlToTextConverter</code> to display short excerpts as plain text.</p>
<p>Here’s what I’ve got (careful, very long):</p>
<div class="language-xml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt"><binding:HtmlToTextConverter</span> <span class="na">x:Key=</span><span class="s">"HtmlToText"</span><span class="nt">/></span>
<span class="nt"><DataTemplate</span> <span class="na">x:Key=</span><span class="s">"ArticleItemViewTemplate"</span><span class="nt">></span>
<span class="nt"><Grid></span>
<span class="nt"><Grid></span>
<span class="nt"><StackPanel></span>
<span class="nt"><Grid</span> <span class="na">Margin=</span><span class="s">"12,12,12,0"</span><span class="nt">></span>
<span class="nt"><Grid.RowDefinitions></span>
<span class="nt"><RowDefinition</span> <span class="na">Height=</span><span class="s">"Auto"</span> <span class="nt">/></span>
<span class="nt"><RowDefinition</span> <span class="na">Height=</span><span class="s">"*"</span> <span class="nt">/></span>
<span class="nt"><RowDefinition</span> <span class="na">Height=</span><span class="s">"*"</span> <span class="nt">/></span>
<span class="nt"></Grid.RowDefinitions></span>
<span class="nt"><TextBlock</span> <span class="na">Grid.Row=</span><span class="s">"0"</span>
<span class="na">Text=</span><span class="s">"{Binding pubDate}"</span>
<span class="na">TextWrapping=</span><span class="s">"NoWrap"</span>
<span class="na">Foreground=</span><span class="s">"Gray"</span>
<span class="na">FontSize=</span><span class="s">"14"</span>
<span class="nt">/></span>
<span class="nt"><TextBlock</span> <span class="na">Grid.Row=</span><span class="s">"1"</span>
<span class="na">Margin=</span><span class="s">"0,8,0,0"</span>
<span class="na">TextWrapping=</span><span class="s">"Wrap"</span>
<span class="na">MaxHeight=</span><span class="s">"52"</span>
<span class="na">TextTrimming=</span><span class="s">"CharacterEllipsis"</span>
<span class="na">Foreground=</span><span class="s">"White"</span>
<span class="na">FontWeight=</span><span class="s">"Bold"</span> <span class="na">FontSize=</span><span class="s">"18"</span>
<span class="nt">></span>
<span class="nt"><TextBlock.Resources></span>
<span class="nt"><Style</span> <span class="na">TargetType=</span><span class="s">"{x:Type Hyperlink}"</span><span class="nt">></span>
<span class="nt"><Setter</span> <span class="na">Property=</span><span class="s">"Foreground"</span> <span class="na">Value=</span><span class="s">"LightGray"</span> <span class="nt">/></span>
<span class="nt"><Setter</span> <span class="na">Property=</span><span class="s">"ForceCursor"</span> <span class="na">Value=</span><span class="s">"True"</span> <span class="nt">/></span>
<span class="nt"><Setter</span> <span class="na">Property=</span><span class="s">"Cursor"</span> <span class="na">Value=</span><span class="s">"Hand"</span> <span class="nt">/></span>
<span class="nt"><Setter</span> <span class="na">Property=</span><span class="s">"TextDecorations"</span> <span class="na">Value=</span><span class="s">"None"</span> <span class="nt">/></span>
<span class="nt"><Style.Triggers></span>
<span class="nt"><Trigger</span> <span class="na">Property=</span><span class="s">"IsMouseOver"</span> <span class="na">Value=</span><span class="s">"True"</span><span class="nt">></span>
<span class="nt"><Setter</span> <span class="na">Property=</span><span class="s">"Foreground"</span> <span class="na">Value=</span><span class="s">"Khaki"</span> <span class="nt">/></span>
<span class="nt"></Trigger></span>
<span class="nt"></Style.Triggers></span>
<span class="nt"></Style></span>
<span class="nt"></TextBlock.Resources></span>
<span class="nt"><Hyperlink</span>
<span class="na">CommandParameter=</span><span class="s">"{Binding link}"</span>
<span class="na">Command=</span><span class="s">"{x:Static widgets:Commands.LaunchUrl}"</span><span class="nt">></span>
<span class="nt"><Run</span> <span class="na">Text=</span><span class="s">"{Binding title}"</span> <span class="nt">/></span>
<span class="nt"></Hyperlink></span>
<span class="nt"></TextBlock></span>
<span class="nt"><TextBlock</span> <span class="na">Grid.Row=</span><span class="s">"2"</span>
<span class="na">Margin=</span><span class="s">"0,4,0,12"</span>
<span class="na">Text=</span><span class="s">"{Binding 'description.#cdata-section', Converter={StaticResource HtmlToText}}"</span>
<span class="na">TextWrapping=</span><span class="s">"Wrap"</span>
<span class="na">MaxHeight=</span><span class="s">"100"</span>
<span class="na">TextTrimming=</span><span class="s">"CharacterEllipsis"</span>
<span class="na">Foreground=</span><span class="s">"White"</span>
<span class="nt">/></span>
<span class="nt"></Grid></span>
<span class="nt"><Rectangle</span> <span class="na">x:Name=</span><span class="s">"BorderBottom"</span>
<span class="na">Grid.Row=</span><span class="s">"2"</span>
<span class="na">Height=</span><span class="s">"1"</span>
<span class="na">HorizontalAlignment=</span><span class="s">"Stretch"</span>
<span class="na">VerticalAlignment=</span><span class="s">"Bottom"</span>
<span class="na">Fill=</span><span class="s">"Silver"</span> <span class="nt">/></span>
<span class="nt"></StackPanel></span>
<span class="nt"></Grid></span>
<span class="nt"></Grid></span>
<span class="nt"></DataTemplate></span>
</code></pre></div></div>
<p>Insert it into the <code class="language-plaintext highlighter-rouge">ResourceDictionary</code> just below our <code class="language-plaintext highlighter-rouge">XmlParser</code>.</p>
<p>This also requires a new reference:
<br />
<code class="language-plaintext highlighter-rouge">xmlns:widgets="clr-namespace:LostTech.Stack.Widgets;assembly=LostTech.Stack.Widgets"</code>
<br />
that is used to open articles by clicking on them:</p>
<div class="language-xml highlighter-rouge"><div class="highlight"><pre class="highlight"><code>...
<span class="nt"><Hyperlink</span>
<span class="na">CommandParameter=</span><span class="s">"{Binding link}"</span>
<span class="na">Command=</span><span class="s">"{x:Static widgets:Commands.LaunchUrl}"</span><span class="nt">></span>
...
</code></pre></div></div>
<p>Now we can replace the default <code class="language-plaintext highlighter-rouge">ListView</code> with our customizedlooks.
Replace the above <code class="language-plaintext highlighter-rouge">ListView</code> with:</p>
<div class="language-xml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt"><ItemsControl</span>
<span class="na">ItemsSource=</span><span class="s">"{Binding Content,
Source={StaticResource RssFeed},
Converter={StaticResource XmlParser},
ConverterParameter=rss.channel.item, IsAsync=True}"</span>
<span class="na">ItemTemplate=</span><span class="s">"{StaticResource ArticleItemViewTemplate}"</span>
<span class="nt">/></span>
</code></pre></div></div>
<p>And, voila!</p>
<p><img src="/images/HanselmanWidget.gif" alt="Stack layout with Scott's blog on the side" /></p>
<h2 id="conclusion">Conclusion</h2>
<p>You can find general documentation on the <a href="https://github.com/losttech/Stack.Widgets">GitHub page</a> for the project.
Or <a href="../samples/Large Horizontal Left - WebDataSource.xaml">download
the full layout</a>, that includes all the elements described here, and some more.</p>
<p>If you have any questions, please ask on <a href="https://www.allanswered.com/community/s/stack-wm/">our Q&A community</a>.</p>
<p>Stay tuned for more!</p>With the release of The Widgets Update, Stack provides some interesting ways to display various data on your desktop. While other documentation is still being updated in the preparation for rollout, I am going to show how to make a widget, that displays your favorite news feed. In this case, I will embed the blog of Scott Hanselman, famous for his hands-on articles for Windows developers and power users. The sample is based on the Large Horizontal Left layout. Result will look like this:Resize Grip2018-04-16T00:00:00+00:002018-04-16T00:00:00+00:00https://stack.blogs.losttech.software/Resize-Grip<p>Recently, we’ve released <a href="https://www.microsoft.com/en-us/store/p/stack-wm/9p4rj8rl7qgs">Stack WM 2.0</a>, that added <a href="https://losttech.software/stack-whatsnew-2.0.html#helpers">permanently visible elements</a>. In this blog post I am going to show you, how I used them to add a grip to my vertical layout,
that lets me redistribute space between the bottom and the top zones.</p>
<!--more-->
<h3>Hello, world!</h3>
<p>Permanently visible elements is a new superpower of Stack, that you will see explored further here in the coming months, but we should start with something simple. We will make a “Hello, world!” layout, that simply shows “Hello, world!” on the screen. You will see how incredibly simple it can be.</p>
<p>Here’s what you need to do:</p>
<ol>
<li>Create a new layout (tray menu -> Edit Layout -> New)</li>
<li>Give it a name (I used “Hello World”)</li>
<li>Next, open it in your text editor of choice (I recommend free Visual Studio Code)</li>
</ol>
<p>You’ll see something like this:</p>
<div class="language-xml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt"><Grid</span>
<span class="na">xmlns=</span><span class="s">"http://schemas.microsoft.com/winfx/2006/xaml/presentation"</span>
<span class="na">xmlns:d=</span><span class="s">"http://schemas.microsoft.com/expression/blend/2008"</span>
<span class="na">xmlns:mc=</span><span class="s">"http://schemas.openxmlformats.org/markup-compatibility/2006"</span>
<span class="na">xmlns:sys=</span><span class="s">"clr-namespace:System;assembly=mscorlib"</span>
<span class="na">xmlns:x=</span><span class="s">"http://schemas.microsoft.com/winfx/2006/xaml"</span>
<span class="na">xmlns:zones=</span><span class="s">"clr-namespace:LostTech.Stack.Zones;assembly=Stack"</span>
<span class="na">zones:Layout.Version=</span><span class="s">"2"</span>
<span class="na">mc:Ignorable=</span><span class="s">"d"</span>
<span class="na">Width=</span><span class="s">"1024"</span> <span class="na">Height=</span><span class="s">"576"</span>
<span class="na">d:DesignWidth=</span><span class="s">"1024"</span>
<span class="na">d:DesignHeight=</span><span class="s">"576"</span>
<span class="na">x:Name=</span><span class="s">"Root"</span>
<span class="nt">></span>
<span class="nt"><Grid.Resources></span>
...
<span class="nt"></Grid.Resources></span>
<span class="nt"><Grid.ColumnDefinitions></span>
...
<span class="nt"></Grid.ColumnDefinitions></span>
...
<span class="nt"></Grid></span>
</code></pre></div></div>
<p>Note that <code class="language-plaintext highlighter-rouge">zones:Layout.Version="2"</code> at the top is important, it tells Stack, that this layout uses 2.0 features, and should be permanently visible.</p>
<p>Remove everything inside <Grid …></Grid>, and put this instead: <code class="language-plaintext highlighter-rouge"><TextBlock Foreground="Red">Hello, world!</TextBlock></code>. Save it.</p>
<p>Now go to the Stack menu for your screen, and load your new layout. If you did everything correctly, this is what you will see:
<img src="/images/HelloWorld.png" alt="Desktop with Hello, World! on it" /></p>
<p>Now this layout might not be very useful, considering there are no zones :) , but it demonstrates a powerful concept: you can decorate your desktop with Stack in a very customizable way.</p>
<p>For example, here’s markup to add white Stack logo to your layout:</p>
<div class="language-xml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt"><Grid</span> <span class="na">Width=</span><span class="s">"40"</span> <span class="na">Height=</span><span class="s">"30"</span> <span class="na">HorizontalAlignment=</span><span class="s">"Left"</span> <span class="na">VerticalAlignment=</span><span class="s">"Top"</span><span class="nt">></span>
<span class="nt"><Grid</span> <span class="na">Margin=</span><span class="s">"3"</span><span class="nt">></span>
<span class="nt"><Grid.RowDefinitions></span>
<span class="nt"><RowDefinition</span> <span class="na">Height=</span><span class="s">"1*"</span><span class="nt">/></span>
<span class="nt"><RowDefinition</span> <span class="na">Height=</span><span class="s">"1.5*"</span><span class="nt">/></span>
<span class="nt"></Grid.RowDefinitions></span>
<span class="nt"><Grid.ColumnDefinitions></span>
<span class="nt"><ColumnDefinition</span> <span class="na">Width=</span><span class="s">"3*"</span><span class="nt">/></span>
<span class="nt"><ColumnDefinition</span> <span class="na">Width=</span><span class="s">"2*"</span><span class="nt">/></span>
<span class="nt"></Grid.ColumnDefinitions></span>
<span class="nt"><Border</span> <span class="na">BorderBrush=</span><span class="s">"White"</span> <span class="na">Grid.Column=</span><span class="s">"0"</span> <span class="na">Grid.Row=</span><span class="s">"0"</span> <span class="na">BorderThickness=</span><span class="s">"3,3,0,3"</span><span class="nt">/></span>
<span class="nt"><Border</span> <span class="na">BorderBrush=</span><span class="s">"White"</span> <span class="na">Grid.Column=</span><span class="s">"1"</span> <span class="na">Grid.Row=</span><span class="s">"0"</span> <span class="na">BorderThickness=</span><span class="s">"3"</span><span class="nt">/></span>
<span class="nt"><Border</span> <span class="na">BorderBrush=</span><span class="s">"White"</span> <span class="na">Grid.ColumnSpan=</span><span class="s">"2"</span> <span class="na">Grid.Row=</span><span class="s">"1"</span> <span class="na">BorderThickness=</span><span class="s">"3,0,3,3"</span><span class="nt">/></span>
<span class="nt"></Grid></span>
<span class="nt"></Grid></span>
</code></pre></div></div>
<p>If you’ve ever worked with Inkscape, it can save vector images in a compatible format: choose Microsoft XAML when saving.
You’ll get something like this:</p>
<div class="language-xml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp"><?xml version="1.0" encoding="UTF-8"?></span>
<span class="nt"><Viewbox</span> <span class="na">xmlns=</span><span class="s">"http://schemas.microsoft.com/winfx/2006/xaml/presentation"</span> <span class="na">Stretch=</span><span class="s">"Uniform"</span><span class="nt">></span>
...
<span class="nt"></Viewbox></span>
</code></pre></div></div>
<p>You should be able to copy and paste the entire Viewbox into your layout where you want it to be. (drop the xml part)</p>
<h3>The Grip</h3>
<p>Stack is based on Microsoft WPF, which provides a lot of powerful controls, that you can now use to customize your screen.
Most of layouts already use <code class="language-plaintext highlighter-rouge"><Grid></code> and <code class="language-plaintext highlighter-rouge"><Border></code> controls for the basic functionality.
You can also use <code class="language-plaintext highlighter-rouge"><TextBlock></code> as shown above, or add an <code class="language-plaintext highlighter-rouge"><Image></code> (<a href="https://www.tutorialspoint.com/wpf/wpf_image.htm" title="how to insert image into your layout">see how</a>).</p>
<p>We will try to explore what is available in this blog later, and see how you can use it in Stack to get some cool behaviors.
Today, we will focus on <code class="language-plaintext highlighter-rouge"><GridSplitter></code> (<a href="http://www.wpf-tutorial.com/panels/gridsplitter/" title="more details about GridSplitter">more details</a>).</p>
<p><code class="language-plaintext highlighter-rouge"><GridSplitter></code> is a control, that allows you to dynamically resize rows or columns in your layout’s Grids with mouse.
The idea is simple: add a Row or a Column to your layout between the zones you want to resize,
put a <code class="language-plaintext highlighter-rouge"><GridSplitter></code> into it, and let it handle the rest. For example:</p>
<div class="language-xml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt"><GridSplitter</span> <span class="na">Grid.Row=</span><span class="s">"1"</span> <span class="na">Height=</span><span class="s">"6"</span>
<span class="na">ResizeDirection=</span><span class="s">"Rows"</span> <span class="na">ResizeBehavior=</span><span class="s">"PreviousAndNext"</span>
<span class="na">HorizontalAlignment=</span><span class="s">"Stretch"</span> <span class="na">VerticalAlignment=</span><span class="s">"Top"</span> <span class="nt">/></span>
</code></pre></div></div>
<p>Turns into:</p>
<p><img src="/images/GridSplitter.png" alt="Vertical layout with a draggable splitter" /></p>
<p>Now you can grab the splitter (marked violet) with mouse, and resize top and bottom zones together.</p>
<p>Be careful when inserting splitter next to WindowTabs.
If you do it blindly, the tabs will be resized instead of the zone below them.
To circumvent that in my example I put tabs and splitter into the same row,
and set <code class="language-plaintext highlighter-rouge">Margin="0,6,0,0"</code> on tabs to leave area above them for the splitter. Here’s the full example:</p>
<div class="language-xml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt"><Grid</span>
<span class="na">xmlns=</span><span class="s">"http://schemas.microsoft.com/winfx/2006/xaml/presentation"</span>
<span class="na">xmlns:d=</span><span class="s">"http://schemas.microsoft.com/expression/blend/2008"</span>
<span class="na">xmlns:x=</span><span class="s">"http://schemas.microsoft.com/winfx/2006/xaml"</span>
<span class="na">xmlns:zones=</span><span class="s">"clr-namespace:LostTech.Stack.Zones;assembly=Stack"</span>
<span class="na">xmlns:mc=</span><span class="s">"http://schemas.openxmlformats.org/markup-compatibility/2006"</span>
<span class="na">mc:Ignorable=</span><span class="s">"d"</span>
<span class="na">Width=</span><span class="s">"576"</span> <span class="na">Height=</span><span class="s">"1024"</span>
<span class="na">zones:Layout.Version=</span><span class="s">"2"</span>
<span class="na">d:DesignWidth=</span><span class="s">"576"</span>
<span class="na">d:DesignHeight=</span><span class="s">"1024"</span>
<span class="nt">></span>
<span class="nt"><Grid.RowDefinitions></span>
<span class="nt"><RowDefinition</span> <span class="na">Height=</span><span class="s">"*"</span><span class="nt">/></span>
<span class="nt"><RowDefinition</span> <span class="na">Height=</span><span class="s">"Auto"</span><span class="nt">/></span>
<span class="nt"><RowDefinition</span> <span class="na">Height=</span><span class="s">"4*"</span><span class="nt">/></span>
<span class="nt"></Grid.RowDefinitions></span>
<span class="nt"><zones:Zone</span> <span class="na">x:Name=</span><span class="s">"Full"</span> <span class="na">Grid.RowSpan=</span><span class="s">"4"</span><span class="nt">/></span>
<span class="nt"><zones:Zone</span> <span class="na">Grid.Row=</span><span class="s">"0"</span><span class="nt">/></span>
<span class="nt"><GridSplitter</span> <span class="na">Grid.Row=</span><span class="s">"1"</span> <span class="na">Height=</span><span class="s">"6"</span>
<span class="na">ResizeDirection=</span><span class="s">"Rows"</span> <span class="na">ResizeBehavior=</span><span class="s">"PreviousAndNext"</span>
<span class="na">HorizontalAlignment=</span><span class="s">"Stretch"</span> <span class="na">VerticalAlignment=</span><span class="s">"Top"</span> <span class="nt">/></span>
<span class="nt"><zones:WindowTabs</span> <span class="na">Grid.Row=</span><span class="s">"1"</span> <span class="na">Margin=</span><span class="s">"0,6,0,0"</span>
<span class="na">ItemsSource=</span><span class="s">"{Binding Windows, Source={x:Reference Main}}"</span><span class="nt">/></span>
<span class="nt"><zones:Zone</span> <span class="na">x:Name=</span><span class="s">"Main"</span> <span class="na">Grid.Row=</span><span class="s">"2"</span><span class="nt">/></span>
<span class="nt"><Border</span> <span class="na">Grid.RowSpan=</span><span class="s">"3"</span> <span class="na">Height=</span><span class="s">"160"</span> <span class="na">VerticalAlignment=</span><span class="s">"Bottom"</span> <span class="na">Background=</span><span class="s">"#44F"</span>
<span class="na">zones:Layout.IsHint=</span><span class="s">"True"</span><span class="nt">></span>
<span class="c"><!-- Find more symbols from Segoe UI Symbol in Character Map app --></span>
<span class="nt"><TextBlock</span> <span class="na">HorizontalAlignment=</span><span class="s">"Center"</span> <span class="na">VerticalAlignment=</span><span class="s">"Center"</span>
<span class="na">FontFamily=</span><span class="s">"Segoe UI Symbol"</span> <span class="na">Foreground=</span><span class="s">"White"</span> <span class="na">Text=</span><span class="s">"⇕"</span> <span class="na">FontSize=</span><span class="s">"80"</span><span class="nt">/></span>
<span class="nt"></Border></span>
<span class="nt"><zones:Zone</span> <span class="na">Grid.RowSpan=</span><span class="s">"3"</span> <span class="na">Height=</span><span class="s">"160"</span> <span class="na">VerticalAlignment=</span><span class="s">"Bottom"</span>
<span class="na">Target=</span><span class="s">"{Binding ElementName=Full}"</span><span class="nt">/></span>
<span class="nt"></Grid></span>
</code></pre></div></div>
<h3>Security warning!</h3>
<p>Stack layouts use very powerful extensibility mechanism, built on WPF.
In theory, one can make any program to be part of their layout.
However, this mechanism can be used for hacking.</p>
<p>DO NOT USE LAYOUTS FROM PEOPLE YOU DO NOT TRUST!</p>
<h3>Questions?</h3>
<p>If you have any questions, feel free to <a href="https://www.allanswered.com/community/s/stack-wm/">ask our community</a>.</p>Recently, we’ve released Stack WM 2.0, that added permanently visible elements. In this blog post I am going to show you, how I used them to add a grip to my vertical layout, that lets me redistribute space between the bottom and the top zones.