精华内容
下载资源
问答
  • 1.亲爱的自己,这个世界只有回不去的而没有什么是过不去的。2.在这个特别的日子里,我没有别的话,只想你知道,每年今天,你都会收到我的祝福,感到我的爱,永远的爱!3.在遇到梦中人之前,上天也许会安排我们先遇到...

    1. 亲爱的自己,这个世界只有回不去的而没有什么是过不去的。

    2. 在这个特别的日子里,我没有别的话,只想你知道,每年今天,你都会收到我的祝福,感到我的爱,永远的爱!

    3. 在遇到梦中人之前,上天也许会安排我们先遇到别的人;在我们终于遇见心仪的人时,便应当心存感激。祝自己生日快乐.

    4. 余生没那么长,请忠于自己,活得像最初的模样,致自己生日快乐。

    5. 努力做一个积极向上的人,致自己的十八岁,生日快乐,亲爱的自己!

    6. 愿有人待你如初,疼你入骨,从此深情不被辜负。敬你一杯酒,愿你有诗,有梦,有坦荡荡的远方,我干杯,你随意。生日快乐,致自己!

    7. 又长一岁,应该又成熟了许多,不能在浪费光阴了温柔不帅,祝自己永远开心快乐,找到幸福。祝我生日快乐!

    8. 默默的祝自己生日快乐,时间过得真的很快,转眼就23了,希望自己以后能保持初心,砥砺前行

    9. 离开的人越来越多,留下的人越来越重要。时间太快,你别太慢。爸爸妈妈辛苦了,祝自己生日快乐!

    10. 又是一年,照顾好自己,如果尚有余力,记得保护美好的东西,不畏不怖不怂不退不磨叽。祝自己生日快乐

    11. 我爱自己,没有情敌~祝我生日快乐!或向着天空,或向着大海,或向着草原,宣泄自己的快乐!更重要的是,对自己的心说,生日快乐

    12. 生命是一种喜悦,愿我的生活,永远充满喜悦,祝生日快乐!

    13. 愿我们永远敢爱敢恨,活的简单勇敢坚定纯粹,像个少年;愿明年今日不会辜负此时的心意。

    14. 这个点萱闹夜,折腾半个小时哄好,还有55分钟到我的30岁,祝自己生日快乐,余生,只有你,晚安,全世界!

    15. 娇艳的鲜花,已为你开放;美好的日子,已悄悄来临。祝我生日快乐!

    16. 你不要老是想依赖别人,更不能奢望别人在你需要的时候第一时间站出来,毕竟你们谁都不是谁的谁。

    17. 爱你的人如果没有按你所希望的方式来爱你,那并不代表他们没有全心全意地爱你。祝自己生日快乐!

    18. 亲爱的自己,今天是你的生日,生日快乐,记得要常常仰望天空,记住仰望天空的时候也要看看脚下。

    19. 亲爱的自己,今天是你的生日,生日快乐,学会控制自己的情绪,谁都不欠你,所以你没有道理跟别人随便发脾气,耍性子。

    20. 今年可能是最难的一年经历了太多看错了很多希望从今天起好的坏的都是风景余生不负自己路很长干就完了!最后祝自己生日快乐,待我归来!

    21. 风里的梦,挽留不住。梦里的风,不必挽留。我愿随风去,挽留那梦境。祝自己生日快乐!

    22. 在人生道路上,走上坡路要昂首阔步,走下坡路要谨小慎微,走阳关道要目视前方,走羊肠路要俯视脚下。祝自己生日快乐!

    23. 时间不停,看透了很多,放下了很多,慢慢没了棱角,没了拼劲,慢慢被生活所缚,即使这样,我依然在尽全力的苦中作乐。独自在陌生的城市里,祝自己生日快乐,感谢有你们,晚安梦中人

    24. 随着年纪的增长,慢慢地我知道了,谁一路走来都不容易,没有人可以真正走得了捷径,好运气只是少数时候,你并不算倒霉的。而当你正在发愁埋怨的时候却有人仰望地羡慕着你!祝自己生日快乐!!

    25. 在这个特殊的日子,祝愿生活越来越美好,让美丽潇洒永远相伴。

    26. 愿我经得起冷落,耐得住寂寞,眼中既容得下牛鬼神蛇,心里也藏得住清风明月。

    27. 一晃眼,多少个年华已过,匆匆离去的是时光和背影,刻在心头的是回忆和期待。

    展开全文
  • 最初产生这样一个需求是源于项目经理近乎白痴般要求,有一天,他告诉我说那个弹出来消息框太小了。我告诉他,这是系统自带东西,大小随着给定文本内容长度自动变化,他说不行,给弄大点,而且字体也太小,...

    摘要
    1.是什么导致我们需要提供一个自定义的消息框?
    2.说说我的大致思路
    3.你的亮点在哪里?
    4.难道就是这些吗?

    下载本文讲述的项目源码包

    是什么导致我们需要提供一个自定义的消息框?

    最初产生这样一个需求是源于项目经理的近乎白痴般的要求,有一天,他告诉我说那个弹出来的消息框太小了。我告诉他,这是系统自带的东西,大小随着给定文本内容的长度自动变化,他说不行,给弄大点,而且字体也太小,换个字体吧!我的天,难道架构师都是从来不真实写代码的吗?

    接 到这个要求,想想也许不大难吧。先看看系统给了我什么接口:MessageBox位于System.Windows.Forms命名空间内,是一个被密封了的静态类,能够使用的公共方法也就是MessageBox.Show,倒是有很多重载版本,也有一个选项参数,但该参数却没提供我真正感兴趣的东西。

    碰 到问题我还是老规矩,首先请教Google,然后直接上codeproject或sourceforge查找,一般的问题都可以解决。一看,原来大家都曾 有过这样的需求啊;再来看别人的解决方法。大部分人使用Hook,也就是系统消息拦截,获取消息框的句柄,然后使用winApi篡改该窗体的某些特征;这样的示例非常多,而且有着非常有特色的特征:可以在上面添加个comboBox,告诉它Don't show this in the next time;可以赋予按钮自己想要的文本值;也能修改一些文本的字体和字号属性;

    看起来这就是我要的解决方案,因为它几乎能做一切;作为 windows上的新手,我于是迫切需要去弄弄Hook,这东西也不难;可问题在于,我发现无论怎么去尝试修改那些作者使用Hook做的示例,最后的结果仍然是:该消息框上所有使用文本的地方最终都是同一个变化!也就是说你如果把Message Text部分的字体弄成Vadana,按钮上的文本的字体也会变为Vadana,这居然是一体的!

    很好,我正不想弄Hook,这东西我就没弄成功过,别人例子都行,我就是不行!

    也罢,逼急了,我自己来搞一个。


    说说我的大致思路

    .NET下画个窗体不难,事实上拖下鼠标就行了;问题在于一样东西总是牵扯到其它的很多东西。
    ok,看看我自己的MessageBox究竟需要什么,其实需要的就是尽可能模仿系统自带的消息框,最好就是完全取代之。

    必须能够自定义按钮的数目,给出不同的提示图标(错误,询问,信息等),最好还能发出相应的系统声音,消息框消失后获取按钮的某种枚举值,必须能够为其指定一个父窗体(作为此上的模式窗体),必须能够安全的在非UI线程下使用。大概就是这些吧。

    自定义按钮的数目
    按钮的数目会影响它们在窗体上的位置布局,于是需要知道单个按钮的宽度,相邻2个按钮之间的位置差。
    在源代码中我提供了这样一个枚举:

     

    public   enum  MsgBoxButtons
    {
        
    /// <summary>
        
    /// OK按钮
        
    /// </summary>

        OK = 0,
        
    /// <summary>
        
    /// OK按钮以及Cancel按钮
        
    /// </summary>

        OKCancel,
        
    /// <summary>
        
    /// OK按钮, No按钮, 以及Cancel按钮
        
    /// </summary>

        OKNoCancel,
    }

     

    因为我发现大多数情况下,这样的按钮组合足够应付需要了。

    我发现我无法获取系统默认的按钮的大小,于是我作了个假设:

     

    const   int  DefBtnWidth  =   75 ;   //  TODO -- this may not be right
    const   int  GapTwoBtns  =   150 ;
    const   int  GapTriBtns  =   100 ;


    以上同时包含了按钮之间的间距值。

    自定义错误提示图标
    目的是一眼看出来发生了什么:错误?提示性信息?询问选择?
    为此我拖了一个imageList组件,嵌入了一组图标,并定义了如下枚举:

     

     

    public   enum  MsgBoxIcons
    {
        
    // NOTE: notice the order, corresponds to their images' order

        
    /// <summary>
        
    /// 成功标志
        
    /// </summary>

        Good = 0,
        
    /// <summary>
        
    /// 错误标志
        
    /// </summary>

        Error,
        
    /// <summary>
        
    /// 提示性标志
        
    /// </summary>

        Info,
        
    /// <summary>
        
    /// 询问标志
        
    /// </summary>

        Question,
        
    /// <summary>
        
    /// 不要出现任何标志
        
    /// </summary>

        None,
    }



    需要注意的是:这些枚举值与我的

    imageList中的image的顺序是一一对应的,如果你要添加你自己的图标,你就应该保持这种对应关系。

     

    弹出窗体的时候发出声音

    这个功能完全是模仿来的,看代码吧

     

     

    internal   static   void  DoBeep(MsgBoxIcons icon)
    {
        
    // Play the associated SystemSound
        switch (icon)
        
    {
            
    case MsgBoxIcons.Error:
                SystemSounds.Hand.Play();
                
    break;
            
    case MsgBoxIcons.Good:
            
    case MsgBoxIcons.Info:
                SystemSounds.Asterisk.Play();
                
    break;
            
    case MsgBoxIcons.Question:
                SystemSounds.Question.Play();
                
    break;
            
    default:
                SystemSounds.Beep.Play();
                
    break;
        }

    }

     

    获取窗体关闭时的DialogResult

    这个值很重要,它将反馈给调用者,以辅助其作出某种相应的决策。在这里我直接使用了系统框架类中的DialogResult枚举,在窗体中写死了每个按钮的DialogResult值。

     

    为之提供父窗体参数

    这个本身很简单,任何窗体的ShowDialog都有一个owner参数,我也提供就行了。可是你将会发现,如果你身处该父窗体所在的UI线程中,这样调用没有任何的不适,你甚至不需要为之提供owner参数,缺省的是将当前窗体作为父窗体。一切都运行良好;但是在非UI线程中,你就不能这么做了。看下文。

     

    UI线程中使用它

    假定我们已经提供了ShowDialog方法,事实上我提供了该方法的很多重载版本,其易用性比系统自带的还好。在非UI线程中使用它时,你有2个选择:为之提供owner参数或者不提供;如果不提供,它就无法和你的UI主窗体联系起来,它不会挡在任何窗体的前面,成为其之上的模式窗体,这让人感觉很不爽,我发现尤其要解决这一点;那就提供这个参数就可以了嘛,把主窗体的Handle给它不就完了嘛,哈,这样一来,你的程序只能偶尔的工作。大家应该都知道,这就是跨线程访问控件的问题,原来问题在于,如果需要在A窗体上显示一个模式窗体b,这个任务必须委托给A窗体UI线程执行才行!请注意这句话,我花了很长时间才明确这一点!

     

    ok,你明白了,你需要一个委托来做这件事情,很好,你在A窗体的非UI线程的代码中定义一个委托对象,使用某个方法(b窗体的ShowDialog方法)将其实例化,然后通过FormA.Invoke()来委托给AUI线程来执行。

     

    没错,这就是标准的解决方案,大家一直都是这样做的,.NETMSDN就告诉并建议我们这样做。可是我们需要的消息框是一个独立的组件,你难道要求每个使用该组件的程序都去提供一个委托来在非UI线程中显示这样一个消息框吗?很麻烦不是吗?我就希望在任何线程中,我给你一个Handle,你给我挡在这个Handle的窗体前面显示就行了。于是这个问题成为这个小项目的难点。

     

    你的亮点在哪里?

     

    这是本文最重要的一个部分。我花了很长时间领悟到,我希望你只需要不到1分钟就能理解并记住。

    上面说了,.NET的这种跨线程调用机制要求我们必须使用委托来实现:如果需要在A窗体上显示一个模式窗体b,那么请将该任务委托给AUI线程来执行!

    委托对象放在调用者方会带来额外的编码,于是我把它放进了我自己的组件里,也就是这个自定义的消息框中!

     

    //  跨线程使用之必须
    private   delegate  DialogResult ShowItDelegate(Form owner);
    private   static  DialogResult ShowIt(Form owner, MsgBox mbx)
    {
        
    if (owner != null
            
    && owner.InvokeRequired)
        
    {
            ShowItDelegate d 
    = new ShowItDelegate(mbx.ShowDialog);
            
    return (DialogResult)owner.Invoke(d, owner);
        }


        
    return mbx.ShowDialog(owner);
    }

     

     

    难道就是这些吗?

     

    这样看起来,你的消息框确实比系统的要强,可以在非UI线程下方便的使用;但也就是一个很基本的消息框,那些Hook示例所展示的似乎比你的还要吸引人。

     

    没错,以上Hook示例中展示了很多很有用的技术:添加comboBox,让窗体在一段时间没有被点击后自动消失(同时返回某个默认的DialogResult值),可以替换按钮上的文本字体。

     

    可是这一切对于一个完全由你自己开发的窗体程序而言,是个难题么?太简单了,当然我把一些东西做死了,其实如果你想获得高度自定义的功能,你为自己的Show方法提供一个MsgBoxOptions参数就可以了,源代码在你自己手里,没有什么是不能做的!

     

    当然这取决于你的需要了,就我而言,这已经非常足够了,我一直在用我自己编写的消息框,太方便了!赞一个自己先 :-) 

    后记

    最初我使用的是Singleton模式,可是在很多地方可能先后都要求弹出一个窗体,而先前的这个窗体尚未消失,这就带来了一个问题,.NET抛出了这样一个异常:已经显示的模式窗体不能够再次被显示(大意如此)。经过自己观察,我发现系统自带的消息框类似于每次需要时创建,然后丢弃之,也就是说每个使用的地方都是一个新的消息框。于是就演化成了现在的这样一个版本。

     

    谢谢各位大虾和菜鸟的阅读,祝您使用愉快!

     

    (全文完,页面上会提供源码包下载)


    <script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script>
    展开全文
  • 对于ORM,我也是从最初的ORM工具开始接触到这块,想当初刚接触的时候用到的是DevExpress的商业化ORM组件XPO。这个项目当中让我觉得很爽的一点就是不用想怎么去拼那种复杂的SQL语句,对于复杂的查询,你要的就是搞...

    近来园子里对ORM的讨论又有升级的趋势,我也来凑个热闹。自知自己水平有限,说的不对的地方还请各位大虾指教。

    对于ORM,我也是从最初的ORM工具开始接触到这块,想当初刚接触的时候用到的是DevExpress的商业化ORM组件XPO。这个项目当中让我觉得很爽的一点就是不用想怎么去拼那种复杂的SQL语句,对于复杂的查询,你要做的就是搞明白他们之间的代数逻辑关系。另外对于这个商业化的组件他还提供了对数据绑定的一个支持,并且根据反射机制以及ConnectionString的配置自动为你建立数据库和表,极大地提高了开发的效率。就这样,我便坚定的站在了支持ORM的一边。

    对ORM接触了一段时间之后很自然就会知道在Java界大名鼎鼎的Hibernate,所以很自然的也就了解了.NET下有从他那里进行移植的一个兄弟:NHibernate。鉴于之前使用ORM的经验,我便在接手的一个研究性的项目中采用了NHibernate。但由于经验所限,实际上我们是使用由R到O的一个设计方法在使用ORM,结果正如大多数反对ORM的人一样,程序运行异常缓慢,对象之间的关系也异常复杂,很多业务层有效性的约束由于NHibernate的机制和数据库原理的冲突而不得不作出折衷方案,并且经常会引发各种异常。后来干脆直接就不采用ORM了,使用MS的EntLib来写DAL。

    其实要使用ORM,首先我们要来看看为什么会有ORM?我们现在都强调使用面向对象的方式来进行编程,那么在程序进行逻辑处理的时候,对象是保存在内存中的。但是由于操作系统所支持的内存容量有限,所以我们需要把那些已经完成逻辑运算的对象保存到另外一个地方,等我们再次使用的时候再去取。这里所谓的另外一个地方其实就是我们的关系数据库。但是对象是一个多维结构,而数据库只是一系列二维表的集合,所以这里就有一个问题:怎么在这两者之间建立映射,并且不会造成信息的丢失呢?ORM的出现其实就是为我们解决这个问题。

    说到这里我们再来看,如果我们在做设计的时候是先设计数据库表,然后使用ORM工具进行对象的映射(或者是先写类的属性,然后再映射到数据库,其实这两者都是一样),那么你真正做业务逻辑,需要持久化保存的时候,就不得不去考虑数据库的表结构以及他们之间的关系影响,甚至需要构造复杂的事务。就算这道关被咬牙坚持了下来,但由于数据库表结构的固定,必然会造成大量DTO在业务逻辑中的传递,很自然就出现了性能问题。

    所以最后很自然,先有对象再映射到数据库才是使用ORM的正途。任何东西都有自己的生命周期,对象也是。从一个对象的生命周期,即对象被创建或者被从数据库中取到内存中,进行完复杂的业务逻辑运算,到最后消亡,这之中需要ORM的就是取对象到内存以及消亡之前的持久两个阶段。所以关于ORM性能的判断就决定于这个地方:我们知道一个对象通常会有关联和聚合,缺少了任何一个都会造成对象信息的不完整,所以ORM在构造SQL的时候必须要把这个对象的关联和聚合都要表示出来,而有些时候业务逻辑根本就不关心它的关联和聚合,于是大多数ORM组件都提供了一个LazyLoad的机制来提高性能。但是这一点也是ORM的反对者们所吹捧的一个性能杀手。那么究竟是怎样的一个情况,我没有自己实验过,不敢妄下结论。但从我阅读过的资料上来看,ORM加缓存并不比传统方法慢,有时候甚至要快上几倍。

    这样肯定有人会问:如果我的需求改变,那么我的对象模型改变了,数据库岂不是也变了?咋一看确实没错,但是值得注意的是面向对象的设计原则中有一条所谓的开闭原则:类的设计要对扩展开放,对更改关闭。所以一个设计的符合面向对象5原则的模型应该是可以做到不用去修改已有系统的代码而满足变更的需求。这样一来,我们不过是需要在原有的数据库基础上新增几个表而已。

    所以我个人对ORM的理解是只要你建立了对象模型,并采用关系数据库作为你的持久存储器,那么你就需要ORM,而不管你是用已有的组件还是自己实现。从这个层面上来说,什么该用ORM还是不该用ORM根本就是一个设计问题。如果从模型开始,不用也得用;如果是从数据库表设计开始,用也是没用。

    参考资料:
    1. 当前java项目开发中的几个误区
    2. Why OO+多层结构?

    转载于:https://www.cnblogs.com/gamix/archive/2007/01/06/613657.html

    展开全文
  • 最初产生这样一个需求是源于项目经理近乎白痴般要求,有一天,他告诉我说那个弹出来消息框太小了。我告诉他,这是系统自带东西,大小随着给定文本内容长度自动变化,他说不行,给弄大点,而且字体也太小,...

     

    摘要
    1.是什么导致我们需要提供一个自定义的消息框?
    2.说说我的大致思路
    3.你的亮点在哪里?
    4.难道就是这些吗?

    下载本文讲述的项目源码包

    是什么导致我们需要提供一个自定义的消息框?

    最初产生这样一个需求是源于项目经理的近乎白痴般的要求,有一天,他告诉我说那个弹出来的消息框太小了。我告诉他,这是系统自带的东西,大小随着给定文本内容的长度自动变化,他说不行,给弄大点,而且字体也太小,换个字体吧!我的天,难道架构师都是从来不真实写代码的吗?

    接 到这个要求,想想也许不大难吧。先看看系统给了我什么接口:MessageBox位于System.Windows.Forms命名空间内,是一个被密封了的静态类,能够使用的公共方法也就是MessageBox.Show,倒是有很多重载版本,也有一个选项参数,但该参数却没提供我真正感兴趣的东西。

    碰 到问题我还是老规矩,首先请教Google,然后直接上codeproject或sourceforge查找,一般的问题都可以解决。一看,原来大家都曾 有过这样的需求啊;再来看别人的解决方法。大部分人使用Hook,也就是系统消息拦截,获取消息框的句柄,然后使用winApi篡改该窗体的某些特征;这样的示例非常多,而且有着非常有特色的特征:可以在上面添加个comboBox,告诉它Don't show this in the next time;可以赋予按钮自己想要的文本值;也能修改一些文本的字体和字号属性;

    看起来这就是我要的解决方案,因为它几乎能做一切;作为 windows上的新手,我于是迫切需要去弄弄Hook,这东西也不难;可问题在于,我发现无论怎么去尝试修改那些作者使用Hook做的示例,最后的结果仍然是:该消息框上所有使用文本的地方最终都是同一个变化!也就是说你如果把Message Text部分的字体弄成Vadana,按钮上的文本的字体也会变为Vadana,这居然是一体的!

    很好,我正不想弄Hook,这东西我就没弄成功过,别人例子都行,我就是不行!

    也罢,逼急了,我自己来搞一个。


    说说我的大致思路

    .NET下画个窗体不难,事实上拖下鼠标就行了;问题在于一样东西总是牵扯到其它的很多东西。
    ok,看看我自己的MessageBox究竟需要什么,其实需要的就是尽可能模仿系统自带的消息框,最好就是完全取代之。

    必须能够自定义按钮的数目,给出不同的提示图标(错误,询问,信息等),最好还能发出相应的系统声音,消息框消失后获取按钮的某种枚举值,必须能够为其指定一个父窗体(作为此上的模式窗体),必须能够安全的在非UI线程下使用。大概就是这些吧。

    自定义按钮的数目
    按钮的数目会影响它们在窗体上的位置布局,于是需要知道单个按钮的宽度,相邻2个按钮之间的位置差。
    在源代码中我提供了这样一个枚举:

     

    None.gifpublic enum MsgBoxButtons
    ExpandedBlockStart.gifContractedBlock.gif
    dot.gif{
    ExpandedSubBlockStart.gifContractedSubBlock.gif    
    /**//// <summary>
    InBlock.gif    
    /// OK按钮
    ExpandedSubBlockEnd.gif    
    /// </summary>

    InBlock.gif    OK = 0,
    ExpandedSubBlockStart.gifContractedSubBlock.gif    
    /**//// <summary>
    InBlock.gif    
    /// OK按钮以及Cancel按钮
    ExpandedSubBlockEnd.gif    
    /// </summary>

    InBlock.gif    OKCancel,
    ExpandedSubBlockStart.gifContractedSubBlock.gif    
    /**//// <summary>
    InBlock.gif    
    /// OK按钮, No按钮, 以及Cancel按钮
    ExpandedSubBlockEnd.gif    
    /// </summary>

    InBlock.gif    OKNoCancel,
    ExpandedBlockEnd.gif}

     

    因为我发现大多数情况下,这样的按钮组合足够应付需要了。

    我发现我无法获取系统默认的按钮的大小,于是我作了个假设:

     

    None.gifconst int DefBtnWidth = 75;  // TODO -- this may not be right
    None.gif
    const int GapTwoBtns = 150;
    None.gif
    const int GapTriBtns = 100;


    以上同时包含了按钮之间的间距值。

    自定义错误提示图标
    目的是一眼看出来发生了什么:错误?提示性信息?询问选择?
    为此我拖了一个imageList组件,嵌入了一组图标,并定义了如下枚举:

     

    None.gifpublic enum MsgBoxIcons
    ExpandedBlockStart.gifContractedBlock.gif
    dot.gif{
    InBlock.gif    
    // NOTE: notice the order, corresponds to their images' order
    InBlock.gif

    ExpandedSubBlockStart.gifContractedSubBlock.gif    
    /**//// <summary>
    InBlock.gif    
    /// 成功标志
    ExpandedSubBlockEnd.gif    
    /// </summary>

    InBlock.gif    Good = 0,
    ExpandedSubBlockStart.gifContractedSubBlock.gif    
    /**//// <summary>
    InBlock.gif    
    /// 错误标志
    ExpandedSubBlockEnd.gif    
    /// </summary>

    InBlock.gif    Error,
    ExpandedSubBlockStart.gifContractedSubBlock.gif    
    /**//// <summary>
    InBlock.gif    
    /// 提示性标志
    ExpandedSubBlockEnd.gif    
    /// </summary>

    InBlock.gif    Info,
    ExpandedSubBlockStart.gifContractedSubBlock.gif    
    /**//// <summary>
    InBlock.gif    
    /// 询问标志
    ExpandedSubBlockEnd.gif    
    /// </summary>

    InBlock.gif    Question,
    ExpandedSubBlockStart.gifContractedSubBlock.gif    
    /**//// <summary>
    InBlock.gif    
    /// 不要出现任何标志
    ExpandedSubBlockEnd.gif    
    /// </summary>

    InBlock.gif    None,
    ExpandedBlockEnd.gif}

    None.gif



    需要注意的是:这些枚举值与我的

    imageList中的image的顺序是一一对应的,如果你要添加你自己的图标,你就应该保持这种对应关系。

     

    弹出窗体的时候发出声音

    这个功能完全是模仿来的,看代码吧

     

    None.gifinternal static void DoBeep(MsgBoxIcons icon)
    ExpandedBlockStart.gifContractedBlock.gif
    dot.gif{
    InBlock.gif    
    // Play the associated SystemSound
    InBlock.gif
        switch (icon)
    ExpandedSubBlockStart.gifContractedSubBlock.gif    
    dot.gif{
    InBlock.gif        
    case MsgBoxIcons.Error:
    InBlock.gif            SystemSounds.Hand.Play();
    InBlock.gif            
    break;
    InBlock.gif        
    case MsgBoxIcons.Good:
    InBlock.gif        
    case MsgBoxIcons.Info:
    InBlock.gif            SystemSounds.Asterisk.Play();
    InBlock.gif            
    break;
    InBlock.gif        
    case MsgBoxIcons.Question:
    InBlock.gif            SystemSounds.Question.Play();
    InBlock.gif            
    break;
    InBlock.gif        
    default:
    InBlock.gif            SystemSounds.Beep.Play();
    InBlock.gif            
    break;
    ExpandedSubBlockEnd.gif    }

    ExpandedBlockEnd.gif}

    None.gif

     

    获取窗体关闭时的DialogResult

    这个值很重要,它将反馈给调用者,以辅助其作出某种相应的决策。在这里我直接使用了系统框架类中的DialogResult枚举,在窗体中写死了每个按钮的DialogResult值。

     

    为之提供父窗体参数

    这个本身很简单,任何窗体的ShowDialog都有一个owner参数,我也提供就行了。可是你将会发现,如果你身处该父窗体所在的UI线程中,这样调用没有任何的不适,你甚至不需要为之提供owner参数,缺省的是将当前窗体作为父窗体。一切都运行良好;但是在非UI线程中,你就不能这么做了。看下文。

     

    UI线程中使用它

    假定我们已经提供了ShowDialog方法,事实上我提供了该方法的很多重载版本,其易用性比系统自带的还好。在非UI线程中使用它时,你有2个选择:为之提供owner参数或者不提供;如果不提供,它就无法和你的UI主窗体联系起来,它不会挡在任何窗体的前面,成为其之上的模式窗体,这让人感觉很不爽,我发现尤其要解决这一点;那就提供这个参数就可以了嘛,把主窗体的Handle给它不就完了嘛,哈,这样一来,你的程序只能偶尔的工作。大家应该都知道,这就是跨线程访问控件的问题,原来问题在于,如果需要在A窗体上显示一个模式窗体b,这个任务必须委托给A窗体UI线程执行才行!请注意这句话,我花了很长时间才明确这一点!

     

    ok,你明白了,你需要一个委托来做这件事情,很好,你在A窗体的非UI线程的代码中定义一个委托对象,使用某个方法(b窗体的ShowDialog方法)将其实例化,然后通过FormA.Invoke()来委托给AUI线程来执行。

     

    没错,这就是标准的解决方案,大家一直都是这样做的,.NETMSDN就告诉并建议我们这样做。可是我们需要的消息框是一个独立的组件,你难道要求每个使用该组件的程序都去提供一个委托来在非UI线程中显示这样一个消息框吗?很麻烦不是吗?我就希望在任何线程中,我给你一个Handle,你给我挡在这个Handle的窗体前面显示就行了。于是这个问题成为这个小项目的难点。

     

    你的亮点在哪里?

     

    这是本文最重要的一个部分。我花了很长时间领悟到,我希望你只需要不到1分钟就能理解并记住。

    上面说了,.NET的这种跨线程调用机制要求我们必须使用委托来实现:如果需要在A窗体上显示一个模式窗体b,那么请将该任务委托给AUI线程来执行!

    委托对象放在调用者方会带来额外的编码,于是我把它放进了我自己的组件里,也就是这个自定义的消息框中!

     

    None.gif// 跨线程使用之必须
    None.gif
    private delegate DialogResult ShowItDelegate(Form owner);
    None.gif
    private static DialogResult ShowIt(Form owner, MsgBox mbx)
    ExpandedBlockStart.gifContractedBlock.gif
    dot.gif{
    InBlock.gif    
    if (owner != null
    InBlock.gif        
    && owner.InvokeRequired)
    ExpandedSubBlockStart.gifContractedSubBlock.gif    
    dot.gif{
    InBlock.gif        ShowItDelegate d 
    = new ShowItDelegate(mbx.ShowDialog);
    InBlock.gif        
    return (DialogResult)owner.Invoke(d, owner);
    ExpandedSubBlockEnd.gif    }

    InBlock.gif
    InBlock.gif    
    return mbx.ShowDialog(owner);
    ExpandedBlockEnd.gif}

    None.gif

     

     

    难道就是这些吗?

     

    这样看起来,你的消息框确实比系统的要强,可以在非UI线程下方便的使用;但也就是一个很基本的消息框,那些Hook示例所展示的似乎比你的还要吸引人。

     

    没错,以上Hook示例中展示了很多很有用的技术:添加comboBox,让窗体在一段时间没有被点击后自动消失(同时返回某个默认的DialogResult值),可以替换按钮上的文本字体。

     

    可是这一切对于一个完全由你自己开发的窗体程序而言,是个难题么?太简单了,当然我把一些东西做死了,其实如果你想获得高度自定义的功能,你为自己的Show方法提供一个MsgBoxOptions参数就可以了,源代码在你自己手里,没有什么是不能做的!

     

    当然这取决于你的需要了,就我而言,这已经非常足够了,我一直在用我自己编写的消息框,太方便了!赞一个自己先 :-) 

    后记

    最初我使用的是Singleton模式,可是在很多地方可能先后都要求弹出一个窗体,而先前的这个窗体尚未消失,这就带来了一个问题,.NET抛出了这样一个异常:已经显示的模式窗体不能够再次被显示(大意如此)。经过自己观察,我发现系统自带的消息框类似于每次需要时创建,然后丢弃之,也就是说每个使用的地方都是一个新的消息框。于是就演化成了现在的这样一个版本。

     

    谢谢各位大虾和菜鸟的阅读,祝您使用愉快!

     

    (全文完,页面上会提供源码包下载)

    转载于:https://www.cnblogs.com/Peter-Yung/archive/2007/03/16/677786.html

    展开全文
  • 说说游戏服务器

    千次阅读 2010-06-23 10:17:00
    注:此帖来源于CSDN游戏开发论坛,作者是gantleman,非常感谢他无私的分享了自己的开发经验。以下是他的技术博客,欢迎大家支持:...说到网游服务器是最近火起来的,但最初的网游服务器几
  • linux下nginx配置(静态服务)

    千次阅读 2018-10-17 11:59:20
    nginx配置较为复杂,基本很好理解,也好学习,但是很多是要靠摸索来总结经验,接下来,拿券君就来说说自己的经验,希望能对正在阅读你有一定帮助。   nginx虽然只有小小几MB,但是功能超级强大,比如 ...
  • 所以,我们坚守着最初的誓言,每次在持久层技术选型的时候,我们总是选择最原始的JDBC,快乐的coding。直到有一天,Java界的武林盟主-Spring,为了进一步巩固自己在Java开发领域的地位,无情的抢走了它,随即对它...
  • 经历了最初项目采用node 0.10.x 版本(callback hell问题)升级到4.x(比较短暂一个新项目,最终没继续)升级到6.x(使用co + yield来解决回调问题)最近终于升级到10.x(可以采用原生async + await了)先说说优点:第...
  • 题图:from Behance by Maurice Heesen新年给自己一个年度目标是上线一个个人产品,所以最近就把几年来收集想法进行整理发散。第一个想做的东西是回忆相册,姑且这么叫吧。最初想实现功能是【在今天提醒...
  • 产品一点思考

    2017-11-23 19:47:55
    这几个月在公司产品中实现了一个自己的模块,下面就是说说这个模块给我感悟 好产品必定是大量心力投入 以前玩app,用别人软件,没有感觉到要做出一款好应用有多难,注意力都集中在使用上了。对于别人为...
  • 为什么要写这篇文章呢?因为公司在使用Dubbo时并没有对Dubbo用法深入了解,而是属于拿来就用,随着自己的想法来使用。这样很不好,就像天龙八部鸠摩智练习错误六脉...先说说最初使用时做法: 由于Provide
  • 15号开始系统.30号正式完....最初的想法是利用存储过程实现.首先连接数据库,查询,返回. 由于刚开始使用vb.net开发环境.有点陌生,再加上对数据库操作的不熟悉.让自己很是恼火.一遍,无法实现.再一遍,还是
  • 华为——我面试之路

    千次阅读 2009-11-27 00:24:00
    在我的前几天的博客《人生最难得是选择》里,我谈到了我由于一个很偶然的机会选择了华为而放弃了出国,现在可以好好地说说这件事儿了。在这里我先把面试华为的过程...大家请不要小看这份最初的“简历”,如果你的好,
  • 嵌入式软件之定时器设计

    千次阅读 2014-01-03 14:21:12
    这是真正意义上第一篇自己博客,以前...一说到定时器,估计很多人都第一个想到是用alarm来,这个是没问题,我最初所用方法也是用是alarm,但是由于项目要求是在一个进程内控制多个设备定时开关机(我
  • 在这个公司,从项目建设上讲,老实说贡献不是很大,项目经理团队带不好,当然小创业公司本身资源真非常有限,自己也特别累,有老板压力,也有团队成员压力,虽然如此,纵然如此,我还是要说说我对公司...
  • 先来说说背景吧,最初想要在公司核心路由器上添加静态路由规则,通过IP地址段来判定网络出口,本来公司人就不多,当初就让熟人一个套TP-Link方案,核心路由用是TP-R4239G 小型企业路由器,管理界面都是tplink...
  • 作品展(五)

    2012-05-06 13:35:00
    最初的想法是英语软件,因为提高班的学习内容包括软件更包括英语,况且,我是ShortBrain英语学习的先行者,何不将我学到的计算机知识应用到英语软件开发上,从自身的需求出发做出的软件一定更适合自己;...
  • sort-list

    2017-01-12 17:53:39
    说说自己做的过程中的几个错误吧。 1忽略了空链表的情况。 2两个链表进行并归排序的时候,应该拿函数返回的头结点,而不是划分的头结点,因为在递归的过程中,最初的头结点可能因为排序而后移了。 3快慢指针的...

空空如也

空空如也

1 2 3
收藏数 42
精华内容 16
关键字:

做最初的自己说说