很多常用的软件中,我们都可以看到分隔栏(Split或SplitContainer)的使用,而且可以点击然后收缩其中的某个面板,例如QQ游戏大厅:



.NET也提供了分隔栏控件(Split或SplitContainer),但是却不能实现点击收缩的功能,不过我们可以在它的基础上实现点击收缩的功能。下面就来详细介绍怎样实现分隔栏控件点击收缩的功能。

首先来看看最终需要实现的效果:



  现在说明一下实现分隔栏控件点击收缩的功能的原理,原理很简单:

1.       确定点击按钮在分割栏的位置(实现的时候是取分隔栏的中间位置),然后在分隔栏上把按钮画出来。

2.       实现一个属性(CollapsePanel),以便选择使哪一个面板收缩,SplitContainer控件有两个面板,分别是Panel1和Panel2。

3.       提供一个点击按钮的事件(CollapseClick),当点击按钮的时候响应这个事件,以方便处理点击操作,默认的处理就是收缩和展开面板。

4.       重点,处理SplitContainer控件的鼠标事件(OnMouseMove、OnMouseDown、OnMouseUp、OnMouseLeave),以便处理按钮的点击、是否允许拖动分隔栏和改变控件的鼠标指针样式。

下面是SplitContainer控件扩展后的类视图:



下面来看看中要的实现代码:

CollapsePanel属性:

[DefaultValue(typeof(CollapsePanel), "1")]

public CollapsePanel CollapsePanel

{

get { return _collapsePanel; }

set

{

if (_collapsePanel != value)

{

Expand();

_collapsePanel = value;

}

}

}

重写OnMouseMove方法:

protected override void OnMouseMove(MouseEventArgs e)

{

//如果鼠标的左键没有按下,重置HistTest

if (e.Button != MouseButtons.Left)

{

_histTest = HistTest.None;

}

Rectangle collapseRect = CollapseRect;

Point mousePoint = e.Location;

//鼠标在Button矩形里,并且不是在拖动

if (collapseRect.Contains(mousePoint) &&

_histTest != HistTest.Spliter)

{

base.Capture = false;

SetCursor(Cursors.Hand);

MouseState = ControlState.Hover;

return;

}//鼠标在分隔栏矩形里

else if (base.SplitterRectangle.Contains(mousePoint))

{

MouseState = ControlState.Normal;

//如果已经在按钮按下了鼠标或者已经收缩,就不允许拖动了

if (_histTest == HistTest.Button ||

(_collapsePanel != CollapsePanel.None &&

_spliterPanelState == SpliterPanelState.Collapsed))

{

base.Capture = false;

base.Cursor = Cursors.Default;

return;

}

//鼠标没有按下,设置Split光标

if (_histTest == HistTest.None &&

!base.IsSplitterFixed)

{

if (base.Orientation == Orientation.Horizontal)

{

SetCursor(Cursors.HSplit);

}

else

{

SetCursor(Cursors.VSplit);

}

return;

}

}

MouseState = ControlState.Normal;

//正在拖动分隔栏

if (_histTest == HistTest.Spliter &&

!base.IsSplitterFixed)

{

if (base.Orientation == Orientation.Horizontal)

{

SetCursor(Cursors.HSplit);

}

else

{

SetCursor(Cursors.VSplit);

}

base.OnMouseMove(e);

return;

}

base.Cursor = Cursors.Default;

base.OnMouseMove(e);

}

重写OnMouseDown方法:

protected override void OnMouseDown(MouseEventArgs e)

{

Rectangle collapseRect = CollapseRect;

Point mousePoint = e.Location;

if (collapseRect.Contains(mousePoint) ||

(_collapsePanel != CollapsePanel.None &&

_spliterPanelState == SpliterPanelState.Collapsed))

{

_histTest = HistTest.Button;

return;

}

if (base.SplitterRectangle.Contains(mousePoint))

{

_histTest = HistTest.Spliter;

}

base.OnMouseDown(e);

}

重写OnMouseUp方法:

protected override void OnMouseUp(MouseEventArgs e)

{

base.OnMouseUp(e);

base.Invalidate(base.SplitterRectangle);

Rectangle collapseRect = CollapseRect;

Point mousePoint = e.Location;

if (_histTest == HistTest.Button &&

e.Button == MouseButtons.Left &&

collapseRect.Contains(mousePoint))

{

OnCollapseClick(EventArgs.Empty);

}

_histTest = HistTest.None;

}

重写OnMouseLeave方法:

protected override void OnMouseLeave(EventArgs e)

{

base.Cursor = Cursors.Default;

MouseState = ControlState.Normal;

base.OnMouseLeave(e);

}

以上介绍SplitContainer控件的扩展,希望能对你了解扩展SplitContainer控件有所帮助。

声明:

本文版权归作者和CS 程序员之窗所有,欢迎转载,转载必须保留以下版权信息,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

作者:Starts_2000

出处:CS 程序员之窗 http://www.csharpwin.com。

你可以免费使用或修改提供的源代码,但请保留源代码中的版权信息,详情请查看:

CS程序员之窗开源协议 http://www.csharpwin.com/csol.html。

牛bb文章网欢迎您转载分享:http://www.niubb.net/a/2015/04-29/332432.html

arrow
arrow
    全站熱搜

    戮克 發表在 痞客邦 留言(0) 人氣()