首 页 | 新 闻 | 技术中心 | 第二书店 | 《程序员》 | 《开发高手》 | 社 区 | 黄 页 | 人 才
移 动专 题SUNIBM微 软微 创精 华Donews人 邮
我的技术中心 
我的分类 我的文档
全部文章 发表文章
专栏管理 使用说明



 RSS 订阅 
最新文档列表
Windows/.NET
.NET  (rss)    
Visual C++  (rss)    
Delphi  (rss)    
Visual Basic  (rss)    
ASP  (rss)    
JavaScript  (rss)    
Java/Linux
Java  (rss)    
Perl  (rss)    
综合
其他开发语言  (rss)    
文件格式  (rss)    
企业开发
游戏开发  (rss)    
网站制作技术  (rss)    
数据库
数据库开发  (rss)    
软件工程
其他  (rss)    

积极原创作者 
psyl (153)
capsicum29 (8)
qdzx2008 (51)
ShowLong (1)
cyp403 (16)
yjz0065 (114)
lphpc (31)
smallnest (63)
tellmenow (22)
cutemouse (22)
CSDN - 文档中心 - .NET 阅读:2127   评论: 0    参与评论
标题   [原创]IssueVision 学习笔记(二)-----为控件添加自定义属性和事件     选择自 yellowwee 的 Blog
关键字   控件,属性
出处  


     我们先来看看IssueVision中一个用户控件PaneCaption在可视化设计器中的属性窗口.



    再看一下在另一个用户控件StaffPane中使用它时的属性窗口:




    大家会发现它多出来很多个属性,这些属性是原来继承控件中没有的属性,如:InactiveTextColor,InactiveTextColor等等.它们是如何实现的呢?我们就来看一下这个用户控件的代码PaneCaption.cs吧.

namespace IssueVision
{
 // Custom control that draws the caption for each pane. Contains an active
 // state and draws the caption different for each state. Caption is drawn
 // with a gradient fill and antialias font.
 public class PaneCaption : UserControl
 {
  private class Consts
  {
 ......

  可以看到它是由 System.Windows.Forms.UserControl 继承而来,图一显示了它的默认属性.下面我们接着PaneCaption.cs代码,看看是如何将属性或事件显示在可视化设计器中.

  [DefaultValueAttribute(typeof(Color), "3, 55, 145")]
  [DescriptionAttribute("Low color of the inactive gradient.")]
  [CategoryAttribute("Appearance")]

  public Color InactiveGradientLowColor
  {
   get
   {
    return m_colorInactiveLow;
   }

   set
   {
    if (value == Color.Empty)
    {
     value = Color.FromArgb(3, 55, 145);
    }
    m_colorInactiveLow = value;
    CreateGradientBrushes();  //自定义方法,用于创建线形渐变笔刷
    Invalidate();    //Control.Invalidate 方法,使控件的特定区域无效并向控件发送绘制消息
   }
  }

  [CategoryAttribute("Appearance")]
  [DescriptionAttribute("High color of the inactive gradient.")]
  [DefaultValueAttribute(typeof(Color), "90, 135, 215")]

  public Color InactiveGradientHighColor
  {
   get
   {
    return m_colorInactiveHigh;
   }

   set
   {
    if (value == Color.Empty)
    {
     value = Color.FromArgb(90, 135, 215);
    }
    m_colorInactiveHigh = value;
    CreateGradientBrushes();
    Invalidate();
   }
  }

  [DescriptionAttribute("Text displayed in the caption.")]
  [DefaultValueAttribute("")]
  [CategoryAttribute("Appearance")]

  public string Caption
  {
   get
   {
    return m_text;
   }

   set
   {
    m_text = value;
    Invalidate();
   }
  }

  其结果如下图所示:




    我们可以看到Views,Staff list背景都是使用这个自定义的PaneCaption产生渐变效果(由InactiveGradientHighColorInactiveGradientLowColor属性实现),文字Views和Staff list是由属性Caption实现.



  代码分析:

     最重要的是 CategoryAttribute 类,它指定属性或事件将显示在可视化设计器中的哪个类别,具体类别如下表:

 类别

 说明

 Action  关于可用操作的属性。
 Appearance  影响实体外观的属性。
 Behavior  影响实体行为的属性。
 Data  关于数据的属性。
 Format  影响格式的属性。
 Layout  关于布局的属性。
 Default  没有类别的属性属于默认类别。













有关更多信息,请参阅.Net Framework 1.1 SDK

    我们看到举例的这三个属性CategoryAttribute属性值都为CategoryAttribute("Appearance"),从图二可以看出,这些属性都显示在"外观"下.

    DefaultValueAttribute 属性顾名思义,就是此自定义属性的默认值.
    DescriptionAttribute 属性则为此自定义属性的描述.


    关键部分已经设置完成,剩下的就是如何实现属性的效果了,我以代码说明:

 protected override void OnPaint(PaintEventArgs e)
  {
   DrawCaption(e.Graphics);
   base.OnPaint(e);
  }

  // draw the caption
  private void DrawCaption(Graphics g)
  {
   // background
   g.FillRectangle(this.BackBrush, this.DisplayRectangle);
   
   if (m_antiAlias)
    g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
   
   // need a rectangle when want to use ellipsis
   RectangleF bounds  = new RectangleF(Consts.PosOffset,
            0,
            this.DisplayRectangle.Width - Consts.PosOffset,
            this.DisplayRectangle.Height);

   g.DrawString(m_text, this.Font, this.TextBrush, bounds, m_format);
  }

 使用Graphics.DrawString 绘制出Caption(即文字Views和Staff list),Graphics.FillRectangle 绘制渐变背景.注意此Graphics.FillRectangle 方法的第一个参数为笔刷,此笔刷就为上面自定义属性代码中CreateGradientBrushes() 方法所创建的笔刷.代码如下:

 private void CreateGradientBrushes()
  {
   // can only create brushes when have a width and height
   if (Width > 0 && Height > 0)
   {
    if (m_brushActive != null)
    {
     m_brushActive.Dispose();
    }
  // 其中  m_colorActiveHigh 值就为自定义属性InactiveGradientHighColor的值,m_colorActiveLow则为自定义属性InactiveGradientLowColor的值.
    m_brushActive = new LinearGradientBrush(DisplayRectangle, m_colorActiveHigh, m_colorActiveLow, LinearGradientMode.Vertical);
    
    if (m_brushInactive != null)
    {
     m_brushInactive.Dispose();
    }
    
    m_brushInactive = new LinearGradientBrush(DisplayRectangle, m_colorInactiveHigh, m_colorInactiveLow, LinearGradientMode.Vertical);
   }
  }

// gradient brush for the background
  private LinearGradientBrush BackBrush
  {
   get
   {
    if (m_active && m_allowActive)
     return m_brushActive;
    else
     return m_brushInactive;
   }
  }

 补充一点:根据GDI+要求,所有图形的绘制都通过OnPaint()方法绘制,只用重载此方法,就可以重新绘制所需的图形了.(此方法就如Java中的PaintComponet()方法一样)

  这次就写这么多了,希望大家多多交流,这也只是我一个人的认识,还要多和大家交流才会有提高.



CopyRight © YellowWee 2004. All Right Reserved.


相关文章
对该文的评论