给自定义Control加上Smart Tag

Posted on 2005-12-19 21:44  Vitoria  阅读(2435)  评论(3编辑  收藏  举报
 

智能标签,提供快捷的控件属性编辑。毋庸多说,见下图1:



 

如何在自定义的控件里也添加上SmartTag呢?本文作简单描述。

秘密就在自定义控件的Designer里面。

ControlDesigner. ActionLists 属性用以实现具体的SmartTag

首先需要写一个从DesignerActionList派生的类用来实现我们的SmartTag,本文只在SmartTag上放了一个TextBox


public class CustomControlActionList :System.ComponentModel.Design.DesignerActionList
  
{    … …
    
public override DesignerActionItemCollection GetSortedActionItems()
   
{
            DesignerActionItemCollection item 
= new DesignerActionItemCollection();
             item.Add(
                     
new DesignerActionPropertyItem("Text",
                     
"Text String""Appearance",
                      
"Sets the display text."));
             
return item;
         }

         … …
    }


 

看到我们加了一个DesignerActionPropertyItem用以编辑Text

public DesignerActionPropertyItem(

               string memberName,

               string displayName,

               string category,

               string description

)

参数memberName,变量名

参数displayName,显示的名称

参数category,类别名称

参数description,描述,在ToolTip中显示

注意到我给它的Category传的是Appearance,为了好看我想给它加个类别,怎么加呢?如下:

item.Add(new DesignerActionHeaderItem("Appearance"));

显然Text是个Property,我需要告诉SmartTag怎么得到Text的值,怎么把编辑的值送回去,在CustomControlActionList类中创建一个“Text”属性就可以了


public string Text
  
{
      
get
           
{
                 
return CustomControl.Text;
             }

            
set
            
{
                 PropertyDescriptor descriptor 
= TypeDescriptor.GetProperties(CustomControl)["Text"];
                 descriptor.SetValue(CustomControl, value);
                 
this._service.Refresh(this.Component);
              }

          }


 

设值是通过反射去做的。

 

好了,接下来我们要做的事情就是把它添加到ControlDesigner中了

public class CustomControlDesigner : ControlDesigner
  
{
     
{
         
public override System.ComponentModel.Design.DesignerActionListCollection ActionLists
         
{
             
get
            
{
                 DesignerActionListCollection collection 
= new DesignerActionListCollection();
                collection.Add( 
new CustomControlActionList(this.Component, this));
                
return collection;
             }

         }

    }


 

很简单吧,好了看看我们的CustomControl效果:

 

给出所有的代码:

 

CustomControl1


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace WindowsApplication1
{
    [Designer( 
typeof( CustomControlDesigner))]
    
public partial class CustomControl1 : Control
    
{
        
public CustomControl1()
        
{
            InitializeComponent();
        }


        
protected override void OnPaint(PaintEventArgs pe)
        
{
            
// TODO: Add custom paint code here
            pe.Graphics.FillRectangle(new SolidBrush(this.BackColor), pe.ClipRectangle);
            pe.Graphics.DrawString(
this.Text, this.Font, new SolidBrush(this.ForeColor), pe.ClipRectangle);
            
// Calling the base class OnPaint
            base.OnPaint(pe);
        }


        
public new string Text
        
{
            
get return base.Text; }
            
set base.Text = value; this.Refresh(); }
        }

    }

}


 

CustomControlDesignerCustomControlActionList


using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms.Design;
using System.Windows.Forms.Design.Behavior;
using System.ComponentModel.Design;
using System.ComponentModel;

namespace WindowsApplication1
{
    
public class CustomControlDesigner : ControlDesigner
    
{
        
public override System.ComponentModel.Design.DesignerActionListCollection ActionLists
        
{
            
get
            
{
                DesignerActionListCollection collection 
= new DesignerActionListCollection();
                
                collection.Add( 
new CustomControlActionList(this.Component, this));
                
return collection;
            }

        }

    }


    
public class CustomControlActionList :
          System.ComponentModel.Design.DesignerActionList
    
{
        
private DesignerActionUIService _service;
        
private CustomControlDesigner _designer;

        
public CustomControlActionList(IComponent c, CustomControlDesigner designer)
            : 
base(c) {
                
this._designer = designer;
                
this._service = c.Site.GetService(typeof(DesignerActionUIService)) as DesignerActionUIService;
                
this.AutoShow = true;
        }

        
public override DesignerActionItemCollection GetSortedActionItems()
        
{
            DesignerActionItemCollection item 
= new DesignerActionItemCollection();
            item.Add(
new DesignerActionHeaderItem("Appearance"));
            item.Add(
                    
new DesignerActionPropertyItem("Text",
                     
"Text String""Appearance",
                     
"Sets the display text."));
            
return item;
        }


        
private CustomControl1 CustomControl
        
{
            
get
            
{
                
return this.Component as CustomControl1;
            }

        }


        
public string Text
        
{
            
get
            
{
                
return CustomControl.Text;
            }

            
set
            
{
                PropertyDescriptor descriptor 
= TypeDescriptor.GetProperties(CustomControl)["Text"];
                descriptor.SetValue(CustomControl, value);

                
this._service.Refresh(this.Component);
            }

        }

    }

}

Copyright © 2024 Vitoria
Powered by .NET 8.0 on Kubernetes