• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号
您的位置:首页 > 程序设计 >C#教程 > .net2.0+ Winform项目实现弹出容器层

.net2.0+ Winform项目实现弹出容器层

作者:ahdung 字体:[增加 减小] 来源:互联网 时间:2017-05-28

ahdung 通过本文主要向大家介绍了net2.0,net2.0官方下载,net2.0 64位,.net2.0下载,net2.0官方下载中文等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com

适用于:.net2.0+ Winform项目

背景:

有时候我们需要开一个简单的窗口来做一些事,例如输入一些东西、点选一个item之类的,可能像这样:

完了返回原窗体并获取刚刚的输入,这样做并没有什么问题,但在几天前我突然产生了一些想法:为什么非得有板有眼的弹出一个窗体给用户呢,是不是可以在按钮附近迅速呈现一个层来做这些事呢,类似快捷菜单那样,用户高兴就在里面做一下该做的事,不高兴就在其它地方点一下它就消失,本来很轻便快捷的操作,DUANG~弹出一个窗体来会不会令用户心里咯噔一下呢,感受层面的事情往往是很微妙的,不管怎样,我既然起了这个念头,just try it。

我首先找了一下现成的方案,果然在牛逼的codeproject.com已经有牛人做了这样的事情:

http://www.codeproject.com/Articles/17502/Simple-Popup-Control

简单体验了一下,的确是了不起的创造。原理是利用ToolStripControlHost可以承载自定义控件的这一能力,让下拉式控件ToolStripDropDown将任何自定义控件像右键菜单那样弹出来(别忘了右键菜单ContextMenuStrip就是继承自ToolStripDropDown),这样就等于把菜单作为一个容器,可以弹出任何或简单或复杂的控件组合,同时又具有菜单具有的便捷性,召之即来挥之即去。当时了解到这方案的时候真挺开心,正是我想要的效果,感觉这下好了,不用瞎费劲自己造了。

但很快发现一个在我看来还挺在意的不足,就是ToolStripDropDown只有Show,没有ShowDialog,就是不能以模式化(Modal,也有叫模态的,鉴于MSDN都称模式,我也随流叫它模式)的方式弹出,这是由ToolStripDropDown的固有能力决定的,该方案既然基于ToolStripDropDown,自然也受限于此,不能模式化弹出。这样带来的问题是某些情况下的调用体验不好(体验这种事当然不是用户才有的专利,俺们码农也是人,也要讲体验的说),比如弹出的控件是让用户输入一些东西,完了用户点击某个按钮什么的返回原窗体,然后在原窗体获取用户刚刚的输入,然后接着做后面的事。由于非模式的Show不会阻塞代码,所以就不能在Show的下方想当然的获取值、使用值~这是显然的。要想获得值可能就得额外采取一些做法,例如响应弹出控件的关闭事件,或者把原窗体传入弹出控件完了在后者中做原本应该在原窗体中做的事~等等,办法当然有很多,但这都是因为只能Show带来的多余的事,有什么比在一个方法中弹出控件、等待返回、继续处理来的爽滑的呢,像这样不是很自然吗:

所以很遗憾,不得不挥别这个优秀的方案,造自己的轮子。不过受该方案的启发,我想到用ContextMenu来做容器(注意这个菜单类跟上面提到的继承自ToolStripDropDown的ContextMenuStrip大大的不同,前者是OS原生的菜单,就是在桌面、图标以及文本框中右键弹出的那种菜单,.net是通过调API的方式来操作这样的菜单,而后者则完全是.net实现,更多信息请参考MSDN,此处不展开),因为ContextMenu的Show是阻塞式的,正合我意。但一番尝试之后放弃,它的菜单项MenuItem不像ToolStripItem那样可以通过ToolStripControlHost承载自定义控件,希望是我能力有限,总之我做不到把自定义控件弄到ContextMenu上,也没见过原生菜单上出现过文本框、复选框等奇怪的东西,如果您知道怎么扩展原生菜单,还望不吝赐教,先行谢过!

我还是打回.net的主意,当中仍然是做了许多不同的尝试,Form、Panel、UserControl、ContainerControl、Control等等看起来适合做容器层的东西都试了个遍,甚至重新在ToolStripDropDown上打主意,最后选用Form,改造一番,自我感觉较理想的实现了我要的东西:一个叫做FloatLayerBase的基类,它本身继承自System.Windows.Forms.Form类,而需要作为浮动层显示的应用则继承自FloatLayerBase进行实现,例如下面这个接受用户输入数值的NumInputDemo实现:

样子和特点:不会令父窗口失去焦点(不会抢焦点的层才是好层):

当然,男人不止一面:

还有其它边框样式,有待用户自行体验,最后有demo提供。

可以有调整尺寸的手柄:

可以点住客户区拖动:

别的一些应用:

这些都只是demo,没那么好看和强大,重点是有了这个FloatLayerBase,就可以实现自己的浮动应用。

使用说明:确保FloatLayerBase类在项目中~废话。源码在此:

using System;
using System.ComponentModel;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace AhDung.WinForm.Controls
{
  /// <summary>
  /// 浮动层基类
  /// </summary>
  public class FloatLayerBase : Form
  {
    /// <summary>
    /// 鼠标消息筛选器
    /// </summary>
    //由于本窗体为WS_CHILD,所以不会收到在窗体以外点击鼠标的消息
    //该消息筛选器的作用就是让本窗体获知鼠标点击情况,进而根据鼠标是否在本窗体以外的区域点击,做出相应处理
    readonly AppMouseMessageHandler _mouseMsgFilter;

    /// <summary>
    /// 指示本窗体是否已ShowDialog过
    /// </summary>
    //由于多次ShowDialog会使OnLoad/OnShown重入,故需设置此标记以供重入时判断
    bool _isShowDialogAgain;

    //边框相关字段
    BorderStyle _borderType;
    Border3DStyle _border3DStyle;
    ButtonBorderStyle _borderSingleStyle;
    Color _borderColor;

    /// <summary>
    /// 获取或设置边框类型
    /// </summary>
    [Description("获取或设置边框类型。")]
    [DefaultValue(BorderStyle.Fixed3D)]
    public BorderStyle BorderType
    {
      get { return _borderType; }
      set
      {
        if (_borderType == value) { return; }
        _borderType = value;
        Invalidate();
      }
    }

    /// <summary>
    /// 获取或设置三维边框样式
    /// </summary>
    [Description("获取或设置三维边框样式。")]
    [DefaultValue(Border3DStyle.RaisedInner)]
    public Border3DStyle Border3DStyle
    {
      get { return _border3DStyle; }
      set
      {
        if (_border3DStyle == value) { return; }
        _border3DStyle = value;
        Invalidate();
      }
    }

    /// <summary>
    /// 获取或设置线型边框样式
    /// </summary>
    [Description("获取或设置线型边框样式。")]
    [DefaultValue(ButtonBorderStyle.Solid)]
    public ButtonBorderStyle BorderSingleStyle
    {
      get { return _borderSingleStyle; }
      set
      {
        if (_borderSingleStyle == value) { return; }
        _borderSingleStyle = value;
        Invalidate();
      }
    }

    /// <summary>
    /// 获取或设置边框颜色(仅当边框类型为线型时有效)
    /// </summary>
    [Description("获取或设置边框颜色(仅当边框类型为线型时有效)。")]
    [DefaultValue(typeof(Color), "DarkGray")]
    public Color BorderColor
    {
      get { return _borderColor; }
      set
      {
        if (_borderColor == value) { return; }
        _borderColor = value;
        Invalidate();
      }
    }

    protected override sealed CreateParams CreateParams
    {
      get
      {
        CreateParams prms = base.CreateParams;

        //prms.Style = 0;
        //prms.Style |= -2147483648;  //WS_POPUP
        prms.Style |= 0x40000000;   //WS_CHILD 重要,只有CHILD窗体才不会抢父窗体焦点
        prms.Style |= 0x4000000;    //WS_CLIPSIBLINGS
        prms.Style |= 0x10000;     //WS_TABSTOP
        prms.Style &= ~0x40000;    //WS_SIZEBOX    去除
        prms.Style &= ~0x800000;    //WS_BORDER    去除
        prms.Style &= ~0x400000;    //WS_DLGFRAME   去除
        //prms.Style &= ~0x20000;   //WS_MINIMIZEBOX  去除
        //prms.Style &= ~0x10000;   //WS_MAXIMIZEBOX  去除

        prms.ExStyle = 0;
        //prms.ExStyle |= 0x1;     //WS_EX_DLGMODALFRAME 立



 
分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

  • dotNet中的反射用法入门教程
  • .net2.0+ Winform项目实现弹出容器层

相关文章

  • 2017-05-28c#判断正确的ip地址格式示例
  • 2017-05-28asp.net新闻列表生成静态页之批量和单页生成
  • 2017-05-28浅析泛型类接口定义
  • 2017-05-28Repeater控件绑定的三种方式
  • 2017-05-28一种c#深拷贝方式完胜java深拷贝(实现上的对比分析)
  • 2017-05-28将文件夹下所有文件输出到日志文件中 c#递归算法学习示例
  • 2017-05-28C#时间戳基本用法实例分析
  • 2017-05-28C#文件分割的方法
  • 2017-05-28C#不可变类型深入解析
  • 2017-05-28C#实现的微信网页授权操作逻辑封装示例

文章分类

  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号

最近更新的内容

    • C#实现多线程的同步方法实例分析
    • C#的WebBrowser的操作与注意事项介绍
    • C#中使用JSON.NET实现JSON、XML相互转换
    • VB.NET中TextBox的智能感知应用实例
    • C#实现Excel表数据导入Sql Server数据库中的方法
    • c#通过ip获取地理信息
    • C#实现由四周向中心缩小的窗体退出特效
    • C#实现百度ping推送功能的方法
    • C# WinForm创建Excel文件的实例
    • 怎么利用c#修改services的Startup type

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有