Repeater控件中实现删除一条记录
ASP.NET数据绑定控件中,Repeater控件比较灵活,所以在项目中使用的频率相对来说比较高,对某些需求来说,删除还是比较重要的,如下面图片所示场景:
如果没有删除,我想你能很快想到结果,用户体验也就可想而知,下面我们来实现这个删除功能。
注:在这个事例中,为了简单起见没有使用数据库,而是使用了“泛型字典”零时存放数据,在实际开发中数据应该是从数据库中获取的。
为了有点面向对象的意思,在这个实例中有“三层架构”的影子,后面我适当地会说明。
实体(Entity)层
学过三层架构的人应该对这个不会陌生吧,上代码:
public class News : IComparable
{
/// <summary>
/// 获取或设置作者ID
/// </summary>
public int Id { get; set; }
private string author;
/// <summary>
/// 获取或设置作者名
/// </summary>
public string Author
{
get
{
if (String.IsNullOrEmpty(author))
{
throw new ArgumentNullException("用户名不能为空!");
}
return author;
}
set { author = value; }
}
/// <summary>
/// 获取或设置标题
/// </summary>
public string Title { get; set; }
private DateTime comDatetime;
/// <summary>
/// 获取发布时间
/// </summary>
public DateTime ComDatetime
{
get { return comDatetime; }
}
/// <summary>
/// 构造函数
/// </summary>
public News()
{
Id = 0;
author = "游客";
comDatetime = DateTime.Now;
}
/// <summary>
/// 构造函数
/// </summary>
/// <param name="aothor"></param>
public News(int id, string aothor,string title)
{
this.Id = id;
//看见了吗?此处我用的是属性,这样就可以把在写属性时做的限制也应用上,是不是以后维护时只改属性部分就行了。
this.Author = aothor;
//由于comDatetime是只读的,所以我只能给字段赋值了。
this.comDatetime = DateTime.Now;
this.Title = title;
}
/// <summary>
/// IComparable接口的简单实现,可以用来排序等
/// </summary>
/// <param name="obj"></param>
/// <returns></returns>
public int CompareTo(object obj)
{
News obj1 = obj as News;
if (this.Id > obj1.Id)
{
return 1;
}
else if (this.Id < obj1.Id)
{
return -1;
}
else
{
return 0;
}
}
#region 重写
/*
* 这三个方法就不实现了,它们实现的格式基本上是固定的,在重写Equals时把=,和!=也要重写了。
* 具体为什么重写大家找本书看看就行了。
*/
public override string ToString()
{
return base.ToString();
}
public override int GetHashCode()
{
return base.GetHashCode();
}
public override bool Equals(object obj)
{
return base.Equals(obj);
}
#endregion
}
看起来有点复杂了,不过没有关系,大家可以发散发散思维,或者指点一下小弟也行。嘿嘿,后面的重写方法在这个示例中没有用到,可以省去不看。前面代码都是熟悉的属性和构造方法我就不做过多解释了。
数据访问(DAL)层
这个类我用到了单例模式,为了让数据在整个程序运行时只初始化一次,不然每次点删除就会吧前一次删除的又显示出来了,大家把单例去掉试试就明白了。
下面先看代码:
public class Datasource { private static Dictionary<int, News> newsDictionary; /// <summary> /// 构造函数 /// </summary> private Datasource() { newsDictionary = new Dictionary<int, News>(); } private static Datasource datasource; /// <summary> /// 获取唯一的实例 /// </summary> public static Datasource Instance { get { if (datasource == null) { datasource = new Datasource(); } return datasource; } } /// <summary> /// 添加新闻 /// </summary> /// <param name="dics"></param> public void Add(Dictionary<int, News> dics) { if (newsDictionary.Count == 0) { newsDictionary = dics; } else { foreach (var item in dics) { newsDictionary.Add(item.Key, item.Value); } } } /// <summary> /// 添加新闻 /// </summary> /// <param name="id">新闻ID</param> /// <param name="news">News对象</param> public void Add(int id, News news) { if (newsDictionary.ContainsKey(id)) { throw new ApplicationException("该ID已经存在,请重新设置!"); } newsDictionary.Add(id, news); } /// <summary> /// 通过id删除新闻 /// </summary> /// <param name="id">新闻ID</param> public void Delete(int id) { newsDictionary.Remove(id); } /// <summary> /// 取得全部新闻 /// </summary> /// <returns></returns> public List<News> GetComment() { List<News> newsList = new List<News>(); newsList.AddRange(newsDictionary.Values); return newsList; } }
应该也不是很难,有不明白的或者不好的地方我们可以在评论中讨论。
UI层
有些人现在可能坐不住了,问为什么没有BLL层呢?BLL层不是最重要的吗?其实不用那么较真,任何模式、框架都是为人服务的,我们用着合适就好,在这里我想也不用考虑那么复杂再写个BLL吧。今天我的主题也不在业务逻辑上,所以我只是按三层的思路想问题,但是不是真正的三层,感兴趣的朋友可以去专门学习三层架构(不知道现在是不是MVC更火一点,总之记住技不压身就是了)。
Repeater控件上场了:
<head runat="server"> <title>repeater实例</title> <style type="text/css"> table { border:2px solid #666; width: 800px; text-align:center; } table caption { margin:10px; font-size:150%; font-weight:bold; } table th { font-weight:bold; } </style> </head> <body> <form id="form1" runat="server"> <div> <table> <caption>repeater控件实例</caption> <tr> <th>新闻ID</th> <th> 新闻标题</th> <th>作者</th> <th> 发布时间</th> <th>操作</th> </tr> <asp:Repeater ID="rptNewsComment" runat="server"> <ItemTemplate> <tr> <td> <%# Eval("Id") %></td> <td><%# Eval("Title")%></td> <td><%# Eval("Author")%> </td> <td><%# Eval("ComDatetime")%></td> <td> <asp:LinkButton ID="lbtnDeleteNews" CausesValidation="false" CommandArgument='<%# Eval("Id") %>' runat="server" OnClick="lbtnDeleteNews_Click" OnClientClick="return confirm('是否要真的删除该评论?')">删除</asp:LinkButton> </td> </tr> </ItemTemplate> </asp:Repeater> </table> </div> </form> </body>
看见了吗,是不是跟写HTML差不多,大家想想DataGrid就知道了。其他的我也不多说,关键是下面这句
<asp:LinkButton ID="lbtnDeleteNews" CausesValidation="false" CommandArgument='<%# Eval("Id") %>' runat="server" OnClick="lbtnDeleteNews_Click" OnClientClick="return confirm('是否要真的删除该评论?')">删除</asp:LinkButton>
中的属性CommandArgument='<%# Eval("Id") %>',它可以把Id传给.cs文件中的事件处理,处理如下:
/// <summary> /// 删除新闻 /// </summary> protected void lbtnDeleteNews_Click(object sender, EventArgs e) { try { LinkButton lb = (LinkButton)sender; //获取传过来的commwntid int id = Convert.ToInt32(lb.CommandArgument); //Response.Write(comId); //删除该新闻 Datasource.Instance.Delete(id); //重新绑定新闻列表 BindNews(); } catch (Exception) { //TODO:暂时不处理了 } }
完整代码可以在此下载