Skip to content

mgaffigan/WpfAppBar

Repository files navigation

Itp.WpfAppBar

Nuget

Implementation of an AppBar in WPF based off of Using Application Desktop Toolbars and Extend the Windows 95 Shell with Application Desktop Toolbars.

Goals:

  • Allow dock to any side of the screen
  • Allow dock to a particular monitor
  • Allow resizing of the appbar
  • Handle screen layout changes and monitor disconnections
  • Handle Win + Shift + Left and attempts to minimize or move the window
  • Handle co-operation with other appbars (OneNote et al.)
  • Handle per-monitor DPI scaling

License

MIT License

Example use

<apb:AppBarWindow x:Class="WpfAppBarDemo.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:apb="clr-namespace:WpfAppBar;assembly=WpfAppBar"
    DataContext="{Binding RelativeSource={RelativeSource Self}}" Title="MainWindow" 
    DockedWidthOrHeight="200" MinWidth="100" MinHeight="100">
    <Grid>
        <Button x:Name="btClose" Content="Close" HorizontalAlignment="Left" VerticalAlignment="Top" Width="75" Height="23" Margin="10,10,0,0" Click="btClose_Click"/>
        <ComboBox x:Name="cbMonitor" SelectedItem="{Binding Path=Monitor, Mode=TwoWay}" HorizontalAlignment="Left" VerticalAlignment="Top" Width="120" Margin="10,38,0,0"/>
        <ComboBox x:Name="cbEdge" SelectedItem="{Binding Path=DockMode, Mode=TwoWay}" HorizontalAlignment="Left" Margin="10,65,0,0" VerticalAlignment="Top" Width="120"/>

        <Thumb Width="5" HorizontalAlignment="Right" Background="Gray" x:Name="rzThumb" Cursor="SizeWE" DragCompleted="rzThumb_DragCompleted" />
    </Grid>
</apb:AppBarWindow>

Codebehind:

public partial class MainWindow
{
    public MainWindow()
    {
        InitializeComponent();

        this.cbEdge.ItemsSource = new[]
        {
            AppBarDockMode.Left,
            AppBarDockMode.Right,
            AppBarDockMode.Top,
            AppBarDockMode.Bottom
        };
        this.cbMonitor.ItemsSource = MonitorInfo.GetAllMonitors();
    }

    private void btClose_Click(object sender, RoutedEventArgs e)
    {
        Close();
    }

    private void rzThumb_DragCompleted(object sender, DragCompletedEventArgs e)
    {
        this.DockedWidthOrHeight += (int)(e.HorizontalChange / VisualTreeHelper.GetDpi(this).PixelsPerDip);
    }
}

App.config (for Monitor-specific DPI support):

<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.2"/>
</startup>
<runtime>
    <AppContextSwitchOverrides value="Switch.System.Windows.DoNotScaleForDpiChanges=false"/>
</runtime>
</configuration>

App.manifest (for Monitor-specific DPI support):

<?xml version="1.0" encoding="utf-8"?>
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
<assemblyIdentity version="1.0.0.0" name="MyApplication.app"/>
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
    <security>
    <requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
        <requestedExecutionLevel level="asInvoker" uiAccess="false" />
    </requestedPrivileges>
    </security>
</trustInfo>
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
    <application>
    <!-- Windows 10 -->
    <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" />
    </application>
</compatibility>
<application xmlns="urn:schemas-microsoft-com:asm.v3">
    <windowsSettings>
    <dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true</dpiAware>
    <dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitor</dpiAwareness>
    </windowsSettings>
</application>
</assembly>

Screenshots

Changing docked position (sample):

AppBar docked to edges

Resizing with thumb:

Resize

Cooperation with other appbars:

Coordination

Dock and undock (sample):

Undock

Add Nuget or clone from GitHub if you want to use it. The library itself is only three files, and can easily be dropped in a project.

<PackageReference Include="Itp.WpfAppBar" Version="*" />

Itp.WinFormsAppBar

Nuget

A WinForms variant also is available under Itp.WinFormsAppBar. Edit Form1.cs to inherit from AppBarForm instead of Form.
See (Itp.WinFormsAppBar.Demo) for full demo.

public partial class Form1 : AppBarForm
{
    public Form1()
    {
    }
}

Winforms Safe Context

When using Itp.WinFormsAppBar you must update Program.cs to use SystemEventsSafeAppContext to avoid hangs on exit. Change:

Application.Run(new Form1());

to

Application.Run(new SystemEventsSafeAppContext(new Form1()));