zoukankan      html  css  js  c++  java
  • 跟我学做c#皮肤美化(四)

    源码下载


    做了许多的用户控件,现在让我们换换口味,开始窗体的制作吧!这个窗体的制作可以说是整个美化中比较重要的一部分,因为她显示的是整个美化的窗体。而且内容也比较多,所以我会分几篇把她讲完,而且窗体制作的时候会和前面控件将的时候不一样,我不会在第一篇把最后的代码就放出来,而是希望做成跟着我一起一个版本一版本的完成不断的修改不断的发现问题并去完善。这也是我做这个时候的一个思路:先做一个大致的框架,然后在其基础上增加功能或者发现问题,最后完成功能和解决问题。不知道大家感觉这样是不是更好一点呢? 

    好了,不多说了,先看最终的效果图: 


     

    怎么样?是不是有点心动了?下面就正式开始吧! 

    首先在以前的项目QLFUI上新建一个窗体(不是用户控件咯)并重新命名为MainForm


    如图: 


     

     

    接着来设置几个属性,如下:

    FormBorderStyle:None

    Size:300,300

    接下来就是用picturebox 和 panel来布局了。这一部分可能比较繁琐首先总体介绍一下大概的布局。见图:


     

    因为我们做的窗体是圆角的,所以窗体的四个角上(红色)我们会放上四个picturebox。标题栏和状态栏(蓝色)会是两个panel。二个边框线(绿色)是两个picturebox。最后的主体部分(棕色)是一个panel。说完了大体的布局,下面就来动手做啦。一个一个来:

    左上角

    Name:ptbtl

    Location:0,0

    Size:10,31

    上方的标题栏

    Modifiers:Protected;

    Name:panelt

    Location:10,0

    Size:280,31

    右上角

    Name:ptbtr

    Location:290,0

    Size:10,31

    左侧的边框线

    Name:ptbml

    Location:0,31

    Size:2,232

    主窗体部分

    Modifiers:Protected;

    BackgroundImageLayout:Stretch

    Name:panelm

    Location:2,31

    Size:296,232

    右侧的边框线

    Name:ptbmr

    Location:298,31

    Size:2,232

    左下角

    Name:ptbbl

    Location:0,263

    Size:10,37

    下方的状态栏

    Modifiers:Protected;

    Name:panelb

    Location:10,263

    Size:280,37

    右下角

    Name:ptbbr

    Location:290,263

    Size:10,37

    最后还有右上方的三个按钮可不要忘记了,注意按钮都是在panelt里面设置的而且这三个按钮都是我们前面做的按钮哦,终于派上用场啦!

    最小化按钮

    Caption:0

    Name:btmin

    Location:180,0

    Size:31,22

    最大化按钮

    Caption:0

    Name:btmax

    Location:211,0

    Size:31,22

    关闭按钮

    Caption:0

    Name:btclose

    Location:243,0

    Size:37,22

    还原按钮

    Caption:0

    Name:btres

    Location:211,-30

    Size:31,22

     

    最后再加上一个label作为窗体的标题

    Name:lbtitle

    Location:6,9

    Size:35,12

    BackColor:Transparent

    呼,终于结束了!不知道大家有没有晕乎乎的感觉,反正我是有点儿了,呵呵。最后的布局图应该是这个样子滴:


     

    老规矩,界面的事情弄完了,现在开始编码了。上代码:

     

    【代码】(代码不短,大家还是看我附件里面的代码,看的也清楚点儿!)


     

    变量部分:

    变量我在代码里都注明了其作用。这里只会说说为什么要这些变量。首先needMaxbt和needMinbt是指示该窗体是否需要最大化或最小化按钮的,毕竟窗体有很多种吧,比如说一个消息框就没必要用最大化按钮吧,所以我们这边也就设置的灵活一点,下面会将这两个变量封装成属性以便在设计模式下方便的选择。

    接下来的四个变量

    orginWidth;

    orginHeight;

    X;

    Y;

    都是用来记录窗体的信息的,分别是窗体的宽,高,x坐标值,y坐标值。为什么要设置一些变量呢?说起来也比较郁闷,这些都是为了窗口的最大化和还原准备的。可能有人会问了最大化不就一句话嘛
    this.WindowState= FormWindowState.Maximized;何必还要这些个变量呢。关键郁闷就郁闷在这里啦,假如直接用这一句话最后窗体虽然也能最大化可就是右上角的一小段边框线莫名其妙的没有了,如图:


     

    搞了半天也不明白。最后不得已才想出个自己手动最大化的方法来,讲到具体的地方再和大家说吧。

    接下来我又定义了一个枚举stat,用来表示窗体的三种状态,正常,最大化,最小化。下面的那个st就是枚举的一个变量,默认的是normal也就是窗体正常显示啦。

    变量讲完了接下来讲属性。


    第一个属性Size。这个属性有点特别,因为它里面有一个new关键字,为什么呢?因为Size这个属性在设计器里面原来就有了所以我们加上这个new就相当于重写这个属性啦。这个属性里面我只写了一个get方法。我写这个属性的目的就是要将设计器下原来的size属性隐藏(看见了上面的那个[Browsable(false)]吗?就是用它来隐藏的),这样别人如果要设置窗体的大小就得修改我们下面提到的BorderWidth和BorderHeight了。那为什么要隐藏原来的实现呢,这是因为当我们设置窗体大小的时候窗体上相应的picturebox和panel也需要相应的改变,这里面就需要设置很多的东西。所以我们另外设置属性来完成这些工作。


     

    第二个属性BorderWidth。毫无疑问,这个就是用来设置窗体的宽度的啦。[CategoryAttribute("QLFSkinDll"), Description("设置窗体宽度")]我就不讲了,前面已经提到过了。里面的get也很简单就是返回当前窗口的宽度。重点讲解set。首先我们用if语句限制了用户设置的值不能小于180像素,因为当小于180个像素的时候,界面上的最小化按钮就有将标题都“挤”没了。所以最小180啦。接下来如果用户设置的值和设置前的不一样,那么就开始一下一连串的设置了。我们用newwidth把用户设置的这个值记录下来,下面要用到。然后紧接着就改变窗体的大小。

    如果仅仅这样就结束了你会发现panel,picturebox那些控件的位置都没有动,这不是我们想要的。接下来就是设置这些控件的位置啦。一开始我做的时候也被这些设置搞乱了,最后我用的相对位置才搞清楚的。什么叫相对位置,打比方说无论你窗体的大小怎么变化,关闭按钮总是在距窗体右侧57个像素的位置。按照这个一句来做我们也会发现其他的控件都是一样的。于是一个一个的设置,找相对距离。当然我现在已经找好了,大家就不必再麻烦一个一个找一遍来了。至此,BorderWidth属性讲完。


    第三个属性BorderHeight经过上面BorderWidth属性的讲解,我想height属性就不要我再讲解了,都是一样的道理。


    第四个属性FormTitle看意思就应该看出来了吧,这个是用来设置窗体的标题的。这个在前面讲到的button,checkbox等控件里也有差不多的属性,这里也不就不罗嗦了。


    第五个属性NeedMax这个属性是用来指定窗体是否需要最大化按钮的。怎么指定呢?看代码。如果用户设置的是false也就是不需要,那我们就会将btmax按钮向上移动50个像素(this.btmax.Top = -50;)同时btmin按钮顶替最大化按钮的位置(this.btmin.Left = this.Width - 89;),怎么样?是不是很简单就实现了按钮的隐藏呢?


    第六个属性NeedMin用法参见上面的第五个属性。


    接下来讲构造函数。

    前四句就不要我讲了吧,前面也遇到过就是开启双缓冲和系统默认的是初始化控件。剩下的N多的语句都是用来加载图片的,其实也没啥好说的要说的点前面控件制作的时候也已经介绍过了,呵呵。。。说一下最后一句的意思吧。因为我们的窗体默认是没有状态栏什么的,所以也就决定了当窗体最小化后右击任务栏上的窗体没有菜单弹出来。如果要实现这个功能就需要借助系统API来完成了。不过在c#里面是不可以直接调用API的,需要实现声明一下。在这里就偷懒一下直接将别人封装好的API类(win32.cs)。一句话完成这个功能:

    Win32.SetWindowLong(this.Handle, -16, Win32.WS_SYSMENU+ Win32.WS_MINIMIZEBOX);好了,来运行看看吧:

     


    发现问题:

    大体的模样是出现了。不过也许大家看图看不清楚,图中被我画圈的其实都不是透明的,而是灰色的。我们在下一篇文章的讲解中将解决或实现以下几个问题:

    1.消除图中不透明的地方

    2.实现标题栏的拖动

    3.实现窗体的最大化,最小化,关闭功能。


    敬请期待。。。

  • 相关阅读:
    ASP.NET在禁用视图状态的情况下仍然使用ViewState对象【转】
    Atcoder Regular Contest 061 D Card Game for Three(组合数学)
    Solution 「CERC 2016」「洛谷 P3684」机棚障碍
    Solution 「CF 599E」Sandy and Nuts
    Solution 「洛谷 P6021」洪水
    Solution 「ARC 058C」「AT 1975」Iroha and Haiku
    Solution 「POI 2011」「洛谷 P3527」METMeteors
    Solution 「CF 1023F」Mobile Phone Network
    Solution 「SP 6779」GSS7
    Solution 「LOCAL」大括号树
  • 原文地址:https://www.cnblogs.com/jcomet/p/1719173.html
Copyright © 2011-2022 走看看