前一段看到Yupoo有个日历相册还不错,很精美,具体地址为http://www.yupoo.com/explore/interesting?year=2008&month=12,看到这个日历效果,自己也想用asp.net日历控件尝尝鲜,那么就动手设计看看。
\n
\n
最终的运行效果为:(可以兼容大多数的浏览器)
\n
\n
图一
\n
点击其中某一天的图片,可以看到:
\n
\n
图二
\n
\n
现在讲讲我的思路:
\n
1. 首先先创建一个数据库,我这里简单起见,建立了一个data.mdb的Access数据库,添加表PhotoInfo,具体的设计视图为:
\n
\n
也是简单起见,PhotoUrl字段作为图片存储路径,PublishDate作为上传时间,这里还可以有其他字段,如用户ID等等,我省略掉了。
\n
\n
打开表后,具体的数据为类似这样的数据;
\n
\n
2. 在Default.aspx页面上添加日历控件
\n
<asp:Calendar ID=”calendar” runat=”server”></asp:Calendar>
运行下结果:
\n
\n
嗯,看起来很简陋的日历控件,现在我加上属性 DayNameFormat=”Full”,DayNameFormat属性还包括FirstLetter,FirstTwoLetters,Short,Shortest,现在再运行一下:
\n
\n
加上属性 BorderWidth=”0″:
\n
\n
日历外框消失了。
\n
加上<TitleStyle CssClass=”day_title” BorderWidth=”0px” BackColor=”White” Width=”700″ />,通过day_title设置样式:
\n
\n
加上<DayStyle Width=”86″ Height=”86″ BorderColor=”#7E7262″ HorizontalAlign=”Left” VerticalAlign=”Top” />,得到图:
\n
\n
设置了每一日中的宽度和高度。
\n3. 在Default.aspx.cs后台代码的Page_Load事件中,首先初始化上一月,下一月的赋值:
\n
DateTime prevMonth = calendar.VisibleDate.AddMonths(-1);
DateTime nextMonth = calendar.VisibleDate.AddMonths(1);
calendar.PrevMonthText = “<a class=np href=\\”Default.aspx?year=” + prevMonth.Year + “&month=” + prevMonth.Month + “\\”><<上个月</a>”;
calendar.NextMonthText = “<a class=np href=\\”Default.aspx?year=” + nextMonth.Year + “&month=” + nextMonth.Month + “\\”>下个月>></a>”;
其中PrevMonthText和NextMonthText属性为上一月,下一月的HTML内容。
\n
4. 现在首先得到一个DataSet数据,以便于绑定到日历控件中。
\n
private void BindData()
{
DateTime firstDate = new DateTime(calendar.VisibleDate.Year, calendar.VisibleDate.Month, 1);
DateTime lastDate = firstDate.AddMonths(1);
\n
FillData(firstDate, lastDate);
}
\n
protected void FillData(DateTime startTime, DateTime endTime)
{
StringBuilder builder = new StringBuilder();
builder.Append(“SELECT PhotoID, PhotoUrl, PublishDate FROM PhotoInfo, “);
builder.Append(“(SELECT FORMAT(PublishDate, ‘yyyy-mm-dd’) AS PDate, MAX(PhotoID) AS PID FROM PhotoInfo “);
builder.Append(“GROUP BY FORMAT(PublishDate, ‘yyyy-mm-dd’)) t1 “);
builder.Append(“WHERE t1.PID=PhotoInfo.PhotoID “);
builder.Append(“AND PublishDate>=#” + startTime + “# AND PublishDate<#” + endTime + “#”); //暂时用连接串来表示
ds = AccessHelper.ExecuteDataSet(builder.ToString());
}
AccessHelper类为了执行SQL语句,返回数据集;这样就可以将某个月份的图片每天的最后一张 查询出来了。
5. 现在这段是实现的重点代码,给日历控件添加一个事件OnDayRender,OnDayRender是在呈现日的时候激发:
\n
protected void calendar_DayRender(object sender, DayRenderEventArgs e)
{
if (e.Day.IsOtherMonth) //当日期不在当前月份中时不显示
{
e.Cell.Controls.Clear();
}
else
{
e.Cell.BorderWidth = 1;
e.Cell.CssClass = “FullDay”;
\n
DateTime nextDate;
Literal ltl = new Literal();
if (ds != null)
{
foreach (DataRow dr in ds.Tables[0].Rows)
{
nextDate = DateTime.Parse(((DateTime)dr["PublishDate"]).ToShortDateString());
\n
if (nextDate == e.Day.Date) //比较每个天是否与当前控件日期相同
{
e.Cell.CssClass = “NotDay”;
\n
ltl.Text = “”;
string mediaPath = dr["PhotoUrl"].ToString();
mediaPath = ResolveUrl(“~/”) + “images/” + dr["PhotoUrl"].ToString();
ltl.Text = “<a class=date href=\\”javascript:void(0);\\”><IMG onclick=\\”ShowPhotos(this, ‘” + nextDate.ToShortDateString() + “‘);\\”class=\\”Thumb\\” src=” + mediaPath + ” width=\\”82\\” height=\\”80\\” /></A>”;
}
}
}
ltl.Text += “<DIV class=\\”BlackDate\\”>” + e.Day.Date.Day + “</DIV>”;
ltl.Text += e.Day.Date == calendar.TodaysDate ? “<DIV class=\\”RedDate\\”>” + e.Day.Date.Day + “</DIV>” : “<DIV class=\\”WhiteDate\\”>” + e.Day.Date.Day + “</DIV>”;
e.Cell.Controls.Add(ltl);
}
}
\n
增加相应的CSS代码:
\n
style.css
.day
{
padding-right: 5px;
padding-left: 5px;
padding-bottom: 5px;
margin: 0px;
font: bold 14px arial, helvetica, sans-serif;
vertical-align: bottom;
color: #000000;
padding-top: 5px;
text-align: center;
}
.FullDay
{
background:url(../images/calendar_bg.gif) repeat-x;
width:86px;
height:86px;
padding:0;
\n
}
.NotDay
{
width:84px;
height:84px;
padding:0;
\n
}
\n
.FullDay a
{
display:none;
margin:2px;
margin-left:3px;
}
.NotDay a
{
display:none;
margin:2px;
margin-left:3px;
}
\n
.Thumb
{
z-index: 1;
position:absolute;
margin:0;
border: #fff 1px solid;
}
\n
A.date {display:block;}
A.date:link { color: #6b9f1f;text-decoration: underline;-moz-outline: none;}
\n
.WhiteDate { PADDING-LEFT: 4px; Z-INDEX: 3; FONT: bold 18px “Trebuchet MS”, Arial, Helvetica, sans-serif; COLOR: #fff; PADDING-TOP: 0px; POSITION: absolute}
.RedDate { PADDING-LEFT: 4px; Z-INDEX: 3; FONT: bold 18px “Trebuchet MS”, Arial, Helvetica, sans-serif; COLOR: #FF2A55; PADDING-TOP: 0px; POSITION: absolute}
.BlackDate { PADDING-LEFT: 5px; Z-INDEX: 2; FONT: bold 18px “Trebuchet MS”, Arial, Helvetica, sans-serif; COLOR: #000; PADDING-TOP: 1px; POSITION: absolute}
可以得到刚开始时 图一 的效果。
6. 至于图二,我这里添加了showdiv.js
\n
function ShowPhotos(div, pDate) {
var iWidth = (“#divPhoto”).width();
var iHeight = (“#divPhoto”).height();
(“#divPhoto”).css(“top”,(document.body.clientHeight – iHeight)/2 + ‘px’);
(“#divPhoto”).css(“left”,(document.body.clientWidth – iWidth)/2 + ‘px’);
(“#divPhoto”).css(“display”,”inline”);
(“#spanDate”).html(pDate);
var ret = .ajax({url:”ShowPic.aspx”, data:{“date”:pDate}, async: false}).responseText;
(“#divMore”).html(ret);
}
\n
function ClosePhotos() {
(“#divPhoto”).css(“display”,”none”);
(“#spanDate”).html(“”);
(“#divMore”).html(“”);
}
其中ShowPhotos是居中显示,并且利用AJAX得到ShowPic.aspx返回的HTML内容;
\n
最终完成了 图二 的效果。
\n代码大家自己去查看吧,我这里附上我的源代码:
\n
\n\n