如何创建模拟 switch/case 的 ASP.NET 控件?
我有一个中继器循环遍历不同类型的对象列表。我想根据对象的类型以不同的方式渲染它们。为此,我需要某种具有类似于 switch/case 语句行为的控制(因为我想避免使用隐藏代码)。基本上它可能看起来像这样:
<xxx:TestType Object='<%# Container.DataItem %>'>
<Case Type="Namespace.ClassX">
<asp:Label ... />
</Case>
<Case Type="Namespace.ClassY">
<asp:TextBox ... />
</Case>
<Default>
<p>Other</p>
</Default>
</xxx:TestType>
我以前制作过 Web 控件,但这是一个相当复杂的控件...
- 如何使其支持多个
元素? - 是否可以实现
元素,或者我是否仅限于无属性元素?
我猜我必须为
元素创建一个类型,并以某种方式为主 Web 控件指定它?
如果有任何指示、教程链接等,我将不胜感激!
替代方案
或者,建议一种更好的方法来根据当前绑定对象的类型呈现不同的 HTML/ASP.NET 控件。我脑海中闪现的第一个方法是这个,我认为它(非常)丑陋:
<asp:PlaceHolder Visible='<%# CheckType(Container, typeof(ClassX)) %>' runat="server">
...
</asp:PlaceHolder>
<asp:PlaceHolder Visible='<%# CheckType(Container, typeof(ClassY)) %>' runat="server">
...
</asp:PlaceHolder>
I've got a repeater looping through a list of objects that are of different types. I'd like to render the objects differently depending on their type. For this I need some kind of control (since I want to avoid using the code-behind) that has a behavior similar to a switch/case statement. Basically it could look like this:
<xxx:TestType Object='<%# Container.DataItem %>'>
<Case Type="Namespace.ClassX">
<asp:Label ... />
</Case>
<Case Type="Namespace.ClassY">
<asp:TextBox ... />
</Case>
<Default>
<p>Other</p>
</Default>
</xxx:TestType>
I've made web controls before, but this is a rather complex one...
- How do I make it support multiple
<Case>
elements? - Is it possible to implement the
<Case Type="...">
elements, or am I limited to attribute-less elements?
I'm guessing I have to make a type for the <Case>
elements and somehow specifying it for the main web control?
I'd be grateful for any pointers, links to tutorials, etc!
Alternative
Alternatively, suggest a nicer way of rendering different HTML/ASP.NET controls based on the type of the currently bound object. The first method that popped into my head was this, which I consider (very) ugly:
<asp:PlaceHolder Visible='<%# CheckType(Container, typeof(ClassX)) %>' runat="server">
...
</asp:PlaceHolder>
<asp:PlaceHolder Visible='<%# CheckType(Container, typeof(ClassY)) %>' runat="server">
...
</asp:PlaceHolder>
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
MultiView 控件是最接近的ASP.NET 中现成的东西转换为 C# switch 语句。
The MultiView control is the closest thing out-of-the-box in ASP.NET to a C# switch statement.
查看实现 ITemplate 接口
Look at implementing ITemplate interface
为什么不放弃服务器控件并使用 C# switch 语句。您所需要做的就是将其包装在代码标签中。
另一种方法是迭代(for 循环)。创建一个具有类型属性和渲染方法的接口。然后迭代接口,直到找到正确的类型。
Why don't you ditch the server control and use the C# switch statement. All you need is to wrap it in the code tags.
Another approach is a iteration (for loop). Create an interface with a type property and a render method. Then iterate over the interfaces until you've found the correct type.
不久前我有类似的要求,我做了类似的事情:
protected TypedTemplate GetTemplate(object dataItem)
{
如果(数据项==空)
{
返回空值;
}
foreach(模板中的TypedTemplate模板)
{
类型 itemType = dataItem.GetType();
if (dataItem.IsAssignableFrom(template.Type))
{
返回模板;
}
}
返回空值;
其中
TypedTemplateCollection 是 TypedTemplate 类的 StateManagedCollection:
并且 TypedTemplateRepeaterItem 是:
I had a similar requirement a while ago and I did something similar to:
protected TypedTemplate GetTemplate(object dataItem)
{
if (dataItem == null)
{
return null;
}
foreach (TypedTemplate template in Templates)
{
Type itemType = dataItem.GetType();
if (dataItem.IsAssignableFrom(template.Type))
{
return template;
}
}
return null;
}
where TypedTemplateCollection is a StateManagedCollection of a TypedTemplate class:
and TypedTemplateRepeaterItem is:
MSDN 网站有一个简单清晰的模板示例,它看起来确实适合您的情况。
The MSDN site has a simple clear example of templating and it certainly seems like the way to go in your case.