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

Visual WebGui 中的持久化分割器控件

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.75/5 (3投票s)

2008年7月22日

CPOL

3分钟阅读

viewsIcon

28544

downloadIcon

312

在 Visual WebGui 中实现持久化分割器控件

引言

Visual WebGui 是一个强大的框架,用于开发基于 AJAX 的企业应用程序。 它建立在 ASP.NET 之上,并实现了一个类似“WinForms”的编程模型,用于使用丰富的用户界面开发企业 Web 应用程序。 它提供了与 WinForms 编程模型中可用的用户控件兼容的各种用户控件。

其中有分割器控件,它允许将工作区分成两个或多个面板,每个面板都包含自己的控件。

分割器一个非常有用的功能是记住它在运行时的位置。 在本文中,我将创建一个新的分割器组件,通过增强 Visual Webgui 工具箱中的股票分割器控件,使其记住它在运行时的位置。

然而,分割器的一个很好的特性是允许用户自定义面板的大小,加宽/缩小它们以满足各种需求,并在下次使用应用程序时记住大小。

因此,我增强了内置的 Visual WebGui 分割器以实现此功能。

实现细节

当我尝试实现这一点时,我面临的问题是如何在运行时设置分割器的位置。 经过一些测试,我注意到分割器的位置实际上不是由分割器本身的一些属性决定的,而是由分割器停靠在其上的控件的大小决定的。

为了保存/恢复分割器的位置,我使用了一个 cookie。

持久分割器组件具有设计时支持,并且它具有可以在设计时设置的两个属性

  • CookieName - 用于保存/加载分割器名称的 cookie 的名称
  • DockedControl - 分割器停靠在其上的控件的名称

持久分割器有两个主要的private 方法

  • SaveSplitterPosition – 这是从分割器停靠在其上的控件的 Resize 事件处理程序中调用的,并且根据分割器的停靠样式,它将停靠控件的宽度(对于垂直分割器)或高度(对于水平分割器)的值保存在 cookie 中。
  • RestoreSplitterPosition – 这是从 HostControlLoaded 属性的 SET 访问器中调用的。 它告诉分割器,托管分割器和相关控件(特别是分割器停靠在其上的控件)的组件已加载,因此它们的位置可以在代码中进行操作)。

SaveSplitterPosition 中的代码很简单

private void SaveSplitterPosition()
{
    // if we have the cookie name set
    if (m_cookieName != string.Empty)
        // if this is vertical splitter, save the width of docked control
        if (this.Dock == DockStyle.Left || this.Dock == DockStyle.Right)
            VWGHelper.SetCookiesParameter
		(m_cookieName, m_dockedControl.Width.ToString()); 
        // if this is horizontal splitter, save the height of docked control
        else if (this.Dock == DockStyle.Top || this.Dock == DockStyle.Bottom)

            VWGHelper.SetCookiesParameter
		(m_cookieName, m_dockedControl.Height.ToString());
        else
            // for safety
            throw new Exception(string.Format("{0}: Invalid Dock value", this.Name));
}

RestoreSplitterPosition 的工作方式类似。 只有一个问题 – 由于在此方法中我们更改了停靠控件的大小,这将触发 Resize 事件,这将导致事件处理程序调用 SaveSplitterPosition,这将尝试再次保存 cookie 值。 为了防止这种情况,我们在启动过程时取消绑定 Resize 事件,并在完成时再次绑定。 代码如下所示

private void RestoreSplitterPosition()
{
    if (m_dockedControl != null && m_cookieName != string.Empty)
    {
        // we unbind from resize event of docked control, 
        // to avoid saving the position again in cookie
        m_dockedControl.Resize -= new EventHandler(m_dockedControl_Resize);
        try
        {
            // read the last location from cookie
            string offsetStr = VWGHelper.GetCookiesParameter(m_cookieName);
            bool dockValid = false;
            if (offsetStr != string.Empty)
            {
                int offsetInt = Int32.Parse(offsetStr);
                // if vertical splitter
                if (this.Dock == DockStyle.Left || this.Dock == DockStyle.Right)
                {
                    m_dockedControl.Width = offsetInt; 
                    dockValid = true;
                }
                // if vertical splitter
                else if (this.Dock == DockStyle.Top || this.Dock == DockStyle.Bottom)
                {
                    m_dockedControl.Height = offsetInt;
                    dockValid = true;
                }
                if (!dockValid) // for safety
                    throw new Exception(string.Format("{0}: 
				Invalid Dock value", this.Name));
            }
        }
        catch (Exception ex)
        {
            throw new Exception
		("Error in PersistentSplitter.RestoreSplitterPosition", ex) ;
        }
        finally
        {
            // we make sure we rebind to resize event, 
            // to save new splitter position if user changes it
            m_dockedControl.Resize = new EventHandler(m_dockedControl_Resize);
        }
    }
}

Using the Code

PersistentSplitter 功能由 HostControlLoaded 属性控制。 这是写入/只读的,用于在分割器停靠在其上的组件可用时通知分割器。 在那一刻,分割器可以通过调整其停靠组件的大小来恢复其位置。 这应该发生在宿主组件(表单或用户控件)的 Load 事件中,方法是将 HostControlLoaded 属性设置为 true。 这告诉 PersistentSplitter 控件表单上的所有控件都已加载,因此它可以从 cookie 设置左侧控件的大小以恢复其位置(如下所示)

private void Form1_Load(object sender, EventArgs e)
{ 
    persistentSplitter1.HostControlLoaded = true;
} 

您可以在此处查看使用 PersistentSplitter 组件的示例应用程序。

历史

© . All rights reserved.