一个 WPF 文档和工具窗口布局容器、用于排列文档 和工具窗口的方式与许多知名 IDE 类似,例如 Eclipse、Visual Studio、 PhotoShop 等等
AvalonDock 是一个 WPF 文档和工具窗口布局容器,用于排列文档 和工具窗口的方式与许多知名 IDE 类似,例如 Eclipse、Visual Studio、 PhotoShop 等等。
从源代码构建 AvalonDock (推荐)
此项目支持多目标框架(NetCore 3 和 .Net 4)。这意味着它需要 Visual Studio Community 2019 或更好的版本。
演示屏幕截图

开源地址
实际简单使用查看下面代码
csharp
<Page
x:Class="FlightControlComputer.Views.Pages.RS422Page"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:avalonDock="https://github.com/Dirkster99/AvalonDock"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:FlightControlComputer.Views.Pages"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml"
Title="RS422Page"
d:DesignHeight="450"
d:DesignWidth="800"
UseLayoutRounding="True"
mc:Ignorable="d">
<DockingManager
x:Name="dockManager"
Grid.Row="1"
AllowMixedOrientation="True"
AutoWindowSizeWhenOpened="True"
IsVirtualizingAnchorable="True"
IsVirtualizingDocument="True">
<DockingManager.ContextMenu>
<ContextMenu>
<MenuItem Click="ShowSerialPage_Click" Header="一个数据区" />
<MenuItem Click="ShowDataPage_Click" Header="二个数据区" />
</ContextMenu>
</DockingManager.ContextMenu>
<DockingManager.Theme>
<Vs2013LightTheme />
</DockingManager.Theme>
<DockingManager.DocumentHeaderTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Image Margin="0,0,4,0" Source="{Binding IconSource}" />
<TextBlock Text="{Binding Title}" TextTrimming="CharacterEllipsis" />
</StackPanel>
</DataTemplate>
</DockingManager.DocumentHeaderTemplate>
<LayoutRoot>
<!-- Only include the left side layout for docking -->
<LayoutPanel Orientation="Horizontal">
<!--<LayoutAnchorablePaneGroup DockWidth="50">-->
<LayoutAnchorablePane DockWidth="50">
<LayoutAnchorable
Title="一个数据区"
ContentId="toolWindow1"
Hiding="OnToolWindow1Hiding">
<StackPanel MinHeight="450">
<!-- 一个数据区窗口 的界面代码这里实现 -->
</StackPanel>
</LayoutAnchorable>
</LayoutAnchorablePane>
<LayoutAnchorablePane DockWidth="50">
<LayoutAnchorable Title="二个数据区" ContentId="toolWindow2">
<!-- 另一个数据区窗口界面代码这里实现 -->
</Grid>
</LayoutAnchorable>
</LayoutAnchorablePane>
<!--</LayoutAnchorablePaneGroup>-->
</LayoutPanel>
</LayoutRoot>
</DockingManager>
</Page>
后台代码
csharp
//关键代码
#region TestBackground
/// <summary>
/// TestBackground Dependency Property
/// </summary>
public static readonly DependencyProperty TestBackgroundProperty =
DependencyProperty.Register("TestBackground", typeof(Brush), typeof(RS422Page),
new FrameworkPropertyMetadata((Brush)null));
/// <summary>
/// Gets or sets the TestBackground property. This dependency property
/// indicates a randomly changing brush (just for testing).
/// </summary>
public Brush TestBackground
{
get => (Brush)GetValue(TestBackgroundProperty);
set => SetValue(TestBackgroundProperty, value);
}
#endregion
#region FocusedElement
/// <summary>
/// FocusedElement Dependency Property
/// </summary>
public static readonly DependencyProperty FocusedElementProperty =
DependencyProperty.Register("FocusedElement", typeof(string), typeof(RS422Page),
new FrameworkPropertyMetadata((IInputElement)null));
/// <summary>
/// Gets or sets the FocusedElement property. This dependency property
/// indicates ....
/// </summary>
public string FocusedElement
{
get => (string)GetValue(FocusedElementProperty);
set => SetValue(FocusedElementProperty, value);
}
#endregion
private void OnLayoutRootPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
var activeContent = ((LayoutRoot)sender).ActiveContent;
if (e.PropertyName == "ActiveContent")
{
Debug.WriteLine(string.Format("ActiveContent-> {0}", activeContent));
}
}
private void ShowSerialPage_Click(object sender, RoutedEventArgs e)
{
var toolWindow1 = dockManager.Layout.Descendents().OfType<LayoutAnchorable>().Single(a => a.ContentId == "toolWindow1");
if (toolWindow1.IsHidden)
toolWindow1.Show();
else if (toolWindow1.IsVisible)
toolWindow1.IsActive = true;
else
toolWindow1.AddToLayout(dockManager, AnchorableShowStrategy.Bottom | AnchorableShowStrategy.Most);
}
private void ShowDataPage_Click(object sender, RoutedEventArgs e)
{
var toolWindow1 = dockManager.Layout.Descendents().OfType<LayoutAnchorable>().Single(a => a.ContentId == "toolWindow2");
if (toolWindow1.IsHidden)
toolWindow1.Show();
else if (toolWindow1.IsVisible)
toolWindow1.IsActive = true;
else
toolWindow1.AddToLayout(dockManager, AnchorableShowStrategy.Bottom | AnchorableShowStrategy.Most);
}