一种用户体验-显示对话框时灰化你的主窗体

袁永福 ( http://www.xdesigner.cn ) 2007-8-10

程序全部源代码下载(工程文件使用VS.NET2003格式):/Files/xdesigner/DisableMask.rar

    在一些Web程序中,有一种页面效果,当弹出一个模拟的对话框时,主页面就整体灰化了,其他的元素不能动弹,只有这个对话框能用,用户关闭了对话框,整个页面才恢复原来的操作.这种用户体验是不错的,提示了用户必须处理的对话框才能继续处理页面.如何实现的我猜想是动态生成一个大的DIV层,把它置于顶层并设置半透明的灰色.

    在WinForm程序中也需要这种用户体验,我们有时观察到主窗体显示了一个对话框,此时用户还试图用鼠标点击主窗体搞些操作,但这种操作注定是要失败,影响到软件可用性.于是我就想到把Web程序中的这种用户体验移植到WinForm程序中来帮助用户意识到主窗体的当前状态.

    实现这个用户体验有两个问题,一是如何知道主窗体弹出对话框,二是如何灰化主窗体.

    首先是解决如何知道主窗体何时弹出对话框,研究了一下,没发现窗体对象System.Windows.Forms.Form类型提供有所帮助的事件方法属性.我们可以在程序代码中,每次弹出对话框前添加灰化主窗体的代码,这样加大了程序开发量,而且代码移植性不好。后来想了又想,试了又试,发现弹出对话框时,主窗体的状态是不可用的,但此时窗体的Enabled属性不能反应这种状态,使用Win32API函数却能正确获得其状态.因此最后决定使用计时器System.Windows.Forms.Timer来不断的调用Win32API函数来测试主窗体是否可用,若可用则不必灰化主窗体,若不可用则灰化主窗体。

    第二步就是灰化主窗体了,根据WEB程序中的实现过程,我们很自然的想到用一个半透明的控件来覆盖整个主窗体,于是我们又如何创造这个半透明控件。纵观System.Windows.Forms名称空间,号称提供半透明效果效果的只有Label类型了,经过测试,发现Label类型的半透明属性是假的,是模拟出来的,它是在控件背景中模拟绘制窗体的背景来搞出半透明的效果,若Label控件背后有其他控件还是要被Label无情的覆盖掉。因此我们需要一个真正的半透明控件,于是我又想了又想,试了又试,找了又找,终于把这个真正的半透明控件搞出来了。

    基础问题解决了,然后就是代码的组成和组件化了,我定义了一个DisableMaskControl控件,实现了真正的半透明处理,里面有个定时器,不断的使用Win32API函数测试这个控件所在的窗体是否有效,若有效则隐藏控件,若无效则显示控件,把控件覆盖整个窗体并置于顶层。这样我就用一百来行的C#代码实现了这种弹出对话框灰化主窗体的用户体验,而且这个代码使用非常简单,只要在需要这种效果的主窗体上添加一行代码 this.Controls.Add( new DisableMaskControl()) 即可。

   此处或许有人提出这个定时器的效率问题,我觉得没多大问题,首先控件少,一个窗体才用一个,相对于高速的CPU,用户手动操作来显示和关闭对话框是极其缓慢的操作。而且定时器中进行的判断不多,只调用了一个API函数,无伤大雅。

   以下是程序的运行效果。

disablemask.PNG

   以下是控件 DisableMaskControl的全部代码。

  1 using System;
  2 using System.Runtime.InteropServices ;
  3 namespace DisableMask
  4 {
  5     /// <summary>
  6     /// 窗体无效时用于掩盖整个状态的半透明控件
  7     /// </summary>
  8     /// <remarks>编制 袁永福( http://www.xdesigner.cn )</remarks>
  9     public class DisableMaskControl : System.Windows.Forms.Control
 10     {
 11         /// <summary>
 12         /// 初始化对象
 13         /// </summary>
 14         public DisableMaskControl()
 15         {
 16             this.SetStyle( System.Windows.Forms.ControlStyles.SupportsTransparentBackColor , true );
 17             myTimer = new System.Windows.Forms.Timer();
 18             myTimer.Interval = 100 ;
 19             myTimer.Tick +=new EventHandler(myTimer_Tick);
 20             this.BackColor = System.Drawing.Color.FromArgb( 80 , 0 , 0 , 0 );
 21             myTimer.Start();
 22         }
 23         /// <summary>
 24         /// 内部用于定时处理的计时器
 25         /// </summary>
 26         private System.Windows.Forms.Timer myTimer = null;
 27 
 28         /// <summary>
 29         /// 已重载:返回控件创建参数
 30         /// </summary>
 31         protected override System.Windows.Forms.CreateParams CreateParams
 32         {
 33             get
 34             {
 35                 System.Windows.Forms.CreateParams ps = base.CreateParams;
 36                 ps.ExStyle = ps.ExStyle | 0x20 ;
 37                 return ps ;
 38             }
 39         }
 40 
 41         /// <summary>
 42         /// 绘制控件的背景,啥也不干.
 43         /// </summary>
 44         /// <param name="pevent">事件参数</param>
 45         protected override void OnPaintBackground(System.Windows.Forms.PaintEventArgs pevent)
 46         {
 47         }
 48         /// <summary>
 49         /// 绘制控件
 50         /// </summary>
 51         /// <param name="e">事件参数</param>
 52         protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
 53         {
 54             using( System.Drawing.SolidBrush b = new System.Drawing.SolidBrush( this.BackColor ))
 55             {
 56                 e.Graphics.FillRectangle( b , e.ClipRectangle );
 57             }
 58         }
 59 
 60         /// <summary>
 61         /// 定时器处理
 62         /// </summary>
 63         /// <param name="sender">事件参数</param>
 64         /// <param name="e">事件参数</param>
 65         private void myTimer_Tick(object sender, EventArgs e)
 66         {
 67             System.Windows.Forms.Form frm = this.FindForm();
 68             if( frm == null )
 69                 return ;
 70             if( frm.IsDisposed )
 71                 return ;
 72             ifthis.IsDisposed )
 73                 return ;
 74             ifthis.IsHandleCreated == false )
 75                 return ;
 76 
 77             // 主窗体显示对话框时窗体不可用,但此时它的Enable属性无法判断其是否真的
 78             // 不可用,因此必须调用Win32API来判断其是否真的不可用.
 79             if( IsWindowEnabled( frm.Handle ) == false )
 80             {
 81                 ifthis.Visible == false )
 82                 {
 83                     this.Dock = System.Windows.Forms.DockStyle.None ;
 84                     this.Bounds = new System.Drawing.Rectangle( 
 85                         0 , 
 86                         0 , 
 87                         frm.ClientSize.Width ,
 88                         frm.ClientSize.Height );
 89                     this.BringToFront();    
 90                     this.Visible = true;
 91                     this.Refresh();
 92                     frm.Refresh();
 93                 }
 94             }
 95             else
 96             {
 97                 ifthis.Visible )
 98                     this.Visible = false;
 99             }
100         }
101 
102         /// <summary>
103         /// 用于判断窗体是否有效的Win32API函数
104         /// </summary>
105         /// <param name="hWnd">窗体句柄</param>
106         /// <returns>窗体是否有效</returns>
107         [DllImport("user32.dll", CharSet=CharSet.Auto, ExactSpelling=true)]
108         private static extern bool IsWindowEnabled(IntPtr hWnd);
109 
110     }//public class DisableMaskControl : System.Windows.Forms.Control
111 }

转载于:https://www.cnblogs.com/xdesigner/archive/2007/08/10/850235.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/410741.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

html文档中用于表示页面标题的标记对是,汽车发动机拆装与检修实训超星尔雅答案...

摘要&#xff1a;汽车生活事件也称为应激源( )在教师的直接领导下整个班级的学生一起进行的学习&#xff0c;机拆检修称为( )实训教学二字连用最早出自( )...汽车生活事件也称为应激源( )发动下列不属于课程与教学关系观的是( )在教师的直接领导下整个班级的学生一起进行的学习…

H5|web移动前端自适应适配布局解决方案

方案&#xff1a; 固定一个某些宽度&#xff0c;使用一个模式&#xff0c;加上少许的媒体查询方案使用flexbox解决方案使用百分比加媒体查询使用rem1. 简单问题简单解决 我觉得有些web app并一定很复杂&#xff0c;比如拉勾网&#xff0c;你看看它的页面在iphone4,iphone6,ipad…

[转] 用Diff和Patch工具维护源码

在Unix系统下&#xff0c;维护源码版本可以使用很多方法&#xff0c;其中最常用的当然是大名鼎鼎的CVS&#xff0c;但实际上&#xff0c;简单的版本维护工作并没有必要使用复杂的CVS等专门的版本维护工具&#xff0c;Unix标配中的diff和patch工具就完全可以完成代码的简单备份和…

jQuery 结合 Json 提交数据到Webservice,并接收从Webservice返回的Json数据

简单的Json数据提交 jQuery ajax webservice&#xff1a;get 和 post 一、GET 方式客户端代码vardata { classCode: "0001"}; //这里要直接使用JOSN对象$.ajax({ type: "GET", contentType: "application/json; chars…

X86逆向教程10:学会使用硬件断点

本节课我们将学习硬件断点的使用技巧&#xff0c;硬件断点是由硬件提供给我们的一组寄存器&#xff0c;我们可以对这些硬件寄存器设置相应的值&#xff0c;然后让硬件帮我们断在需要下断点的地址上面&#xff0c;这就是硬件断点&#xff0c;硬件断点依赖于寄存器&#xff0c;这…

html 监控键盘,后台监控鼠标和键盘(可监听全局的鼠标以及键盘按键)

资源下载此资源下载价格为3D币&#xff0c;请先登录资源文件列表MouseKeyboardLibrary/MouseKeyboardLibrary/app.config , 134MouseKeyboardLibrary/MouseKeyboardLibrary/bin/Debug/MouseKeyboardLibrary.exe , 23040MouseKeyboardLibrary/MouseKeyboardLibrary/bin/Debug/Mo…

POJ 3258 River Hopscotch

题目链接&#xff1a;https://vjudge.net/problem/POJ-3258 题目大意 给定数轴上一个起点 0&#xff0c;终点 L&#xff0c;以及中间 N 个不同的点&#xff0c;现准备删除中间 N 个点中的 M 个&#xff0c;使得剩下来的点&#xff08;包括起点和终点&#xff09;&#xff0c;相…

2021泉州高考学校成绩查询,2021泉州市地区高考成绩排名查询,泉州市高考各高中成绩喜报榜单...

距离2018年高考还有不到一个月的时间了&#xff0c;很多人在准备最后冲刺的同时&#xff0c;也在关心高考成绩。2018各地区高考成绩排名查询,高考各高中成绩喜报榜单尚未公布&#xff0c;下面是往年各地区高考成绩排名查询,高考各高中成绩喜报榜单&#xff0c;想要了解同学可以…

转载:CEO如何“养好CIO同时管好CIO”?

http://www.enet.com.cn/article/2010/1214/A20101214800028.shtml 在现代企业经营理论中&#xff0c;有个着名的“二八定律”&#xff0c;即人才对企业贡献而言&#xff0c;常常是20%的人做出了80%的企业效益。显而易见&#xff0c;这“20%”就是企业的骨干与核心。而这“20%”…

Abraca:XMMS2 的客户端

Toy Posted in AppsRSSTrackback Abraca 是基于 GTK2 而开辟的 XMMS2 音乐播放器的客户端。今后具有播放列表、音乐经管等功用。需留神的是&#xff0c;此法式要求 XMMS2、GTK 2、libglade、libnotify&#xff08;可选&#xff09;、Python 等。- Download Abraca 0.1版权声明&…

pandas plot label_数据科学| 手把手教你用 pandas 索引、汇总、处理缺失数据

作者&#xff1a;Paul编者按&#xff1a; pandas提供了很多常用的数学和统计方法&#xff0c;本文中将用十分详细的例子来具体进行介绍&#xff1b;另外在许多数据分析工作中,缺失数据是经常发生的&#xff0c;将会具体介绍如何处理缺失数据。本文十分详细并实在低介绍了pandas…

2011年三八妇女节搜索引擎LOGO设计欣赏

今天是一年一度的三八国际妇女节&#xff0c;在这个特别的日子&#xff0c;烈火学院向所有女性致以节日的祝福&#xff0c;祝愿每位女同胞节日快乐&#xff0c;工作愉快&#xff01;并送上本期的搜索引擎LOGO设计欣赏&#xff0c;希望大家喜欢&#xff01; 一。百度 有作家曾说…

诺基亚2亿欧元建越南新工场

诺基亚昨天颁布发表将会在越南北部河内左近设立扶植一个新的装配厂&#xff0c;方案于2012年尾投入运用&#xff0c;初期投资达到2亿欧元&#xff0c;约合18.3亿人夷易近币。诺基亚目下当今在世界上拥有10个工场&#xff0c;新厂将会进入到诺基亚的举世制造搜集&#xff0c;为他…

Android 一直往文件写数据_( 十 ) 小众但好用:通过 Google drive 备份与同步 Keepass 数据库...

之前有提到过&#xff0c;keepass 的数据库是加密保存在本地的。而且 keepass 又是多平台免费的密码管理软件。所以如果需要实现 keepass 在多平台读取同一个数据库&#xff0c;我们需要自己搭一个服务器才怪&#xff01;搭服务器太麻烦&#xff0c;还要额外支出费用&#xff0…

mysql操作数据库

转载于:https://www.cnblogs.com/sunpxit/p/11189089.html

win7锁定计算机会断网吗,win7系统如何设置电脑定时断网

有些win7系统用户在使用电脑过程中&#xff0c;想要给电脑设置定时断网&#xff0c;但是却不知道要怎么操作&#xff0c;其实我们可以通过系统自带的任务计划功能来进行操作&#xff0c;该怎么操作呢&#xff0c;本教程就给大家讲解一下win7系统设置电脑定时断网的详细步骤。1、…

回文_Manacher算法

算法简介:算法的目的是在O(n)的时间复杂度内找到一个字符串中各个字母所在的最大长度的回文串。 此算法用到了一个Rad[]数组的定义&#xff0c;Rad[i]表示回文的半径&#xff0c;即最大的j满足str[i-j1...i] str[i1...ij]。 我们的工作就是把全部的Rad[]求出来。 有两个结论: …

linux 查当前pid_杀死僵尸进程,你需要这些神奇高效的Linux命令行

Linux 高手&#xff0c;其实都是玩儿命令行很熟练的人。命令行的学习捷径Linux 命令有许多强大的功能&#xff1a;从简单的磁盘操作、文件存取&#xff0c;到进行复杂的多媒体图像和流媒体文件的制作&#xff0c;都离不开命令行。在 Linux 的学习中&#xff0c;新手都会遇到这么…

3d000: no database selected_No.[C9]020

No.[C9]-020”Youre Not Alone&#xff0c;never alone。“别难过&#xff0c;别害怕&#xff0c;这个世界还有那么多爱你的人&#xff0c;和支持你的人&#xff0c;生活可能没有那么趁人心意&#xff0c;每个人都如此&#xff0c;别灰心&#xff0c;你并不孤单。(愿我的好朋友…

js实现树形结构化

我是歌谣 放弃很容易 但是坚持一定很酷 微信公众号关注小歌谣 日常分享前后端知识 前言 今天来讲一下平常我们做权限系统中的树形结构知识 就是如何把对应关系的结构数据转换为可以一个树形结构 const data [{id: 2,pid: 0,path: /course,name: Course,title: 课程管理},{id…