技巧1,合理使用控件的Tag属性几乎所有winform控件有都名为object类型的Tag属性,此属性多数情况下用来承载完整的数据源,相当于WEBFORM页面中hidden控件的作用,举个简单的例子
textBox1.Text=info.UserName;
上述代码非常简单,将实体的属性赋值给一个文本框,而此实体还有其它属性,文本框无法显示那么多了,不过一会儿其它地方还需要使用实体的其它对象,那此时就可以把该实体直接赋给文本框的Tag属性,类型为object,代码如下:
textBox1.Text = info.UserName;textBox1.Tag = info;
这样再次使用实体的时候就可以从控件的Tag属性中取了,如
PersonEntity info = textBox1.Tag as PersonEntity;
当然了,也完全可以把info设计为属性,但有时候这样做可能要添加很多这样的属性,此时就是Tag的用武之地了
 技巧2,模态窗口使用DialogResult关闭窗口如下应用场景,需要弹出一个窗口来,其中需要客户输入处理一些数据后返回,代码如下FrmConnection frmConnection = new FrmConnection();            if( frmConnection.ShowDialog() == DialogResult.OK                && frmConnection.Info != null ) {                frmDataBase.Info = frmConnection.Info;                InitializeCustomControl( frmDataBase );            }
 在弹出的窗口中,给它自己的DialogResult属性赋值,窗口即会自动关闭,通常情况自己关闭也可以,不过调用了Close或Dispose方法后,弹出的窗口对象会销毁,此时再调用它的其它属性什么的,会报"无法访问已释放的资源"的异常
 技巧3,临时挂起控件更新同技巧1一样,几乎所有的"容器控件"都有SuspendLayout()方法和ResumeLayout()方法,这两个方法是做什么的呢?这两个方法在XXX.Designer.cs代码中最常见,就是设计窗体时VS自动生成的代码里,它是临时挂起控件更新,然后修改控件属性,如添加子控件,改变大小等等操作,全部操作完成后再调用ResumeLayout(false)方法,这样将控件"只更新一次"即可,效率上会提高不了,有点像拼接N个INSERT 语句,然后只连接一次数据库执行全部,而不是连接N次,执行N次,效率自然不咋地了,呵呵! 记录学习中的点点滴滴,一次书写,终生享用,人人为我,我为人人

解决方案 »

  1.   

    1,3常用到,
    在更新listview等控时,也会用到beginupdate()和endupdate(),据说是为了提高效率,有所体会,但是会闪
      

  2.   


    其实还有个简单办法,就是先设置listview的Visiable=false,然后调用SuspendLayout方法,
    再然后调整listview的各个属性,完毕后调用ResumeLayout(false)方法,最后再设置listview的Visiable=true,
    这样的效果是"卡"一下,但不会闪,为了不卡,还可以把上述所有操作放到子线程里操作,这样也不卡也不闪,但是使用多线程会带来其它问题
    如跨线程操作控件UI等问题,会带来更多的编码工作,不是非常看重这个,一般不使用,作为一个思路还行,呵呵
      

  3.   

    1. Tag 不建议过多使用,因为可读性不强,不容易被他人甚至自己理解。使用Tag多在封闭的小环境下使用,应该是极少用。2. 标准的模式窗口设计确实应该使用 DialogResult 来做为结束。这时候窗口是 Hide() 而不是 Close(),Close()或Dispose()应该由外部调用者触发。3. 大量实践证明SuspendLayout()和ResumeLayout()并没有起到多大用处,控件多的时候该卡的还是卡,以前查过很多资料,最终还是没什么结果。楼主你觉得这两个方法效果如何呢?
      

  4.   

    说明一下,模式窗口设计中用 DialogResult 做为结束是一个硬性的设计标准,不能当做是一种技巧。
      

  5.   


    既然Visiable=false就不需要调用SuspendLayout方法了,当Visiable=false时控件显然是不会被重绘,所以这时候调用SuspendLayout是没意义的。
      

  6.   


    怎么说呢,不仅仅上述三个技巧,所有的"实现方法"都有"最适合使用"的场景,在最适合使用某技术的场景中使用就是最好的解决方案,相反就不是了,
    1,在最适合使用它的上下文中使用就非常好,过度使用,强行使用效率不佳,举个适合使用它的场景,如TreeView中的TreeNode的Tag可以设置为实体对象,这要在TreeView的事件e里可以找到Node,继而可以从其Tag中获取到实体对象,对这种方法对应的别一种方法,如写一个Dictionary<string,实体>来保存,在使用的时候根据TreeNode的Name或Text到字典里遍历获取以好得多,您觉得呢?
    2,这个是昨天写代码时"不小心"发现的一个现象,最后一再测试发现其规律,故写出来让更多的人的知道,同时也希望更多的人指出它的适用范围,指出我理解中的不足
    3,我能想到的最佳的方法也就是14楼的回复了
      

  7.   


    这种场景不适合用Tag,代码的可读性太差。最佳做法是重写 TreeNode,扩展你所需要的属性,在TreeView中添加你自己的TreeNode,重写一个TreeNode代码量顶多10多行,换来的好处是非常好的可读性和扩展性。
      

  8.   


    那Tag什么时候适用呢?因为几乎所有WINFORM控件都有Tag属性,使用到的全部重写?显然也不太好~您觉得呢?
      

  9.   


    偷懒的时候用。
    不推荐使用Tag的原因:
    1.可读性不佳,这不用说,一个窗体里面,这个控件的Tag是id,另一个控件的Tag是实体,时间久了,看了会头晕。
    2.扩展性不佳,比如你上面说的TreeNode,放了一个实体在Tag上,以后你又使用到一个值,就没地方放了,这时候你就不得不更改你原来的设计模型了。当然,用Tag很方便了,所以在小地方我还是会用,比较会用在很小的窗体里(代码量20行左右),这种时候使用对可读性基本不造成什么影响。
      

  10.   

        public partial class Form1 : Form
        {
            private DataView dataview;        public Form1()
            {
                InitializeComponent();
            }        private class MyTreeNode : TreeNode
            {
                public int Id { get; set; }
            }
        }三行代码为TreeNode增加一个id,而且声明为private class,保证对其它窗体不产生任何影响。
      

  11.   

    up,学习~~~
    楼主我有个问题,我的一个窗体上有很多控件(二十几个吧),这些控件都是设计的时候拖上去的。在窗体SHOW的时候要很慢才能显示完整个窗体,请问楼主有没有好的办法解决?
      

  12.   

    恩,已经常用TEXT显示文本,TAG保存对应的代码
      

  13.   

    呵呵,亲自实践证明过SuspendLayout()和ResumeLayout()并没有起到多大用处
      

  14.   


    no no 
    第一个疑问:这个完全看个人编程习惯了,如一般情况下Tag都存储完整的实体,而不刻意去部分,目的就是在需要的时候可以获取到整个实体对象,基本不会只放实体的一个属性
    关于第二个疑问:暂时想像不到这样的应用场景,但我相信,即使有这样的应用场景,则必定是其它地方设计的不够科学或合理一般情况下,通常情况下,多数情况下,没特别的要求的话,Tag是用来存储完整数据源的,这似乎也是设计它的初衷,这个可参考Tag的提示说明
    如果某控件只用来显示某实体,那么该控件的Tag最适合放该对象了,而不是乱放,基本原则等同变量的存放,在有使用它的上下文中使用它对"临时挂起的控件更新的小技巧"的批评虚心接受,谢谢~
      

  15.   

    对于2 DialogResult对DialogResult赋值后,仍然应该写Close
    因为对于非模态窗体(.Show出来而不是.ShowDialog出来的),对DialogResult赋值后不会自动关闭窗体,这样存在不一致性。另外,由于给DialogResult赋值后自动Close是在消息回圈中检查的,所以很多情况下,比如系统一直忙,或多线程,甚至在窗体使用了Timer控件时都会有问题
      

  16.   

    学习!做个记号,好东西。赞同TAG存放实体。当然,重写也是一种办法。
      

  17.   

    技巧3,临时挂起控件更新 同技巧1一样,几乎所有的"容器控件"都有SuspendLayout()方法和ResumeLayout()方法,这两个方法是做什么的呢? 这两个方法在XXX.Designer.cs代码中最常见,就是设计窗体时VS自动生成的代码里,它是临时挂起控件更新,然后修改控件属性,如添加子控件,改变大小等等操作,全部操作完成后再调用ResumeLayout(false)方法,这样将控件"只更新一次"即可,效率上会提高不了,有点像拼接N个INSERT 语句,然后只连接一次数据库执行全部,而不是连接N次,执行N次,效率自然不咋地了,呵呵我现在也被这第三个闪动的情况深深困扰,真是烦啊,目前还是没有完美的解决方法。
      

  18.   

    嗯,经常用倒TAG,因为我想不除别的什么好办法传值嘿嘿
      

  19.   

    没怎么做过winform开发,学习下了