背景
昨天,我提供了一个例子来完成FieldTemplate的扩展,《如何在Dynamic Data Framework下实现Lookup字段下拉列表》,使得我们能够随心所欲来在不同的模式(List、Edit、Detail、Insert等)下显示一个类型的字段。其中一个关键的属性(Attribute)叫做UIHint,通过它来引向我们自定义的Template并能够传递一些辅助的参数。无疑,利用Metadata,我们能够方便定义Dynamic Data的显示效果,利用System.ComponentModel.DataAnnotations中提供的属性能够完成大部分的定制工作,如DisplayFormat、ScaffoldColumn等等,该类库提供了以下属性:
但是,程序的要求永远是多变的,是无法满足的。比如我们需要将一个数据库的某些字段不显示在列表中,而显示在编辑和详细的UI中,我们利用提供的Scaffold没法完成这个效果。Scaffold只能控制所有页面。
解决方案
我们先扩展一个属性类SamDisplayModeAttribute
Code
/// <summary>
/// display the column in which page
/// </summary>
[Flags]public enum SamDisplayMode{
SDM_LIST=0x01,
SDM_DETAIL=0x02,
SDM_INSERT=0x04,
SDM_EDIT=0x08,
}
public class SamDisplayModeAttribute:Attribute
{
public SamDisplayMode Mode { get; set; }
public SamDisplayModeAttribute(SamDisplayMode mode)
{
Mode = mode;
}
public SamDisplayModeAttribute()
{
Mode = SamDisplayMode.SDM_LIST | SamDisplayMode.SDM_DETAIL | SamDisplayMode.SDM_INSERT | SamDisplayMode.SDM_EDIT;
}
}
这样我们就可以在Metadata中来定义该属性:
Code
[MetadataType(typeof(aspnet_ModuleMetadata))]
public partial class aspnet_Module
{
}
[DisplayName("功能模块")]
public class aspnet_ModuleMetadata
{
[DisplayName("模块名称")]
public string ModuleName { get; set; }
[DisplayName("显示文字")]
[SamJavascript("onclick","javascript:alert('Just test!')")]
public string DisplayName { get; set; }
[DisplayName("链接地址")]
public string Url { get; set; }
[DisplayName("描述")]
[SamDisplayMode(SamDisplayMode.SDM_DETAIL|SamDisplayMode.SDM_EDIT)]
public string Description { get; set; }
[DisplayName("创建时间")]
[SamDisplayMode(SamDisplayMode.SDM_LIST)]
public DateTime CreatedTime { get; set; }
[DisplayName("创建人")]
[UIHint("SamEnumeration", null, "TableName", "aspnet_Users","LookupField","UserId","ResultField","UserName")]
public Guid CreatedBy { get; set; }
}
这一行
[SamDisplayMode(SamDisplayMode.SDM_DETAIL|SamDisplayMode.SDM_EDIT)]
表明该字段将出现在Detail页面和Edit页面,而不会出现在List中。效果如下:
这样我们就能集中在Metadata中来定义,而不是为每个对象(Table)定义很多CustomPages
我们现在就是要能够识别SamDisplayMode并能够作用在不同模式(Mode)的Page中即可。为此我们修改每一个Page Template。
下面以Edit.aspx页面为例,来更改。
Edit.aspx.cs
Code
protected void Page_Load(object sender, EventArgs e)
{
table = DetailsDataSource.GetTable();
foreach (MetaColumn column in table.Columns)
{
SamDisplayModeAttribute dispmode = column.Attributes.OfType<SamDisplayModeAttribute>().FirstOrDefault();
if (dispmode != null)
{
column.Scaffold = ((dispmode.Mode & SamDisplayMode.SDM_EDIT) == SamDisplayMode.SDM_EDIT);
}
}
Title = table.DisplayName;
}
这样,能够按照我们定制,在相应的页面显示适当的字段。更重要的是,我们打开了一扇大门,能够让我们体验更多自由控制的快感!