65.9K
CodeProject 正在变化。 阅读更多。
Home

提示:DockPanel Suite 的小改进,第一部分

starIconstarIconstarIconstarIconstarIcon

5.00/5 (3投票s)

2011 年 7 月 6 日

CPOL

2分钟阅读

viewsIcon

23776

本提示展示了如何为使用 Weifen Luo 的 DockPanel Suite 的应用程序的“窗口”菜单添加对“新建水平选项卡组”和“新建垂直选项卡组”命令的支持,以及其他一些小的改进,以帮助确定至少有一个窗口是否停靠在主窗体的侧面。

引言

由 Weifen Luo 创建的 DockPanel UI 工具套件是创建模仿 Visual Studio 选项卡/停靠窗口环境的用户界面的一个优秀的开源解决方案。 我想为窗体菜单栏创建一个类似于 Visual Studio 环境中的“窗口”菜单。 因此,我决定从主 DockPanel 类派生一个类,并将其命名为 StudioDockPanel,然后将我的小改进放在这段代码中。 其中一项改进是实现 Visual Studio 环境的菜单栏上出现的“新建水平选项卡组”和“新建垂直选项卡组”命令。 这些命令允许你将一组选项卡“堆叠”在另一组的上方。

代码

首先,我从 Weifen Luo 提供的 DockPanel 类派生了一个类,名为 StudioDockPanel
namespace MyProject
{
    public class StudioDockPanel : DockPanel
    {

    }
}
接下来,我添加了一个内部函数 NewHorizontalTabGroup 到其中
internal void NewHorizontalTabGroup()
{
    if (this.DocumentDockWindow == null
        || this.ActiveDocument == null)
        return; // just no-op on error

    IDockContent CurrentDocument = this.ActiveDocument;
    DockPane CurrentPane = this.ActiveContent.DockHandler.Pane;

    // create a new dock pane to the right of the current pane
    // and then transfer the document to the new pane
    DockPane NewPane = DockPaneFactory.CreateDockPane(CurrentDocument,
        CurrentPane, DockAlignment.Bottom, 0.5, true);
    NewPane.Show();
}
DocumentDockWindow 是我添加的一个属性,以便快速找到哪个 DockPanel.DockWinodws 包含选项卡式文档视图。
public DockWindow DocumentDockWindow
{
    get
    {
        foreach (DockWindow Window in DockWindows)
            if (Window.DockState == DockState.Document)
                return Window;
        return null;
    }
}
这非常简单明了;它只是搜索 DockWindows 列表并返回其 DockState 设置为 DockState.Document 的那个。 这是一个公共属性,因此你可以将其放入你当前的 代码中。 接下来,让我们看看如何添加一个新的垂直选项卡组。
internal void NewVerticalTabGroup()
{
    if (this.DocumentDockWindow == null
        || this.ActiveDocument == null)
        return; // just no-op on error

    IDockContent CurrentDocument = this.ActiveDocument;
    DockPane CurrentPane = this.ActiveContent.DockHandler.Pane;

    // create a new dock pane to the right of the current pane
    // and then transfer the document to the new pane
    DockPane NewPane = DockPaneFactory.CreateDockPane(CurrentDocument,
        CurrentPane, DockAlignment.Right, 0.5, true);
    NewPane.Show();
}
现在,当你有一个“窗口”菜单时,你希望更新菜单命令本身的 UI,以便除非打开了多个选项卡式文档,否则它们无法被选择。 否则,没有可用的内容可以添加到新的窗格中! 为此,我实现了一个 TwoOrMoreOpenDocumentWindows 属性
public bool TwoOrMoreOpenDocumentWindows
{
    get
    {
        if (this.DocumentDockWindow == null)
            return false;
        return this.DocumentDockWindow.VisibleNestedPanes[0].Contents.Count > 1;
    }
}
IsDocumentVisible 属性告诉你是否根本存在活动文档。
public bool IsDocumentVisible
{
    get
    {
        return this.ActiveDocument != null;
    }
}
最后,需要知道至少有一个窗格停靠在窗口侧面的要求。 这是为了更新用户界面并启用/禁用适当的菜单命令(浮动、停靠、作为选项卡式文档停靠、自动隐藏、隐藏等)。 因此,这有助于我们添加一个 IsAtLeastOnePaneDocked 属性
public bool IsAtLeastOnePaneDocked
{
    get {
        foreach (DockWindow Window in DockWindows)
            if (Window.DockState != DockState.Document
                && Window.VisibleNestedPanes.Count > 0)
                return true;
        return false;
    }
}
就这样。 随着我对该库进行进一步的增强,以使其更接近这种类型环境的 UI 标准,将会出现更多的更新、提示或技巧。

用法

要实现“窗口”菜单命令“浮动”、“停靠”、“作为选项卡式文档停靠”、“自动隐藏”和“隐藏”,我们执行以下操作(菜单命令的变量名应该不言自明)
private void FloatWindow_Click(object sender, EventArgs e)
{
    if (this.MainDockPanel.ActiveContent == null)
        return;
    this.MainDockPanel.ActiveContent.DockHandler.DockState = DockState.Float;
}

private void DockWindow_Click(object sender, EventArgs e)
{
    if (this.MainDockPanel.ActiveContent == null)
        return;
    this.MainDockPanel.ActiveContent.DockHandler.DockTo(
        this.MainDockPanel, DockStyle.Left);
}

private void DockWindowAsTabbedDocument_Click(object sender, EventArgs e)
{
    if (this.MainDockPanel.ActiveContent == null)
        return;
    this.MainDockPanel.ActiveContent.DockHandler.DockState = DockState.Document;
}

private void AutoHideWindow_Click(object sender, EventArgs e)
{
    if (this.MainDockPanel.ActiveContent == null)
        return;
    switch (this.MainDockPanel.ActiveContent.DockHandler.DockState)
    {
        case DockState.DockLeft:
            this.MainDockPanel.ActiveContent.DockHandler.DockState = DockState.DockLeftAutoHide;
            break;
        case DockState.DockBottom:
            this.MainDockPanel.ActiveContent.DockHandler.DockState = DockState.DockBottomAutoHide;
            break;
        case DockState.DockRight:
            this.MainDockPanel.ActiveContent.DockHandler.DockState = DockState.DockRightAutoHide;
            break;
        case DockState.DockTop:
            this.MainDockPanel.ActiveContent.DockHandler.DockState = DockState.DockTopAutoHide;
            break;
        default:
            break;
    }
}

private void HideWindow_Click(object sender, EventArgs e)
{
    if (this.MainDockPanel.ActiveContent == null)
        return;
    this.MainDockPanel.ActiveContent.DockHandler.Hide();
}

private void AutoHideAll_Click(object sender, EventArgs e)
{
    foreach (DockContent content in this.MainDockPanel.Contents)
    {
        switch (content.DockState)
        {
            case DockState.DockLeft:
            case DockState.DockLeftAutoHide:
                content.DockState = DockState.DockLeftAutoHide;
                break;
            case DockState.DockBottom:
            case DockState.DockBottomAutoHide:
                content.DockState = DockState.DockBottomAutoHide;
                break;
            case DockState.DockRight:
            case DockState.DockRightAutoHide:
                content.DockState = DockState.DockRightAutoHide;
                break;
            case DockState.DockTop:
            case DockState.DockTopAutoHide:
                content.DockState = DockState.DockTopAutoHide;
                break;
            default:
                break;
        }
    }
}

private void NewHorizontalTabGroup_Click(object sender, EventArgs e)
{
    this.MainDockPanel.NewHorizontalTabGroup();
}

private void NewVerticalTabGroup_Click(object sender, EventArgs e)
{
    this.MainDockPanel.NewVerticalTabGroup();
}

private void ResetWindowLayout_Click(object sender, EventArgs e)
{
    // TODO: Add code here to reset the window layout to the default
    // Make sure to prompt the user to confirm
}
最后,你希望适当地更新“窗口”菜单命令
// This is a handler for the DropDownOpening event of the Window menu
private void UpdateWindowMenu(object sender, EventArgs e)
{
    int itemCount = windowMenu.DropDownItems.Count;
    if (windowMenu.DropDownItems[itemCount - 1] is ToolStripSeparator)
        windowMenu.DropDownItems.RemoveAt(itemCount - 1);
    this.CloseAllDocuments.Enabled =
        this.MdiChildren.Length > 0;
    this.AutoHideAll.Visible = this.MainDockPanel.IsAtLeastOnePaneDocked;
    this.NewHorizontalTabGroup.Visible = this.NewHorizontalTabGroup.Enabled = this.MainDockPanel.IsDocumentVisible
        && this.MainDockPanel.TwoOrMoreOpenDocumentWindows;
    this.NewVerticalTabGroup.Visible = this.NewVerticalTabGroup.Enabled = this.MainDockPanel.IsDocumentVisible
        && this.MainDockPanel.TwoOrMoreOpenDocumentWindows;
    if (this.MainDockPanel.ActiveContent == null)
    {
        this.FloatWindow.Enabled =
            this.DockWindow.Enabled =
            this.AutoHide.Enabled =
            this.DockWindowTabbedDocument.Enabled =
            this.HideWindow.Enabled = false;
        return;
    }
    switch (this.MainDockPanel.ActiveContent.DockHandler.DockState)
    {
        case DockState.Document:
        case DockState.Unknown:
            this.FloatWindow.Enabled = true;
            this.DockWindow.Enabled = true;
            this.DockWindowTabbedDocument.Enabled = false;
            this.AutoHide.Enabled = false;
            this.HideWindow.Enabled = false;
            break;
        case DockState.DockBottom:
        case DockState.DockBottomAutoHide:
        case DockState.DockLeft:
        case DockState.DockLeftAutoHide:
        case DockState.DockRight:
        case DockState.DockRightAutoHide:
        case DockState.DockTop:
        case DockState.DockTopAutoHide:
            this.FloatWindow.Enabled = true;
            this.DockWindow.Enabled = false;
            this.DockWindowTabbedDocument.Enabled = true;
            this.AutoHide.Enabled = true;
            this.HideWindow.Enabled = true;
            break;
        case DockState.Float:
            this.FloatWindow.Enabled = false;
            this.DockWindow.Enabled = true;
            this.DockWindowTabbedDocument.Enabled = true;
            this.AutoHide.Enabled = false;
            this.HideWindow.Enabled = true;
            break;
        default:
            break;
    }
}
就这样了。
© . All rights reserved.