zoukankan      html  css  js  c++  java
  • 模仿outlook快捷方式栏的一个控件

    hi,cnblogs readers,this is my first article here.——jinfd
    这是我的第一篇在这里的随笔,我在最近两三天把这个控件的主要代码写完了。
    这是一个用c#写的控件,它的原型是outlook 2000里面左侧的快捷方式栏,类似的控件也会在QQ,Visio等常用软件中找到,我为这个控件写了一个dll,并且做了一个demo演示它。

    如下图所示:


    我把一些主要的控件属性在demo里可以随时更改。它代码量不是很多,dll文件只有36kb。
    我没有为这个控件提供额外的面板,但是控件中的每个元素都具有Tag属性。
    提供了VisibleGroupChanged, ItemClick等主要事件。在它内部我封装了滚动处理,(按住滚动按钮超过0.5秒后由定时器自动滚动),封装了单选状态时的item互斥性切换。在控件中显示的内容全部是绘制而成,也就是说,它们都是逻辑元素,而非实际的子控件对象。为此,我定义了一个SbComponent类作为所有元素的父类,它主要描述了元素的布局信息,同时也提供了通用的HitTest测试方法以响应鼠标,Items对鼠标提供了悬停反馈,但是GroupHeader没有,因为我觉得它并不是最重要的功能,如果想加还是很简单的。在绘制元素时主要使用了ControlPaint类来实现。

    控件的内部组织结构如下图所示:



    控件的使用非常简单:我借鉴了treeview,listview控件的封装用法,
     1SideBar.SideBar sbar=new SideBar.SideBar();
     2//赋予imagelist
     3sbar.ImageList=this.imageList1;
     4sbar.AddGroup("第一组");
     5sbar.AddGroup("第二组");
     6//添加items,参数列表为:itemtext,imageindex
     7sbar.Groups[0].Items.Add("item0",0);
     8sbar.Groups[1].Items.Add("item1",1);
     9sbar.VisibleGroupChanged+=new SbGroupEventHandler(sbar_VisibleGroupChanged);
    10sbar.ItemClick+=new SbItemEventHandler(sbar_ItemClick);

    可以通过鼠标点击自动完成当前显示组的切换,也可以使用代码来完成:
     
    1//设置当前显示的组
    2sbar.VisibleGroupIndex=1;

    晚上的时候,我为这个控件加入了对拖放item的功能支持。不过这个功能确实具有一定挑战性,因为涉及到的鼠标处理比较复杂。我们可以看到,鼠标操作的主要特点是:
    1.当按下某个控件(例如按钮)时,保持鼠标按下状态,并移开控件,则该控件会弹起,如果此时抬起鼠标,则该控件不会被点击。如果保持鼠标按下并移回控件,控件继续显示成按下状态。即,必须按下和抬起时都捕捉到该控件,点击才有效。估计这是windows设计者考虑到了用户的误操作,允许用户可以此种方法取消点击控件。
    2. 当鼠标按下一个item并拖动它到临界区(靠近itemsbox边缘)时,如果item很多,则自动开始滚动。
    3. 当鼠标移动到其他GroupHeader时,会切换当前显示的Group。即允许用户将item从一个Group拖动到其他Group中。

    上面的挑战性和难点在于,需要根据鼠标的位置计算出需要插入的索引位置,以及要绘制标记插入位置的反馈,并且再位置改变时更新它。具体的细节比较复杂,为此我为sidebar引入了很多成员变量来记录一些必要的信息。也使得mousedown,mouseup,mousemove里面的代码量增加了几乎一倍。。。

    不过上面的烦琐细节都被我封装在内部,在外部的使用还是非常简单的。我提供了一个AllowDragItem属性,只需要简单的设置它即可选择是否支持拖放item。同时我考虑为控件增加一个新的事件把它通知给外部。

    1//使控件支持鼠标拖放条目
    2Sbar.AllowDragItem=true;

    你可以在这里下载到这个控件和例子的最新源代码:
    https://files.cnblogs.com/hoodlum1980/SideBar20070707.rar

    在这个网站上面还有我的其他几个比较小但是有趣的例子源码,也许会在以后详细介绍它们。
    ——————————————————————————————
    小Bug记录:
    1.修改了调整字体后布局错误的bug。
    2.修改了在demo中的一个疏忽:在显示字体对话框时,错误的将字体初始化为了form1的字体。
    3.我把影响外观的一些属性修改后的刷新显示封装在了控件内部。这个并不算什么严重的bug
    但会使外部使用时更为简便。例如,对enabled,view(大图标,小图标...),flatstyle等属性的修改,都会在控件内部调用刷新。在外部只要简单的设置它们的值即可。
  • 相关阅读:
    html5表单pattern属性配合正则验证电话和手机号码
    关于a href传参的中文乱码问题
    jq点击事件改变全局变量
    a标签带参页面跳转并在跳转页面接收参数
    json字段不存在,手动添加键值对
    各种类型相互转换
    Caused by: com.mysql.cj.exceptions.InvalidConnectionAttributeException: The server time zone value '�й���׼ʱ��' is unrecognized or r
    微信公众号之微信登录失败,redirect_uri域名与后台配置不一致,错误代码10003
    前后端数据json交换的问题
    jQuery EasyUI 的editor组件使用
  • 原文地址:https://www.cnblogs.com/hoodlum1980/p/807281.html
Copyright © 2011-2022 走看看