你的位置:首页 > 软件开发 > ASP.net > [DForm]我也来做自定义Winform之另类标题栏重绘

[DForm]我也来做自定义Winform之另类标题栏重绘

发布时间:2016-06-21 13:00:04
据说得有楔子 按照惯例,先来几张样例图(注:为了展示窗口阴影效果,截图范围向外扩展了些,各位凭想象吧)。 还要来个序 ...

据说得有楔子

    按照惯例,先来几张样例图(注:为了展示窗口阴影效果,截图范围向外扩展了些,各位凭想象吧)。

    [DForm]我也来做自定义Winform之另类标题栏重绘       [DForm]我也来做自定义Winform之另类标题栏重绘    [DForm]我也来做自定义Winform之另类标题栏重绘    [DForm]我也来做自定义Winform之另类标题栏重绘   [DForm]我也来做自定义Winform之另类标题栏重绘

 

 

 

 

还要来个序

   其实,很多年没写过Winform了,前端时间在重构我们公司自己的呼叫中心系统,突然就觉得客户端好丑好丑,对于我这种强迫症晚期患者来说,界面不好看都不知道怎么写代码的,简直就是种折磨,还是满清十大酷刑级别那种。

   很多人推荐WPF,不过个人对WPF没啥感觉,而且据说也无法支持2.0,还是采用Winform技术来搞吧。

终于第一节

   做Winform皮肤,我了解的无非有2种方式。

   1.采用纯图片模式:由专业美工设计各种样式的图片,进行窗口背景图片设置

   2.采用GDI+纯代码绘制:参照美工设计的各种样式的图片,使用C#代码绘制出来

   第一种方式很简单,但是可复用性不高,性能上面应该也会有一些影响,如果图片太大,窗口拖动等引起的重绘时,会明显有闪烁等情况。

   第二种方式很复杂,但是效率和复用性高,开放各种扩张属性之后,可以适用于大部分场景。

   以前用了很多次第一种方案,每次新做APP,都得重新设计界面,很不便利。这次,我准备采用第二种方案来做一个公用的皮肤。

 

   关于GDI+,我只能算一个新人,不做具体的介绍,这里只讲我的一些实现方式,计划项目完成后,开源到github。

绘制标题栏

   做自定义界面,绕不开一个问题就是绘制标题栏。

   每个Winform窗体,可以分为两个部分:非客户区域和客户区域。

   非客户区域:表示无法由我们程序猿绘制的部分,具体包括:窗口标题栏,边框

   客户区域:表示由我们程序猿绘制的部分,也就是窗体内容,平时我们拖控件都是拖到客户区域

   一般自定义窗口的实现方式无非以下种

   1.设置窗口为无边框窗口,顶部放一个Panel,设置Panel.Dock=Top,然后在Panel里面绘制logo、标题、按钮等元素。

   2.拦截窗口消息,重写WndProc方法,拦截窗口标题绘制消息,由自己手工绘制

  很多人会为了简便,采用第一种方式,不过缺点比较明显,对于我来说,最主要的一点就是真正的实现界面,里面的控件元素Dock会受到影响,不利于客户区域布局。

  高手牛人会采用第二种方式,不是我这种Winform小白的菜,所以,我采用第三种方式,也是本篇文章的核心思想。

    采用无边框窗口,设置窗口Padding.Top为标题栏高度,采用GDI+绘制标题栏元素。

   这种方式的好处显而易见

      具体实现窗体子控件Dock不受影响

      无边框之后,重写窗体拖动事件不需要对标题栏每一个元素进行事件处理

      标题栏高度可随时自定义

   本文开头的几个截图,标题栏绘制代码如下

 绘制标题文字、Logo图片

    private void DrawTitle(Graphics g)    {      var x = 6 + this.GetBorderWidth();      if (this.ShowLogo)      {        g.SmoothingMode = SmoothingMode.AntiAlias;        ImageAttributes imgAtt = new ImageAttributes();        imgAtt.SetWrapMode(System.Draget='_blank'>wing.Drawing2D.WrapMode.TileFlipXY);        using (var image = this.Icon.ToBitmap())        {          var rec = new Rectangle(x, (this.captionHeight - 24) / 2, 24, 24);          g.DrawImage(image, rec, 0, 0, image.Width, image.Height, GraphicsUnit.Pixel, imgAtt);        }      }      if (this.ShowTitle)      {        var font = this.titleFont == null ? this.Font : this.titleFont;        var fontSize = Size.Ceiling(g.MeasureString(this.Text, font));        if (this.CenterTitle)        {          x = (this.Width - fontSize.Width) / 2;        }        else if (this.ShowLogo)        {          x += 30;        }        using (var brush = new SolidBrush(this.CaptionForeColor))        {          g.DrawString(this.Text, font, brush, x, (this.CaptionHeight - fontSize.Height) / 2 + this.GetBorderWidth());        }      }    }

 

海外公司注册、海外银行开户、跨境平台代入驻、VAT、EPR等知识和在线办理:https://www.xlkjsw.com

原标题:[DForm]我也来做自定义Winform之另类标题栏重绘

关键词:winform

*特别声明:以上内容来自于网络收集,著作权属原作者所有,如有侵权,请联系我们: admin#shaoqun.com (#换成@)。

可能感兴趣文章

我的浏览记录