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

  从第八篇的时候跳了很大篇幅来继续讲属性,然后接着讲类型转换器,再接着讲视图状态.绕到现在才接着讲复合控件的样式的使用,因为上面讲的东西是紧密联系的.如果已经理解自定义视图状态管理,那这一篇则看起来相关的简单.

  1.复合控件中样式属性概述

  在第六篇的时候已经介绍过样式的使用了,在复合控件中你同样可以用此方法给控件定义多个样式属性,但此方法很适合像label这样非复合控件。当然复合控件可以适当的定义其自身的样式属性,同时你还需要为其子控件提供样式,典型的控件如GridView控件,如下图

  它有很多不同种类的列,而每种不同的列则有不同的样式集合属性,如果将其每个样式属性均暴露为顶级属性,那样式属性将变得很混乱。我们可以用此方法为复合控件的子控件定义样式,实现每个子控件对应Style类型的复杂样式属性,将样式属性暴露为复合控件的顶级属性,这样更容易管理复合控件样式属性。

  2.复合控件中样式属性实现(为子控件提供样式)

  Style类本身继承IStateManager 接口,并实现了接口方法.在第五篇我们曾重写CreateControlStyle方法,如下

        protected override Style CreateControlStyle()
        {

            return new Style(ViewState);
        }

其初始化的时候即存储样式信息在视图状态中,而其自定义的样式的状态管理机制则跟上一篇非常的相似.你需要重写Control类的状态管理的几个方法来实现样式的状态管理.还是以登录控件为例.


  (1)先自定义样式集合属性

  定义方法跟上一篇视图状态中的Address属性很相似

  如下代码


#region 样式属性
[
Category("Styles"),
DefaultValue(null),
DesignerSerializationVisibility(
DesignerSerializationVisibility.Content),
PersistenceMode(PersistenceMode.InnerProperty),
Description(
"应用于按钮的样式")
]
public virtual Style ButtonStyle
{
get
{
if (_buttonStyle == null)
{
_buttonStyle = new Style();
if (IsTrackingViewState)
{
((IStateManager)_buttonStyle).TrackViewState();
}
}
return _buttonStyle;
}
}

[
Category("Styles"),
DefaultValue(null),
DesignerSerializationVisibility(
DesignerSerializationVisibility.Content),
PersistenceMode(PersistenceMode.InnerProperty),
Description(
"应用于文本框的样式")
]
public virtual Style TextBoxStyle
{
get
{
if (_textBoxStyle == null)
{
_textBoxStyle = new Style();
if (IsTrackingViewState)
{
((IStateManager)_textBoxStyle).TrackViewState();
}
}
return _textBoxStyle;
}
}
#endregion

  (2)自定义视图状态管理

 

  因为此处定义了两个样式集合属性,所以用到了Triplet这个辅助类,其跟Pair类一样都是辅助类,而其可以存储三个相关对象的基本结构.如果你要储存三个以上就不能用这两个辅助类了,实现方法还是很简单的.

如下代码


#region 自定义视图状态
protected override void LoadViewState(object savedState)
{
if (savedState == null)
{
base.LoadViewState(null);
return;
}
else
{
Triplet t = savedState as Triplet;

if (t != null)
{
base.LoadViewState(t.First);

if ((t.Second) != null)
{
((IStateManager)ButtonStyle).LoadViewState(t.Second);
}

if ((t.Third) != null)
{
((IStateManager)TextBoxStyle).LoadViewState(t.Third);
}
}
else
{
throw new ArgumentException("Invalid view state .");
}
}
}

protected override object SaveViewState()
{
object baseState = base.SaveViewState();
object buttonStyleState = null;
object textBoxStyleState = null;

if (_buttonStyle != null)
{
buttonStyleState =
((IStateManager)_buttonStyle).SaveViewState();
}

if (_textBoxStyle != null)
{
textBoxStyleState =
((IStateManager)_textBoxStyle).SaveViewState();
}

return new Triplet(baseState,
buttonStyleState, textBoxStyleState);

}

protected override void TrackViewState()
{
base.TrackViewState();
if (_buttonStyle != null)
{
((IStateManager)_buttonStyle).TrackViewState();
}
if (_textBoxStyle != null)
{
((IStateManager)_textBoxStyle).TrackViewState();
}
}
#endregion

  (3)为子控件添加样式集合属性

  上面工作做好后,然后你就可以在呈现方法Render方法或RenderContent方法中为子控件添加样式集合属性,如下代码

if (_buttonStyle != null)
            {
                submitButton.ApplyStyle(ButtonStyle);
            }

            if (_textBoxStyle != null)
            {
                nameTextBox.ApplyStyle(TextBoxStyle);
                emailTextBox.ApplyStyle(TextBoxStyle);
            }

来看一下效果,属性面板已经有子控件样式集合属性了,这样就更容易管理样式了.

  定义子控件样式就这么的简单,主要难点还是在于自定义视图状态管理,对自定义视图状态管理熟悉的话,看到这里肯定很简单,如果没看明白就须先弄懂如何自定义视图状态管理

  注意点:asp.net2.0中复合控件可以直接继承CompositeControl类即可,大家可以了解一下此类

  本文的示例代码来自MSDN2005中的代码。

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

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

时间: 2024-10-29 19:56:29

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

ASP.NET控件开发基础(12)

上一篇讨论了视图状态的用法,让我们再回到第八篇的时候.从第八篇的时候跳了很大篇幅来继续讲属性,然后接着讲类型转换器,再接着讲视图状态.绕到现在才接着讲复合控件的样式的使用,因为上面讲的东西是紧密联系的.如果已经理解自定义视图状态管理,那这一篇则看起来相关的简单. 1.复合控件中样式属性概述 在第六篇的时候已经介绍过样式的使用了,在复合控件中你同样可以用此方法给控件定义多个样式属性,但此方法很适合像label这样非复合控件. 当然复合控件可以适当的定义其自身的样式属性,同时你还需要为其子控件提供样

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

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

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

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

一起谈.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