一起谈.NET技术,asp.net控件开发基础(5)

  我们根据属性的不同表现形式,把其区分为简单属性和复杂属性,下面来看下属性的表现形式。简单属性表现形式如下,大家都很熟悉

<asp:TextBox ID="TextBox1" Text="textbox控件" runat="server"></asp:TextBox>

  属性中含有子属性,称之为复杂对象,如Font属性,复杂属性的表现形式如下:

  (1)连字符的表现形式

<asp:TextBox ID="TextBox1" Text="textbox控件" runat="server" Font-Bold="True"></asp:TextBox>

  (2)内镶属性的表现形式,如定义样式

<asp:DataList ID="DataList1" runat="server">
            <SelectedItemStyle />
            <EditItemStyle />
        </asp:DataList>

  (3)内镶集合属性的表现形式,如DropDownList (先不介绍,大家可看MSDN)

<asp:DropDownList ID="DropDownList1" runat="server">
            <asp:ListItem>x</asp:ListItem>
            <asp:ListItem>xx</asp:ListItem>
            <asp:ListItem>xxx</asp:ListItem>
        </asp:DropDownList>

 1. 复杂属性基本使用方法

  请看我是怎么做的,关于下面看到了一些元数据,如果你不熟悉,请参考MSDN。下面一段代码记录一个custom的信息.
  1.1 定义枚举

using System;

namespace CustomComponents
{
    /**//// <summary>
    /// 职业
    /// </summary>
    public enum Metier
    {
        教师,程序员,作家
    }
}

  1.2定义复杂属性

using System;
using System.ComponentModel;

namespace CustomComponents
{


    /**//// <summary>
    /// 地址集合
    /// </summary>
    public class Address
    {
        private String street = null;
        private String city = null;
        private String state = null;
        private String zip = null;

        public String Street
        {
            get
            {
                return street;
            }
            set
            {
                street = value;
            }
        }


        public String City
        {
            get
            {
                return city;
            }
            set
            {
                city = value;
            }
        }

        public String State
        {
            get
            {
                return state;
            }
            set
            {
                state = value;
            }
        }

        public String Zip
        {
            get
            {
                return zip;
            }
            set
            {
                zip = value;
            }
        }
    }
}

  1.3 呈现控件

 


using System;
using System.ComponentModel;
using System.Web;
using System.Web.UI;

namespace CustomComponents
{
public class Custom: Control
{
private String name = null;
Address address = new Address();
private Metier metier;
private int age = 0;

属性

protected override void Render(HtmlTextWriter output)
{
output.Write("姓名: " + Name + "<br>");
output.Write("年龄: " + Age + "<br>");
output.Write("职业: " + CustomMetier + "<br>");
output.Write("具体地址: " + CustomAddress.Street + "<br> 城市: "
+ CustomAddress.City + "<br> 国籍: " +
CustomAddress.State + "<br> 邮编: " + CustomAddress.Zip + "<br>");
}
}
}

  1.4 在asp.net页面定义控件,
  发现问题:
属性不是有效属性,如下图

  打开后台代码,输入如下代码检查属性,发现属性是存在的,如下图,再打开视图,发现控件能显示属性,唯一的就是不能认识属性为有效属性,在源视图也无法找到这几个属性.

  1.5  解决1.4无法显示有效属性的问题,(其实以上的测试已经实现复杂属性了).

  解决方法:请在Custom类中的CustomAddress中加入一个元数据(元数据的解释请参考MSDN),如下

        [Description("地址集合")]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
        public Address CustomAddress
        {
            get
            {
                return address;
            }
        }

  再次打开源视图,发现编辑器已经支持此属性了,如下图,这样有点意思吧,呵呵

  虽然源视图上已经支持这个复杂属性了,打开属性面板,发现属性面板并不支持这个复杂属性(因为我们比较懒,不喜欢在源视图里编辑属性,想直接在属性面板编辑属性,下面就称复杂属性是CustomAddress),我们想要达到的效果,是让CustomAddress属性跟Font属性一样(可以折叠)显示在面板上,如下图


  发现问题:属性面板并不支持这个复杂属性

  1.6 实现CustomAddress属性折叠效果

  解决方法:给Address类添加一个元数据,如下

[TypeConverter(typeof(ExpandableObjectConverter))]
    public class Address
    {. }

  编译后,再次打开属性面板,发现CustomAddress属性已经支持折叠效果,如下图

  试着在属性面板编辑CustomAddress的子属性,修改好子属性以后然后运行页面,发现子属性修改数据后无效

  发现问题:在属性面板编辑复杂属性的子属性无效

  1.7 解决属性面板编辑复杂属性的子属性无效的问题

  解决方法:为Address类的每个属性加上一个元数据,如下

        [NotifyParentProperty(true)]
        public String Street
        {
            get
            {
                return street;
            }
            set
            {
                street = value;
            }
        }

  编译后,回到原asp.net的页面,再次在属性面板里修改子属性,再次运行页面.发现修改后的数据生效了。好了,以上代码就是连字符形式的复杂属性的实现,我们接着继续,我们希望把CustomAddress属性做为内镶属性使用,即如下代码的形式

        <custom:custom id="Custom1" runat="server" name="Clingingboy" CustomMetier="教师" Age="21">
         <CustomAddress City="杭州" Street="不告诉你" State="中国" Zip="310000" />
         </custom:custom>

  发现问题:无法使用内镶属性。

  1.8 实现内镶属性

  解决方法:在Custom类中给CustomAddress再加入一个元数据(第三个),如下

        [Description("地址集合")]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
        [PersistenceMode(PersistenceMode.InnerProperty)]
        public Address CustomAddress
        {
            get
            {
                return address;
            }
        }

  打开源视图(请不要把原来的连字符属性去掉),在控件内部加入如下代码(编辑器已经支持此属性了)

        <custom:custom    
        CustomAddress-Zip="3100001"  CustomAddress-City="杭州1" 
        CustomAddress-State="中国1" CustomAddress-Street="不告诉你1"
         id="Custom1" runat="server" name="Clingingboy" CustomMetier="教师" Age="21">
         <CustomAddress City="杭州" Street="不告诉你" State="中国" Zip="310000" />
         </custom:custom>

  发现问题:查看属性面板,再次修改CustomAddress子属性,然后运行,发现修改后无效果,而且显示的数据仍然是连字符属性的数据(非内镶属性的)
  1.9 让控件支持内镶属性
  解决方法:
给Custom类添加元数据,如下代码

    [ParseChildren(true)]
    public class Custom: Control
     }

  编译后,再次测试发现属性显示的优先级发生了变化,在内镶属性存在的时候,显示内镶属性,若其中有子属性不存在,则显示连字符属性,大家可以适当更改内镶属性和连字符属性测试变化。

  发现问题:在属性面板改变属性时,仍然无法使修改后的数据生效,且修改后,数据退回初始的数据,并且导致内镶属性消失

  1.10 解决属性面板的问题

  解决方法:给Custom类再添加一个元数据,如下代码

    [ParseChildren(true)]
    [PersistChildren(false)]
    public class Custom: Control
     }

  编译后再次修改属性面板的值,发现修改的是内镶属性的数据,而且这次修改后数据没有丢失,运行后也是修改后的效果。好了,简单的讲完了.

  总结下:上面刚开始到1.3为止,其实效果已经实现了,接下来都是添加元数据,添加以后给我们带来的是方便.以上解决问题的办法全是套用元数据.可能上面的元数据大家很熟悉,在MSDN里面字面解释的也很清楚,但你去试验过吗?我相信这样的试验可以让你明白的更加深刻。

上一篇:asp.net控件开发基础(4)

下一篇:asp.net控件开发基础(6)

时间: 2024-09-19 09:16:05

一起谈.NET技术,asp.net控件开发基础(5)的相关文章

一起谈.NET技术,asp.net控件开发基础(15)

继续我们的话题吧.自定义控件.如果你还不熟悉自定义控件开发的话,还请看看我以前写了几篇,希望对你有帮助 1.1何处继承 自定义控件一般从以下几个基类(此处不包含数据控件) 一.Control类(所有服务器控件的基类,算是比较底层的类,如果控件功能比较简单,要求不多,可直接继承此类.) 二.WebControl类(标准控件的基类,继承此类,你可以继承其丰富的公共属性,若标准控件中的控件没有你需要的控件,你可以继承此类) 三.CompositeControl 类(2.0新增的类,此类继承自WebCo

一起谈.NET技术,asp.net控件开发基础(13)

1.减轻服务器压力,增加用户体验 服务器功能是强大的,客户端脚本一点也不弱,现在的ajax技术和Atlas技术就是最好的证明,我们总是期待UI有一个好的效果,flash动画给我们带来了很酷的效果,我们至少也可以为我们的服务器控件添加客户端脚本,一方面减少了服务器端的回传,一方面又能为控件提供非常酷的效果.我想我们都很喜欢ATLAS里面很多很酷的控件吧,而且无刷新,服务器控件与客户端脚本交互使用,那会服务器控件变的更加完美. 经过上面的废话,下面我们进入正题 2.简单为服务器控件添加客户端脚本 我

一起谈.NET技术,asp.net控件开发基础(8)

有一些复合控件直接把按钮触发事件所需的事情封装好,另外一种则是自定义事件,更具灵活性,当然这是根据需要设计的.以下会以例子来说明的.下面我们假设我们控件中有两个按钮.以下不列出所有代码,具体可在文章最后下载代码. (1) 直接实现按钮事件 在控件中(以下代码并非实现复合控件)直接实现事件则无需自定义事件,如下代码(如果对数据回传有些不熟悉的话,可先看第三篇,希望对你有帮助) 示例一(只列出局部代码,具体可在文章最后下载代码) void IPostBackEventHandler.RaisePos

一起谈.NET技术,asp.net控件开发基础(2)

或许大家还对为何要重写Render方法存有疑惑,希望大家看看我举的例子,能够明白Render方法和其他两个方法的作用,然后真正明白为何一般情况下只须重写Render方法.我们知道我们每次编写控件时,都需要重写Render方法,我们发现在Control类中很多方法可以重写,但我们没有去重写他们,我们需要遵循一个原则,在需要重载的时候再去重写他们 我们还是先来看看与Render方法相关的两个方法 //RenderControl方法的基本实现 public void RenderControl(Htm

一起谈.NET技术,asp.net控件开发基础(22)

上两篇讨论了如何定义结合数据源控件的数据绑定控件.这次我们一起来看下数据源控件是如何实现的.asp.net2.0已经为我们提供了很多数据源控件,相信大家都用过了,也希望大家对其有所熟悉.关于它能做什么就不说了.下面我们也一起来看看,如何简单的实现. 一.你必须了解的 1.关于数据源控件(DataSourceControl) 虽然表面看来,给数据绑定控件指定DataSourceID属性,数据源控件帮你做了一切工作,其实不然,数据源控件只负责收集与数据交互的相关信息,如:SqlDataSource的

一起谈.NET技术,asp.net控件开发基础(18)

本篇继续上篇的讨论,可能大家已经在使用asp.net2.0了,DataSource属性不再使用,而是跟数据源控件搭配使用.现在讨论的绑定技术都是基于1.1版本,先熟悉一下,本质上是一样的,这样一步步的学习.对以后绝对有帮助.因为当你使用数据源控件,只需要设置一个DataSourceID,方便的同时你是否知道数据源控件帮你做了什么事情,如果你想觉的够用了,可以不用了解,但我相信你一定会有需求.上篇最后说过了,讨论还刚刚开始,我们大致把核心的方法都写出来了.下面我们继续. 一.控件对比 我们可以使用

一起谈.NET技术,asp.net控件开发基础(17)

本篇将开始介绍如自定义数据绑定控件,这里感谢很多人的支持,有你们的支持很高兴.这里首先需要大家熟悉asp.net模板控件的使用,还有自定义模板控件.因为数据绑定控件多是基于模板控件的. 一.回顾 如果你使用过asp.net内置的数据控件(如DataList,Repeater),你一定会这么做 1.设置数据源 DataSource属性 2.调用数据绑定  DataBind方法 3.在控件的不同模板内使用绑定语法显示数据 这三步应该是必须要做的 其他更多的 你可能需要对绑定的数据进行统一的一些操作(

一起谈.NET技术,asp.net控件开发基础(10)

集合属性相信大家都很熟悉也很常用,如DropDownList,ListBox等控件 <asp:DropDownList ID="DropDownList1" runat="server">            <asp:ListItem>测试1</asp:ListItem>            <asp:ListItem>测试2</asp:ListItem>            <asp:Lis

一起谈.NET技术,asp.net控件开发基础(3)

本次来介绍控件的事件处理. 我们知道Button控件有OnClick事件,DropDownList控件有SelectedIndexChanged事件. 一.回发事件和客户端回发 下面来看一个最简单的例子,按钮单击事件 protected void Button1_Click(object sender, EventArgs e)2 {3 Label1.Text = "你好: "+TextBox1.Text;4 } 大家知道Web 服务器控件创建的按钮的类型有三种 1.Button 2.

一起谈.NET技术,asp.net控件开发基础(1)

asp.net本身提供了很多控件,提供给我们这些比较懒惰的人使用,我认为控件的作用就在此,因为我们不想重复工作,所以要创建它,这个本身便是一个需求的关系,所以学习控件开发很有意思. wrox网站上有本书 Professional ASP.NET 2.0 Server Control and Component Development,现在还没有出版,但网站上放出了代码,所以正好下载过来学习一下. 我看过前几章代码,环环相扣,作者用不同的知识向我们展示同一个效果,所以循序渐进的学下来很有好处.虽然