asp.net控件设计时支持(4)

本文详细介绍了ASP.NET控件在设计时的支持实现方法,包括单区域编辑和多区域编辑的设计过程。通过实例展示了如何自定义控件及其实现设计时支持的步骤。
        首先还是 示例代码下载
       这次让我们来看下控件可编辑设计区域的设计时支持.

一.单区域编辑

1.介绍

在内置控件中,典型的则是Panel控件,如下图


其在设计时提供了一个编辑区域,可方便的编辑控件内部文本,并提供了一个标题属性,此设计时呈现效果并非呈现以后的效果.另外除Panel控件外,MultiView控件也提供相似的设计时支持.下面我们看一下类图



ContainerControlDesigner 提供 单个带框区域来表示控件,注意是单个,你只需要关注以上两个属性和一个方法既可, 最终的封装实现还是调用GetDesignTimeHtml 方法的,以下为属性简单说明

FrameCaption  设置时显示的标题

FrameStyle  设置时显示的标题样式


2.实现

2.1
自定义一个继承ContainerControlDesigner的类,并重写相关属性

None.gif      public   class  SimpleContainerControlDesigner : ContainerControlDesigner
ExpandedBlockStart.gifContractedBlock.gif    
dot.gif {
InBlock.gif        
private Style _style = null;
InBlock.gif
InBlock.gif        
//设计时标题
InBlock.gif
        public override string FrameCaption
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
get
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
return "我的测试控件";
ExpandedSubBlockEnd.gif            }

ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
//设计时标题样式
InBlock.gif
        public override Style FrameStyle
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
get
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
if (_style == null)
ExpandedSubBlockStart.gifContractedSubBlock.gif                
dot.gif{
InBlock.gif                    _style 
= new Style();
InBlock.gif                    _style.Font.Name 
= "Verdana";
InBlock.gif                    _style.Font.Size 
= new FontUnit(FontSize.XLarge);
InBlock.gif                    _style.BackColor 
= Color.LavenderBlush;
InBlock.gif                    _style.ForeColor 
= Color.DarkBlue;
ExpandedSubBlockEnd.gif                }

InBlock.gif
InBlock.gif                
return _style;
ExpandedSubBlockEnd.gif            }

ExpandedSubBlockEnd.gif        }

ExpandedBlockEnd.gif    }

2.2 自定义控件,并与控件相关联, 该控件只提供了一个背景图片的属性

None.gif     [
None.gif        Designer(
typeof (SimpleContainerControlDesigner)),
None.gif        ParseChildren(
false )
None.gif    ]
None.gif    
public   class  SimpleContainerControl : WebControl
ExpandedBlockStart.gifContractedBlock.gif    
dot.gif {
InBlock.gif        
public string BackgroundImage
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
ExpandedSubBlockStart.gifContractedSubBlock.gif            
get dot.gifreturn ViewState["BackgroundImage"!= null ? (string)ViewState["BackgroundImage"] : ""; }
ExpandedSubBlockStart.gifContractedSubBlock.gif            
set dot.gif{ ViewState["BackgroundImage"= value; }
ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
protected override void AddAttributesToRender(HtmlTextWriter writer)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
base.AddAttributesToRender(writer);
InBlock.gif            writer.AddStyleAttribute(HtmlTextWriterStyle.BackgroundImage, BackgroundImage);
InBlock.gif
ExpandedSubBlockEnd.gif        }

ExpandedBlockEnd.gif    }


好了,大功告成,可以看下效果了



2.3 设计时区域样式

还没完呢,为什么我故意设置一个 BackgroundImage属性呢,现在我们设置BackgroundImage属性,当设置好以后(请一定设置此属性),你有没发现此控件区域内并没有出现背景图片.还不如不加自定义的设计时支持呢?

原因: 区域编辑区域样式的设计时的每个属性都是由ContainerControlDesigner帮你写好的,里面包括WebControl公有属性,这些不需要你重写,但当你自定义属性需要呈现,而你又想完美的在设计时看到效果时,则你必须重写 AddDesignTimeCssAttributes方法了,如 BackgroundImage属性,Panel控件也有背景图片这个属性,其设计时支持也是这么做的.实现方法如下

None.gif          // 添加设计时样式属性
None.gif
         protected   override   void  AddDesignTimeCssAttributes(System.Collections.IDictionary styleAttributes)
ExpandedBlockStart.gifContractedBlock.gif        
dot.gif {
InBlock.gif            
base.AddDesignTimeCssAttributes(styleAttributes);
InBlock.gif            SimpleContainerControl control 
= base.ViewControl as SimpleContainerControl;
InBlock.gif            
string BackgroundImage = control.BackgroundImage;
InBlock.gif            
if (BackgroundImage.Trim().Length > 0)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                styleAttributes[
"background-image"= "url(" + BackgroundImage + ")";
ExpandedSubBlockEnd.gif            }

ExpandedBlockEnd.gif        }

好了再测试下,效果出来了.以上我认为是理解的重点,其他倒没什么,大家多修改即可理解.

二.多区域编辑

让我们来看下asp.net2.0中的Wizard控件的设计时,当点击 Step1和Step2时,你可以在区域中编辑不同的内容,我称之为 多区域编辑



设计时支持什么呢?多区域则比刚才编辑一个区域复杂,刚才的几乎不需要做什么事情,现在要做的多一些

需要注意的地方如下

1.控件区域点击事件 刚才已经试过了当点击 Step1和Step2时,你可以在区域中编辑不同的内容

此部分操作在ControlDesignerd的OnClick事件中完成

2.设置区域

区域包括两种
(1).点击的区域,
即step1和step2  (DesignerRegion类)
(2).编辑的区域,即那个小边框 (EditableDesignerRegion类)

此部分操作在GetDesignTimeHtml方法中完成
3.模板数据操作

包括两部分操作
(1)
选择一个区域后,编辑区域显示要 获取的数据
(2)当编辑完区域里数据后, 更新数据

4.寻找事件触发对象

万事具备,刚才的第一步中,Step1和Step2也是呈现也页面上的,此做为事件触发者,所以我们 还需要对其做一下标记.

好了,重要部门都已经说清楚了.下面来看例子

先看效果吧,方便理解.这里大多的例子直接来自MSDN



当点击View1和View2时,在蓝色区域会呈现不同模板的内容,还记得上篇模板控件的设计时支持吗?这里又有新方法了,而且更加简单.

下面为自定义控件代码,你只需要知道以下两点
1.提供了两个模板属性
2.Table提供了三个区域

ContractedBlock.gif ExpandedBlockStart.gif
None.gif   public class MyMultiRegionControl : CompositeControl
ExpandedBlockStart.gifContractedBlock.gif    
dot.gif{
InBlock.gif        
InBlock.gif        
private ITemplate _view1;
InBlock.gif        
private ITemplate _view2;
InBlock.gif
InBlock.gif        [PersistenceMode(PersistenceMode.InnerProperty), DefaultValue(
null)]
InBlock.gif        
public virtual ITemplate View1
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
ExpandedSubBlockStart.gifContractedSubBlock.gif            
get dot.gifreturn _view1; }
ExpandedSubBlockStart.gifContractedSubBlock.gif            
set dot.gif{ _view1 = value; }
ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        [PersistenceMode(PersistenceMode.InnerProperty), DefaultValue(
null)]
InBlock.gif        
public virtual ITemplate View2
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
ExpandedSubBlockStart.gifContractedSubBlock.gif            
get dot.gifreturn _view2; }
ExpandedSubBlockStart.gifContractedSubBlock.gif            
set dot.gif{ _view2 = value; }
ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
private int _currentView = 0;
InBlock.gif        
public int CurrentView
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
ExpandedSubBlockStart.gifContractedSubBlock.gif            
get dot.gifreturn _currentView; }
ExpandedSubBlockStart.gifContractedSubBlock.gif            
set dot.gif{ _currentView = value; }
ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
protected override void CreateChildControls()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            Controls.Clear();
InBlock.gif            Table t 
= new Table();
InBlock.gif            t.CellSpacing 
= 1;
InBlock.gif            t.BorderStyle 
= BorderStyle;
InBlock.gif            t.Width 
= this.Width;
InBlock.gif            t.Height 
= this.Height;
InBlock.gif
InBlock.gif            TableRow tr 
= new TableRow();
InBlock.gif            tr.HorizontalAlign 
= HorizontalAlign.Center;
InBlock.gif            tr.BackColor 
= Color.LightBlue;
InBlock.gif
InBlock.gif            TableCell tc 
= new TableCell();
InBlock.gif            tc.Text 
= "View1";
InBlock.gif            tc.Width 
= new Unit("50%");
InBlock.gif            tr.Cells.Add(tc);
InBlock.gif
InBlock.gif            tc 
= new TableCell();
InBlock.gif            tc.Text 
= "View 2";
InBlock.gif            tc.Width 
= new Unit("50%");
InBlock.gif            tr.Cells.Add(tc);
InBlock.gif
InBlock.gif            t.Rows.Add(tr);
InBlock.gif
InBlock.gif            tr 
= new TableRow();
InBlock.gif            tr.HorizontalAlign 
= HorizontalAlign.Center;
InBlock.gif
InBlock.gif            tc 
= new TableCell();
InBlock.gif            tc.ColumnSpan 
= 2;
InBlock.gif            tr.Cells.Add(tc);
InBlock.gif            t.Rows.Add(tr);
InBlock.gif            Controls.Add(t);
ExpandedSubBlockEnd.gif        }

ExpandedBlockEnd.gif    }


步骤

(1).自定义一个从CompositeControlDesigner继承的类,CompositeControlDesigner为复合控件提供设计时支持,我们需要重写CreateChildControl方法

None.gif          protected   override   void  CreateChildControls()
ExpandedBlockStart.gifContractedBlock.gif        
dot.gif {
InBlock.gif            
base.CreateChildControls();
InBlock.gif            Table t 
= (Table)myControl.Controls[0];
InBlock.gif            
if (t != null)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                t.Rows[
0].Cells[0].BackColor = Color.Red;
InBlock.gif
InBlock.gif                
//定义区域事件触发对象
InBlock.gif
                t.Rows[0].Cells[0].Attributes[DesignerRegion.DesignerRegionAttributeName] = "0";
InBlock.gif                t.Rows[
0].Cells[1].BackColor = Color.Green;
InBlock.gif                t.Rows[
0].Cells[1].Attributes[DesignerRegion.DesignerRegionAttributeName] = "1";
InBlock.gif                t.Rows[
1].Cells[0].BackColor = Color.Blue;
InBlock.gif                t.Rows[
1].Cells[0].Attributes[DesignerRegion.DesignerRegionAttributeName] = "2";
ExpandedSubBlockEnd.gif            }

ExpandedBlockEnd.gif        }


主要工作就是为Click事件定义了区域事件出发对象,方法则是为控件属性集合提供DesignerRegion.DesignerRegionAttributeName属性,注意值0,1,2和GetDesignTimeHtml方法中的DesignerRegionCollection集合顺序是一样的,不可以弄乱,按上面效果图

你可以看到0和1是触发区域事件的对象(即View1和View2),2则是编辑区域

(2)添加区域,接同上面步骤,在GetDesignTimeHtml方法中完成,这里命名哦,跟各个操作步骤紧密联系在一起的

None.gif          public   override  String GetDesignTimeHtml(DesignerRegionCollection regions)
ExpandedBlockStart.gifContractedBlock.gif        
dot.gif {
InBlock.gif            
//注意构造函数命名以及区域顺序
InBlock.gif            
//区域顺序与DesignerRegion.DesignerRegionAttributeName相对应
InBlock.gif
            regions.Add(new DesignerRegion(this"Header0"));
InBlock.gif            regions.Add(
new DesignerRegion(this"Header1"));
InBlock.gif            EditableDesignerRegion editableRegion 
=
InBlock.gif                
new EditableDesignerRegion(this,
InBlock.gif                    
"Content" + myControl.CurrentView, false);
InBlock.gif            regions.Add(editableRegion);
InBlock.gif
InBlock.gif            
//突出编辑区域
InBlock.gif
            regions[myControl.CurrentView].Highlight = true;
InBlock.gif
InBlock.gif            
return base.GetDesignTimeHtml();
ExpandedBlockEnd.gif        }

(4)更新和获取模板数据操作

None.gif     // 获取模板内部数据
None.gif
         public   override   string  GetEditableDesignerRegionContent(EditableDesignerRegion region)
ExpandedBlockStart.gifContractedBlock.gif        
dot.gif {
InBlock.gif            
InBlock.gif            IDesignerHost host 
= (IDesignerHost)Component.Site.GetService(typeof(IDesignerHost));
InBlock.gif            
if (host != null)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                ITemplate template 
= myControl.View1;
InBlock.gif                
if (region.Name == "Content1")
InBlock.gif                    template 
= myControl.View2;
InBlock.gif
InBlock.gif                
if (template != null)
InBlock.gif                    
return ControlPersister.PersistTemplate(template, host);
ExpandedSubBlockEnd.gif            }

InBlock.gif
InBlock.gif            
return String.Empty;
ExpandedBlockEnd.gif        }

None.gif
None.gif        
// 设置模板内部数据
None.gif
         public   override   void  SetEditableDesignerRegionContent(EditableDesignerRegion region,  string  content)
ExpandedBlockStart.gifContractedBlock.gif        
dot.gif {
InBlock.gif            
if (content == null)
InBlock.gif                
return;
InBlock.gif            IDesignerHost host 
= (IDesignerHost)Component.Site.GetService(typeof(IDesignerHost));
InBlock.gif            
if (host != null)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                ITemplate template 
= ControlParser.ParseTemplate(host, content);
InBlock.gif
InBlock.gif                
if (template != null)
ExpandedSubBlockStart.gifContractedSubBlock.gif                
dot.gif{
InBlock.gif                    
if (region.Name.EndsWith("0"))
InBlock.gif                        myControl.View1 
= template;
InBlock.gif                    
else if (region.Name.EndsWith("1"))
InBlock.gif                        myControl.View2 
= template;
ExpandedSubBlockEnd.gif                }

ExpandedSubBlockEnd.gif            }

ExpandedBlockEnd.gif        }


好了,又完成了一个.里面一些新出现的类,大家查查MSDN熟悉下就好,知道如何做才是最重要的,如果还不是很清楚,建议你把里面的程序改改,再编译,这样会出现不同的效果,多次反复测试就会明白了.

这里主要是讨论区域编辑,作为控件开发很重要的一部分,设计时支持也很重要.下次我们继续

转载于:https://www.cnblogs.com/Clingingboy/archive/2007/05/15/747818.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值