求解用户自定义控件中的Repeater加载ascx模版参数传递问题

lzeasy 2009-10-04 01:31:36
我在aspx页面中加载了一个用户自定义控件,此控件中只有一个Repeater控件并且加载了一个ItemTemplate模版,在这个模版中需要接收一个参数

aspx页面代码
<uc1:myuc ID="myuc1" runat="server" ColumnId="22" IT_Path="Template/itemplate.ascx" StrLength="36" />
这里的StrLength是在用户自定义控件中定义的,代码如下
public int StrLength
{
get
{
object o = ViewState["StrLength"];
if (o != null)
return Convert.ToInt32(o);
else
return 0;
}
set
{
ViewState["StrLength"] = value;
}
}
在用户自定义控件中我又加载了模版文件
myuc1.ItemTemplate = Page.LoadTemplate(IT_Path);

模版文件代码:
<a href=""><%# Stringval.CutString(Eval("Title").ToString(), StrLength)%></a>

这里要将文本截短,StrLength为保留的字数,我应该怎么把apsx上定义的值传过来呢?
恳请高手指教,不胜感谢!!!

...全文
336 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
lzeasy 2009-10-05
  • 打赏
  • 举报
回复
void c_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
ITemplateAscx c = e.Item.Controls[0] as ITemplateAscx;
if (c != null)
{
c.Param1 = (string)DataBinder.Eval(e.Item.DataItem, "url");
c.Param2 = (int)DataBinder.Eval(e.Item.DataItem, "Age");
c.StrLength=this.StrLength;
}
}
仔细想了想,这样写也是可行的,脑子没转过来,把所有数据都绑定了(我原来只考虑到前模版显示了什么),这样就不用管前台模版要显示什么的问题了。呵呵,想得太复杂了。回去再试试。
问题解决,结帖吧。再次谢谢sp1234!!!
24K純帥 2009-10-05
  • 打赏
  • 举报
回复
学习SP1234大哥。。
  • 打赏
  • 举报
回复
“但是这样会不会导致性能或效率上的问题或是其他问题呢?”

我觉得这类问题根本不用不断提,你自己觉得呢?实在忧心忡忡,你就可以写个测试,看看多一个属性赋值操作并且重复10万次,会不会使用哪怕是0.5秒钟?而这不足每一次处理不足1毫秒的耽误会让你的客户因此在业务处理时损失1毛钱吗?这类问题自己做测试,并且换算金钱,就可以自己评判了。
  • 打赏
  • 举报
回复
为你的ascx模板控件增加StrLength --> 为你的ascx模板控件的数据接口增加StrLength属性

“因为我需要绑定不同的数据,所以不好处理”实在是不懂你的意思。难道你使用Repeater不是绑定不同数据?实在费解你的意思。
  • 打赏
  • 举报
回复
没有仔细看你上面两楼的,因为我感觉有些东西似乎是显而易见的。

void c_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
ITemplateAscx c = e.Item.Controls[0] as ITemplateAscx;
if (c != null)
{
c.Param1 = (string)DataBinder.Eval(e.Item.DataItem, "url");
c.Param2 = (int)DataBinder.Eval(e.Item.DataItem, "Age");
c.StrLength=this.StrLength;
}
}

为你的ascx模板控件增加StrLength,然后你的自定义控件把自己的StrLength传递给ascx。这有什么难的吗?

而如果你说数据绑定不适合你,那么你为什么说在你的自定义控件中使用Repeater并且将ascx模板作为它的ItemTemplate?这是非常小心地按照你的做法而避免了画蛇添足的,如果不适合你,那么大概你的最初的设计描述就根本是错的,这样我就根本不可能知道什么设计是对的。
lzeasy 2009-10-04
  • 打赏
  • 举报
回复
呃,用了个蠢方法,在Hel类库中,定义了一个属性,然后在用户控件中给这个属性赋值,就可以在模版中使用了(<%# Hel.Stringval.CutString(Eval("Title").ToString(), Hel.PublicVal.StringLeght)%></a>)。但是这样会不会导致性能或效率上的问题或是其他问题呢?
lzeasy 2009-10-04
  • 打赏
  • 举报
回复
谢谢sp1234和wuyq11的热心帮助。
我是想做一个列出新闻标题的用户控件,在aspx页面上调用这个控件,因为想做得更通用些,所以又使用了ItemTemplate模版。这样我就可以显示不同的数据和样式了。比如同一页面中一个只显示标题,另一个还需要显示日期,这样我只用注册一个用户控件就能在不同的场合下使用了。现在唯一困扰我的问题就是模版中我需要对标题进行截断,考虑到不同样式下,要保留的字数也不一样,因此我是这么写的<%# Stringval.CutString(Eval("Title").ToString(), StrLength)%>,这个写法我在不使用模版的情况下,通过
public int StrLength
{
get
{
object o = ViewState["StrLength"];
if (o != null)
return Convert.ToInt32(o);
else
return 0;
}
set
{
ViewState["StrLength"] = value;
}
}
方式就能在aspx页面中用<uc1:myuc ID="myuc1" runat="server" ColumnId="22" IT_Path="Template/itemplate.ascx" StrLength="36" />的方式或是在CS代码中定义来传递参数值给StrLength,但我把<%# Stringval.CutString(Eval("Title").ToString(), StrLength)%>放到模版中时,我就抓瞎了,因为我不知道如何将参数值传给StrLength,这样就不能正确的截断标题字符了。数据绑定是没问题的。我看了一下各位的方法,其中ItemDataBound事件是不符合我的想法的,因为我需要绑定不同的数据,所以不好处理。目前采用加载列模版的方式已经差不多可以了。就是被这字符截断卡住了,要是写死的话<%# Stringval.CutString(Eval("Title").ToString(), 36)%>就意味着因为一个参数值不同,我又得加个模版页。
  不知道这样说清楚吗,还请各位老师前辈多多指教啊。谢谢了。
  • 打赏
  • 举报
回复
this.form1.Controls.Add(c);

这只是设想一个例子,你可能写成

this.PlaceHolder1.Controls.Add(c);

更准确。
  • 打赏
  • 举报
回复
模板之所以使用ascx,目的就是为了灵活编辑、重构,也就是说在你的自动以控件发布之后,使用者还是可能编辑作为模板的ascx。例如可能在模板ascx中有另一个列表;或者使用一个FormView,绑定来的字段信息只是显示在这个FormView中。

所以,在ascx实现数据接口的时候,要尽可能灵活和可靠。例如我们甚至可能容许ascx设计者去删除TextBox1控件(或者设置更清晰的id),等等反射、自动化的处理机制。为作为模板的ascx设计数据接口,就避免了Repeater附近的代码想当然地去处理ascx内部的控件。

如果没有灵活的机制,那么不如直接使用ascx来实现你的自动以控件的功能,并且把Repeater的模板直接声明清楚。使用你的自定义控件方式,如果不能允许作为模板的ascx非常灵活地修改布局,反而不够方便。
  • 打赏
  • 举报
回复
呵呵,只能回复三次,只能等别人回复了再回复。

如果一定要使用LoadTemplate方式,模板之所以ascx制作,你其实并不知道它何时被重构,不知道内部如何实现。所以参数可以采用接口来定义。例如,假设我们定义接口
public interface ITemplateAscx
{
string Param1 { get; set; }

int Param2 { get; set; }
}


然后在ascx中例如这样实现:

public partial class TemplateAscx : System.Web.UI.UserControl, ITemplateAscx
{

public string Param1
{
get
{
EnsureChildControls();
return this.TextBox1.Text;
}
set
{
EnsureChildControls();
this.TextBox1.Text = value;
}
}

public int Param2
{
get
{
EnsureChildControls();
return int.Parse(this.Label1.Text);
}
set
{
EnsureChildControls();
this.Label1.Text = value.ToString();
}
}
}


而在你的自定义控件中就可以这样使用Repeater:
private void BindDatas()
{
var c = new Repeater();
c.ID = "Rpt";
this.form1.Controls.Add(c);
c.ItemTemplate = this.Page.LoadTemplate("~\\TemplateAscx.ascx");
c.ItemDataBound += new RepeaterItemEventHandler(c_ItemDataBound);
c.DataSource = 获取数据()
c.DataBind();
}

void c_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
ITemplateAscx c = e.Item.Controls[0] as ITemplateAscx;
if (c != null)
{
c.Param1 = (string)DataBinder.Eval(e.Item.DataItem, "url");
c.Param2 = (int)DataBinder.Eval(e.Item.DataItem, "Age");
}
}
wuyq11 2009-10-04
  • 打赏
  • 举报
回复
加载模板的方式e.Item只是模板的父级容器,e.Item应该属于模板里面控件的父父级的容器
void Repeater1_ItemDataBound(object sender, DataListItemEventArgs e)
{
Control ctrl = e.Item.Controls[0];
Label lbl = (Label)ctrl.FindControl("lbl");
}
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 sp1234 的回复:]
“模板文件代码”?缺少用户控件的完整定义吧。

作为模板用户控件,你同样可以定义public的属性,例如一个是Title,一个是StrLength。

假设用户控件的后台类型或者其接口命名为 MyIT,就可以在你的用户控件中写:

C# codemyuc1.ItemTemplate= Page.LoadTemplate(IT_Path);
MyIT t=(MyIT)myuc1.ItemTemplate;
t.Title=".....";
t.StrLength=this.StrLength;
er的模板列中直接为模板ascx绑定其属性值,程序设计简洁清晰不少。
[/Quote]

sorry!没有看清是模板列,还以为是动态装载。这里的代码是错误的。

不是在LoadTemplate,而是在为Repeater注册的ItemDataBound事件处理程序中,FindControl找到各个组件,然后手动设置值。我这里的代码错了。sorry。
  • 打赏
  • 举报
回复
哦当然,Repeater的模板列跟你说的模板ascx不是一个概念。使用数据绑定方式,实际上你要把ascx中的代码大部分放到上面的Repeater定义中。

  • 打赏
  • 举报
回复
“模板文件代码”?缺少用户控件的完整定义吧。

作为模板用户控件,你同样可以定义public的属性,例如一个是Title,一个是StrLength。

假设用户控件的后台类型或者其接口命名为 MyIT,就可以在你的用户控件中写:

myuc1.ItemTemplate = Page.LoadTemplate(IT_Path); 
MyIT t=(MyIT)myuc1.ItemTemplate;
t.Title=".....";
t.StrLength=this.StrLength;


顺便说一下,你要写“自定义控件”,那么就很难写Eval绑定表达式了。如果不是必须,你可以把这个恶控件写成ascx,然后这个ascx中有一个Repeater控件,其模板列中直接嵌入你的ascx模板文件,这样就直接可以在Repeater的模板列中直接为模板ascx绑定其属性值,程序设计简洁清晰不少。

110,577

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧