编写者
日期
关键词
郑昀@ultrapower
2005-8-18
wap asp.net mobile control device adapter
现有的mobile.list输出效果,每一个item之间一定会换行,如果你看了wmllistadapter的源代码就知道了,这是因为他们在输出每一个item渲染时调用了renderlink(writer, item.value, null, false, false, item.text,true);,最后一个参数就是是否在本item渲染后输出换行标记。
我们可以改变这种渲染方式,从而让mobile.list变成横排效果。
现有的mobile.list输出效果,每一个item前后无法插入一张image。
我们可以改变这种渲染方式,从而让mobile.list变成可以自定义每一行的插入图片效果。
总的效果如下图所示:
可以参考我的上一篇文章《[wap]编译adapter来自定义mobile control》,http://www.cnblogs.com/zhengyun_ustc/archive/2005/07/28/customcuildyourmobilecontrol.html。
下面,我们来介绍一下步骤:
在这里我们新建一个类库项目,叫做“listadapter”,它将生成一个listadapter.dll,我们的自定义控件以及adapter就在这个dll中。
在这个项目中,我们将定义一个继承自
system.web.ui.mobilecontrols.adapters.wmllistadapter
的adapter,来准备改写mobile:list控件的输出方式。
将下面的代码保存为listadapter.cs:
<b>listadapter.cs</b><b></b>
using system.web.ui;
using system.web.ui.mobilecontrols.adapters;
using system.web.ui.mobilecontrols;
namespace ultrawmladapter
{
public class imagelist : system.web.ui.mobilecontrols.list
{
private string _img="";
public string image
{
get{ return this._img; }
set{ this._img=value; }
}
}
public class wmlimglistadapter :system.web.ui.mobilecontrols.adapters.wmllistadapter
{
protected new imagelist control
get
{
return (imagelist)base.control;
}
public override void render(
wmlmobiletextwriter writer)
log.debugtrace("imglistadapter render begin:"
+ this.control.uniqueid);
if(control.hascontrols())
writer.begincustommarkup();
renderchildren(writer);
writer.endcustommarkup();
return;
int pagestart = control.firstvisibleitemindex;
int pagesize = control.visibleitemcount;
if (pagesize == 0)
/*
* 我们在上面自定义了image属性,那么这里我们可以通过control.image来获取它,
* 在aspx页面上,它可能是这么定义的,<cc1:imagelist image="images/5.gif" ></cc1:imagelist>;
* 这样,我们就可以直接通过control.image获取字符串"images/5.gif"。
* zhengyun_ustc 20050819
*
*/
string strlistimageurl = (string)control.image;
if(strlistimageurl != null
&& strlistimageurl.length > 0)
writer.writebegintag("img");
writer.writeattribute("src", strlistimageurl);
writer.writeline(" />");
system.web.ui.mobilecontrols.mobilelistitemcollection items = control.items;
if (items.count == 0)
bool itemsaslinks = control.itemsaslinks;
bool hascmdhandler = control.hasitemcommandhandler;
writer.enterstyle(style);
for (int i = 0; i < pagesize; i++)
system.web.ui.mobilecontrols.mobilelistitem item = items[pagestart + i];
/*
* 请注意这里不能用breakafter的名字作为本item的customattributes,
* 因为好像和原先的breakafter冲突;所以这里的customattributes名字最好都起一个
* 比较特殊的,不与原先mobile:list的属性们冲突!
string strbreakafter = (string)item.customattributes["breakafteritem"];
// 默认都换行!
bool bbreakafteritem = true;
if(strbreakafter != null
&& strbreakafter.length > 0)
{
strbreakafter = strbreakafter.tolower();
switch(strbreakafter)
{
case "false":
// 要求渲染时不换行
bbreakafteritem = false;
break;
default:
}
}
if (itemsaslinks)
renderlink(writer, item.value, null, false, false, item.text, bbreakafteritem);
else if (hascmdhandler)
renderpostbackevent(writer, item.index.tostring(), null,true, item.text, bbreakafteritem);
else
writer.rendertext(item.text, bbreakafteritem);
* 我们知道mobilelistitem有一个customattributes成员,它
* “returns the set of custom attributes defined for the control.”
* 也就是说我们通过"item.customattributes",可以得到当前这个control的自定义属性的集合;
* 这样如果我们这样定义list的某一个item:
* <item text="1" value="1" image="images/2.png" breakafteritem="true"></item>
* 那么可以通过item.customattributes["image"]获取image属性的值;
string strcurrentlistitemimageurl = (string)item.customattributes["image"];
if(strcurrentlistitemimageurl != null
&& strcurrentlistitemimageurl.length > 0)
writer.writebegintag("img");
writer.writeattribute("src", strcurrentlistitemimageurl);
writer.writeline(" />");
writer.exitstyle(style);
log.debugtrace("imglistadapter render end");
做一个说明,我们的imagelist类是从system.web.ui.mobilecontrols.list继承下来的,增加了一个image属性作准备。
另外,自定义的wmlimglistadapter就是继承了
system.web.ui.mobilecontrols.adapters.wmllistadapter,所以我们要重写
render(wmlmobiletextwriter writer)函数,从而让它做到下面两件事情:
通过
<b>web.config</b><b>中的</b><b>system.web</b><b>节点下</b><b></b>
来获取在aspx页面上定义的list自定义属性。这里的知识点就是,你可以在aspx中这么定义<cc1:imagelist id="newlist1" runat="server" image="images/5.gif" >,那么直接就可以通过control.image来获取这个“images/5.gif”字符串。这是当前list控件总的image图片显示。
我们还可以通过在每一个item商定以自定义属性image来在list的每一项后面都输出一张图片。
string strcurrentlistitemimageurl = (string)item.customattributes["image"];
这里的知识点是,mobilelistitem有一个customattributes成员,它代表“returns the set of custom attributes defined for the control.”。也就是说我们通过"item.customattributes",可以得到当前这个control的自定义属性的集合。
所以,如果我们这样定义list的某一个item:
<item text="1" value="1" image="images/2.png" breakafteritem="true"></item>
那么可以通过item.customattributes["image"]获取image属性的值了。
编译出一个listadapter.dll,并设置输出路径为你的wap应用程序bin目录下。
在你的wap项目中,添加对lisadapter.dll的引用。
或者你也可以修改web.config,添加如下配置,也能起到相同的作用:
<!-- 动态调试编译
设置 compilation debug="true" 以启用 aspx 调试。否则,将此值设置为
false 将提高此应用程序的运行时性能。
设置 compilation debug="true" 以将调试符号(.pdb 信息)
插入到编译页中。因为这将创建执行起来
较慢的大文件,所以应该只在调试时将此值设置为 true,而在所有其他时候都设置为
false。有关更多信息,请参考有关
调试 asp.net 文件的文档。
-->
<compilation defaultlanguage="c#" debug="true">
<assemblies>
<add assembly="listadapter"/>
<add assembly="multilineinput"/>
</assemblies>
</compilation>
现在你已经修改了mobile:list控件的最终渲染方式,让我们试试看吧。
新建一个移动web窗体页面“imglist.aspx”,填写如下:
<%@ register tagprefix="mobile" namespace="system.web.ui.mobilecontrols" assembly="system.web.mobile" %>
<%@ page language="c#" codebehind="imglist.aspx.cs"
inherits="ipower.imglist" autoeventwireup="false" %>
<%@ register tagprefix="cc1" namespace="ultrawmladapter" assembly="listadapter" %>
<head>
<meta content="microsoft visual studio .net 7.1" name="generator">
<meta content="c#" name="code_language">
<meta content="http://schemas.microsoft.com/mobile/page" name="vs_targetschema">
</head>
<body xmlns:mobile="http://schemas.microsoft.com/mobile/webform">
<mobile:form id="form1" title="wap测试imagelist控件" runat="server">
<cc1:imagelist id="newlist1" runat="server" itemsperpage="0" itemsaslinks="true" breakafter="false"
stylereference="title" enableviewstate="false"image="images/5.gif" >
<item text="1" value="1" image="images/1.png" breakafteritem="true"></item>
<item text="2" value="2" image="images/2.png" breakafteritem="false"></item>
<item text="3" value="3" image="images/3.png" breakafteritem="false"></item>
<item text="4" value="4" image="images/5.gif" breakafteritem="false"></item>
<item text="5" value="5" image="images/1.png" breakafteritem="true"></item>
</cc1:imagelist>
<mobile:textbox id="input1" runat="server" name="ti" rows="5" cols="25"></mobile:textbox>
<mobile:command id="cmdadditem" runat="server">添加一个item</mobile:command>
</mobile:form>
</body>
记得在你的wap项目下,建立一个images目录,并放置图片。
编辑mobile:command的click事件,添加如下代码:
newlist1.items.add(input1.text);
newlist1.items[5].customattributes["image"] = "images//additem.png";
这时候,程序依然无法运行,我们必须修改web.config来告知如何应用我们的自定义imagelist以及adapter。
在你的web.config文件中找到mobilecontrols节点,修改为以下:
<!-- 指定没有 cookie 的数据字典类型
这将使字典的内容出现在本地请求 url 查询字符串中。
这是在没有 cookie 的设备上进行窗体身份验证所必需的。
<!--在您使用像 userandomid 这样的自定义属性时,必须在您的移动 web 应用程序中启用自定义属性allowcustomattributes。
<mobilecontrols allowcustomattributes="true"cookielessdatadictionarytype="system.web.mobile.cookielessdata" >
<device name="ultrawmldeviceadapters" inheritsfrom="wmldeviceadapters">
<b><control name="ultrawmladapter.imagelist,listadapter"</b>
<b> </b><b>adapter</b><b>="ultrawmladapter.wmlimglistadapter,listadapter"</b><b> </b><b>/></b><b></b>
</device>
</mobilecontrols>
device节点就声明了一个新的adapter,名为“ultrawmldeviceadapters”,这个名字是可以随便定义的。
以后你每增加一个自定义adapter,都必须在这个device节点之下加入一个control,你必须通过name属性提供控件的fully qualified control class name:“<b>ultrawmladapter.imagelist,listadapter</b>”,control的name属性指的是“你重载的哪一个mobile控件”,然后<b>adapter</b>属性指出如何渲染。
这样,重新编译你的工程后,新的渲染方式就生效了。
你可以在m3gate模拟器/opera7.6上试验。
2005-8-19