Tag:开源控件 , 源码下载 , 控件开发 , 控件美化 , 窗体换肤 , Skin , QQ表情 , Windows API , GDI+编程 , SQLite , Socket , 控件透明 , 下拉控件 , HTML 解析器 , 图片水印 , ScrollBar(滚动条) , Google Sitemap , 数据库 , SQL , WinForm , P/Invoke , C# 分隔栏控件SplitContainerEx , WinForm控件美化扩展 , C# GDI+

 
您的位置: >> 首页 >> C# 视角 >> C# WinForm控件美化扩展系列之实现点击收缩的SplitContainer控件

C# WinForm控件美化扩展系列之实现点击收缩的SplitContainer控件

2010-03-25  来自:CS 程序员之窗  字体大小:【  
  • 摘要:本文介绍扩展SplitContainer控件,在分隔栏上实现一个按钮,点击按钮可以收缩分隔栏中的一个面板(Panel),实现像QQ游戏中的分隔栏那样的效果。

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

 

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

 

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

 

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

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

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

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