界面截图
点击左侧“日志管理”,在右侧IFrame中载入./admin/log.aspx:
选择错误级别即更新Grid:
在TwinTriggerBox中输入需要查询的关键词,回车或点击查询按钮,则更新Grid,同时显示搜索按钮前面的取消搜索按钮:
AppBox不仅仅是功能的实现
AppBox不仅仅是使用ExtAspNet来完成某项功能,我们还融入了很多用户易用性方面的考虑,
比如外面的Panel和里面Panel的间距,Form中控件距离右侧的距离,对话框在父页面弹出,表单已经修改提醒等等。
最终呈现在用户面前的是一个近乎完美的页面,这也是我们的追求。
细心的读者可能会发现这个常见的列表页面居然没有“查询”按钮,甚至连开始时间和结束时间也浓缩到一个下拉列表中:
这里面有一些设计查询条件时的考虑:
1. 查询条件要尽量浓缩,只保留最常用的,以一行查询条件为最佳(不超过4个)。
2. 如果需要在多个字段中查询关键字,可以在TwinTriggerBox通过(在字段一或者字段二中查询)的方式来实现。
3. 一般只能以TwinTriggerBox和DropDownList(AutoPostback)形式存在的查询条件,不出现“查询”按钮。
上面的设计原则应该可以覆盖80%的应用场景,并且这样的设计不仅可以保持页面的清爽,而且方便了用户操作。
布局,漂亮的布局
一个恰当的布局能够使你的页面美观大方,可以适应窗口的大小变化,并且不会出现指定像素数导致的1px或者2px的空白。
先省略到其他标签定义,只关注布局的定义:
<ext:PageManager ID="PageManager1" AutoSizePanelID="Panel1" runat="server" />
<ext:Panel ID="Panel1" runat="server" BodyPadding="5px" EnableLargeHeader="false"
EnableBackgroundColor="true" ShowBorder="false" Layout="Anchor" ShowHeader="true"
Title="日志管理">
<Items>
<ext:Form ID="Form2" runat="server" Height="36px" BodyPadding="5px" ShowHeader="false"
ShowBorder="false" EnableBackgroundColor="true">
</ext:Form>
<ext:Grid ID="Grid1" runat="server" AnchorValue="100% -36px" ShowBorder="true" ShowHeader="false"
EnableCheckBoxSelect="true" EnableRowNumber="true" DataKeyNames="Logid" AllowSorting="true"
OnSort="Grid1_Sort" AllowPaging="true" IsDatabasePaging="true" OnPageIndexChange="Grid1_PageIndexChange">
</ext:Grid>
</Items>
</ext:Panel>
简单来看,就是外层一个Panel,里面两个Panel(一个Form,一个Grid),
然后在外层指定Layout="Anchor",为Grid指定AnchorValue="100% -36px"(意思是Grid宽度100%,距离下边界36px):
再设定Form的高度为36px,相应的Grid就被挤下去了,形成了如下的布局:
这个就是Anchor布局的含义,很多开发人员在使用ExtAspNet一段时间后还是没弄明白Anchor的意思,不知道这两个丑丑的手绘图是否能让你明白,呵呵。
为什么是36px呢?为什么不是37呢?
这是很多人想问的问题对吧,为什么那个Form要设置高度为36px呢?我说出原因,大家不要吐哦
...
...
...
...
...
...
...
...
那是因为我计算出来的$#%……%@&¥#%#¥@%&……%……
首先我拿Firebug测量Form每行的高度是26px,再加上面和下面5px的内边距,就得到:
26px + 5px + 5px = 36px
虽然这不是一种好办法,不过至少目前能工作,就先这样了。等我想到好的办法再告诉大家。
Form标签的定义
<ext:Form ID="Form2" runat="server" Height="36px" BodyPadding="5px" ShowHeader="false"
ShowBorder="false" EnableBackgroundColor="true">
<Rows>
<ext:FormRow ID="FormRow1" runat="server">
<Items>
<ext:TwinTriggerBox ID="ttbSearchMessage" runat="server" ShowLabel="false" EmptyText="在错误信息中搜索"
Trigger1Icon="Clear" Trigger2Icon="Search" ShowTrigger1="false" OnTrigger2Click="ttbSearchMessage_Trigger2Click"
OnTrigger1Click="ttbSearchMessage_Trigger1Click">
</ext:TwinTriggerBox>
<ext:DropDownList ID="ddlSearchLevel" runat="server" Label="错误级别" AutoPostBack="true"
OnSelectedIndexChanged="ddlSearchLevel_SelectedIndexChanged">
<ext:ListItem Text="全部" Value="ALL" Selected="true" />
<ext:ListItem Text="INFO" Value="INFO" />
<ext:ListItem Text="DEBUG" Value="DEBUG" />
<ext:ListItem Text="WARN" Value="WARN" />
<ext:ListItem Text="ERROR" Value="ERROR" />
<ext:ListItem Text="FATAL" Value="FATAL" />
</ext:DropDownList>
<ext:DropDownList ID="ddlSearchRange" runat="server" Label="搜索范围" AutoPostBack="true"
OnSelectedIndexChanged="ddlSearchRange_SelectedIndexChanged">
<ext:ListItem Text="全部" Value="ALL" />
<ext:ListItem Text="今天" Value="TODAY" Selected="true" />
<ext:ListItem Text="最近三天" Value="LAST3DAYS" />
<ext:ListItem Text="最近七天" Value="LAST7DAYS" />
<ext:ListItem Text="最近一个月" Value="LASTMONTH" />
<ext:ListItem Text="最近一年" Value="LASTYEAR" />
</ext:DropDownList>
</Items>
</ext:FormRow>
</Rows>
</ext:Form>
两个DropDownList都很好理解了,我们来重点看看TwinTriggerBox。
顾名思义,TwinTriggerBox就是有两个(Twin)Trigger的TextBox,我们需要手工指定这两个Trigger分别是什么图标Trigger1Icon="Clear" Trigger2Icon="Search"。
默认不显示第一个Trigger - ShowTrigger1="false",同时注册两个Trigger的点击处理函数。
事件处理函数
protected void ttbSearchMessage_Trigger2Click(object sender, EventArgs e)
{
ttbSearchMessage.ShowTrigger1 = true;
BindGrid();
}
protected void ttbSearchMessage_Trigger1Click(object sender, EventArgs e)
{
ttbSearchMessage.Text = String.Empty;
ttbSearchMessage.ShowTrigger1 = false;
BindGrid();
}
protected void ddlSearchLevel_SelectedIndexChanged(object sender, EventArgs e)
{
BindGrid();
}
protected void ddlSearchRange_SelectedIndexChanged(object sender, EventArgs e)
{
BindGrid();
}
其实也很简单了,点击Trigger2时显示Trigger1,通过查询数据绑定Grid。
点击Trigger1时(也即是清空查询条件),隐藏Trigger1,同时情况此TwinTriggerBox的文本框,并查询数据绑定Grid。
下一章,我们会继续介绍日志管理模块,主要是Grid的数据库分页,排序,批量删除,查看等功能(同时你将感受到SubSonic的强大)。
下载全部源代码