GridView实战二:使用ObjectDataSource数据源控件

简介:

前言:

  ObjectDataSource数据源控件优点甚多,确实令人爱不惜手,但不支持重绑定这一项确实让人失望。下面的实战二将通过ObjectDataSource配合GridView来实现删、改、分页、排序,并分析使用cache后排序失灵的原因。

 

实战:

1.效果:

图1.显示状态

图2.编辑状态

 

2.代码:

.aspx

<asp:ObjectDataSource runat="server" ID="ods" EnablePaging="true" TypeName="OdsDataManager"
        SelectCountMethod="GetRecordCount" SelectMethod="GetRecord" UpdateMethod="UpdateRecord"
        DeleteMethod="DelRecord" OnUpdating="ods_OnUpdating" SortParameterName="sortExpression">
     </asp:ObjectDataSource>
    <asp:GridView runat="server" ID="gv" DataSourceID="ods" AutoGenerateColumns="false"
             AllowPaging="true" PageSize="1" AllowSorting="true" DataKeyNames="ID"
             OnRowDataBound="gv_OnRowDataBound">
             <HeaderStyle BackColor="graytext" />
            <Columns>
                <asp:TemplateField>
                    <HeaderStyle Width="20%" />
                    <HeaderTemplate>
                        <asp:LinkButton runat="server" ID="lbtnSortName" Text="Name" CommandName="Sort" CommandArgument="Name">
                        </asp:LinkButton>
                    </HeaderTemplate>
                    <ItemTemplate><%#Eval("Name") %></ItemTemplate>
                    <EditItemTemplate>
                        <asp:TextBox runat="server" ID="tbxName" Text='<%#Bind("Name") %>'></asp:TextBox> 
                        <asp:RegularExpressionValidator runat="server" ID="revName" ControlToValidate="tbxName"
                             ValidationExpression="[a-zA-Z]+" ErrorMessage="Please input your English name!" Display="Dynamic">
                        </asp:RegularExpressionValidator>
                        <asp:RequiredFieldValidator runat="server" ID="rfvName" ControlToValidate="tbxName"
                            ErrorMessage="Please input your name" Display="Dynamic">
                        </asp:RequiredFieldValidator> 
                    </EditItemTemplate>
                </asp:TemplateField> 
                <asp:TemplateField>
                    <HeaderStyle Width="10%"/>
                    <HeaderTemplate>
                        <asp:LinkButton runat="server" ID="lbtnSortSex" Text="Sex" CommandName="Sort" CommandArgument="Sex">
                        </asp:LinkButton> 
                    </HeaderTemplate> 
                    <ItemTemplate>
                        <asp:RadioButtonList Enabled="false" runat="server" ID="rblSexShow" RepeatDirection="Horizontal" 
                            RepeatColumns="2">
                        </asp:RadioButtonList>
                    </ItemTemplate> 
                    <EditItemTemplate>
                         <asp:RadioButtonList runat="server" ID="rblSexEdit" RepeatDirection="Horizontal" RepeatColumns="2">
                         </asp:RadioButtonList>
                    </EditItemTemplate> 
                </asp:TemplateField>
                <asp:TemplateField>
                    <HeaderStyle Width="20%"/>
                    <HeaderTemplate>
                        <asp:LinkButton runat="server" ID="lbtnSortCountry" Text="Country" CommandName="Sort" CommandArgument="Country">
                        </asp:LinkButton>
                    </HeaderTemplate> 
                    <ItemTemplate><%#Eval("Country")%></ItemTemplate> 
                    <EditItemTemplate>
                        <asp:DropDownList runat="server" ID="ddlCountry"></asp:DropDownList>
                    </EditItemTemplate> 
                </asp:TemplateField>
                <asp:TemplateField>
                    <HeaderStyle Width="20%"/>
                    <HeaderTemplate>Hobby</HeaderTemplate>
                    <ItemTemplate><%#Eval("Hobby") %></ItemTemplate> 
                    <EditItemTemplate>
                        <asp:CheckBoxList runat="server" ID="cbxlHobby" RepeatDirection="Horizontal" RepeatColumns="5">
                        </asp:CheckBoxList>
                    </EditItemTemplate>
                </asp:TemplateField>
                <asp:CommandField ShowDeleteButton="true" DeleteText="Delete" ShowEditButton="true" EditText="Edit" />
            </Columns>
            <PagerSettings Visible="true" />
            <PagerStyle Font-Size="12px"/>
            <PagerTemplate>
                <div style="float:left;margin-left:15px;color:#999;line-height:20px">
                    当前第<%#this.gv.PageIndex+1 %>/<%#this.gv.PageCount %>页
                </div>
                <div style="float:right;margin-right:15px;color:#999;line-height:20px">页</div>
                <div style="float:right">
                    <asp:DropDownList runat="server" ID="ddlPaging" AutoPostBack="true"
                        OnSelectedIndexChanged="ddlPaging_OnSelectedIndexChanged">
                    </asp:DropDownList>
                </div>
                <div style="float:right;color:#999;line-height:20px">跳转到第</div>
            </PagerTemplate>
        </asp:GridView>

说明:

1.因用了数据源控件,所以Name在编辑状态时使用<%#Bind("Name")%>来实现双向通讯的绑定

2.因为没有添加的功能,所以用了asp:CommandField来实现编辑、删除等按钮的功能。

3.排序功能上只要在ods上设定SortParameterName,它的值就是SelectMethod中关于排序的参数的名称,然后设定 GridView的AllowSorting为true就ok了。排序按钮上依然用到GridView内置的CommandName——Sort,然后 CommandArgument设为要排序的字段名,至于排序的方向由ObjectDataSource负责,省心多了。

 

.aspx.cs代码

public partial class Default2 : System.Web.UI.Page
{
    private OdsDataManager dm = new OdsDataManager();

    protected void Page_Load(object sender, EventArgs e)
    {

    }

    protected void gv_OnRowDataBound(object sender, GridViewRowEventArgs e)
    {
         DataRowView drv = e.Row.DataItem as DataRowView;

         if (e.Row.RowType == DataControlRowType.DataRow)
         {
             //显示时
             if (this.gv.EditIndex == -1)
             {
                 //设置性别
                 RadioButtonList rbl = e.Row.FindControl("rblSexShow") as RadioButtonList;
                 rbl.Items.Add(new ListItem("Male", "M"));
                 rbl.Items.Add(new ListItem("Female", "F"));
                 if ((drv["Sex"] as string).ToLower().Equals("m"))
                     rbl.Items[0].Selected = true;
                 else
                     rbl.Items[1].Selected = true;
             }
             //修改时:
             else if (e.Row.RowIndex == this.gv.EditIndex)
             {
                 //性别
                 RadioButtonList rbl = e.Row.FindControl("rblSexEdit") as RadioButtonList;
                 rbl.Items.Add(new ListItem("Male", "M"));
                 rbl.Items.Add(new ListItem("Female", "F"));
                 if ((drv["Sex"] as string).ToLower().Equals("m"))
                     rbl.Items[0].Selected = true;
                 else
                     rbl.Items[1].Selected = true;
                 //国籍
                 DropDownList ddlCountry = e.Row.FindControl("ddlCountry") as DropDownList;
                 DataTable countryDt = dm.GetCountry();
                 ListItem li = null;
                 for (int i = 0; i < countryDt.Rows.Count; ++i)
                 {
                     string cn = countryDt.Rows[i]["cn"] as string;
                     li = new ListItem(cn, cn);
                     if (cn.Equals(drv["Country"] as string))
                         li.Selected = true;
                     ddlCountry.Items.Add(li);
                 }
                 //兴趣
                 CheckBoxList cbl = e.Row.FindControl("cbxlHobby") as CheckBoxList;
                 DataTable hobbyDt = dm.GetHobby();
                 string hobbys = drv["Hobby"] as string;
                 ListItem hobbyLi = null;
                 string hstr = string.Empty;
                 for (int i = 0; i < hobbyDt.Rows.Count; i++)
                 {
                     hstr = hobbyDt.Rows[i]["hobby"] as string;
                     hobbyLi = new ListItem(hstr, hstr);
                     if (hobbys.IndexOf(hstr) >= 0)
                         hobbyLi.Selected = true;
                     cbl.Items.Add(hobbyLi);
                 }
             }
         }
         else if (e.Row.RowType == DataControlRowType.Pager)
         {
             //绑定分页控件
             DropDownList ddlPaging = e.Row.FindControl("ddlPaging") as DropDownList;
             for (int i = 0; i < this.gv.PageCount; i++)
             {
                 ddlPaging.Items.Add(new ListItem(Convert.ToString(i + 1), Convert.ToString(i)));
             }
             ddlPaging.SelectedIndex = this.gv.PageIndex;
         }
    }

    /// <summary>
/// 分页控件的OnSelectedIndexChanged
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
    protected void ddlPaging_OnSelectedIndexChanged(object sender, EventArgs e)
    {
        this.gv.PageIndex = (sender as DropDownList).SelectedIndex;
    }

    protected void ods_OnUpdating(object sender, ObjectDataSourceMethodEventArgs e)
    {
        string Sex = (this.gv.Rows[this.gv.EditIndex].FindControl("rblSexEdit") as RadioButtonList).SelectedValue;
        string Country = (this.gv.Rows[this.gv.EditIndex].FindControl("ddlCountry") as DropDownList).SelectedValue;
        System.Text.StringBuilder hobbys = new System.Text.StringBuilder();
        foreach (ListItem li in (this.gv.Rows[this.gv.EditIndex].FindControl("cbxlHobby") as CheckBoxList).Items)
        {
            if (li.Selected)
                hobbys.Append(li.Value+",");
        }
        if (hobbys.Length >= 2)
            hobbys.Remove(hobbys.Length - 1, 1);

        e.InputParameters.Add("Sex", Sex);
        e.InputParameters.Add("Country", Country);
        e.InputParameters.Add("Hobby",hobbys.ToString());
    }
}

说明:

1.看到behind code是不是发现代码量少了很多呢?这就是用ods的好处了。

2.在更新操作时,因为Country、Sex和Hobby都没有和ods作双向绑定,所以要自己获取并写入到ods的InputParameters中,然后ods就会调用已经设置好的UpdateMethod了。

 

数据操作类

public class OdsDataManager
{
    private static DataTable dt = null;//用户记录
    private static DataTable countryDt = null;//国籍
    private static DataTable hobbyDt = null;//兴趣

    public OdsDataManager()
    {
        if (dt == null)
        {
            dt = new DataTable();
            dt.Columns.Add("ID");
            dt.Columns.Add("Name");
            dt.Columns.Add("Sex");
            dt.Columns.Add("Country");
            dt.Columns.Add("Hobby");

            //Default Data
            dt.Rows.Add(new object[] { 1, "Mary", "F", "China", "Cooking,Music" });
            dt.Rows.Add(new object[] { 2, "John", "M", "China", "Tennis" });
        }

        if (countryDt == null)
        {
            countryDt = new DataTable();
            countryDt.Columns.Add("cn");

            //Default Data
            countryDt.Rows.Add(new object[] { "China" });
            countryDt.Rows.Add(new object[] { "French" });
            countryDt.Rows.Add(new object[] { "America" });
            countryDt.Rows.Add(new object[] { "Afria" });
            countryDt.Rows.Add(new object[] { "Japan" });
        }

        if (hobbyDt == null)
        {
            hobbyDt = new DataTable();
            hobbyDt.Columns.Add("hobby");

            //Default Data
            hobbyDt.Rows.Add(new object[] { "Cooking" });
            hobbyDt.Rows.Add(new object[] { "Music" });
            hobbyDt.Rows.Add(new object[] { "Reading" });
            hobbyDt.Rows.Add(new object[] { "Movies" });
            hobbyDt.Rows.Add(new object[] { "Tennis" });
        }
    }

    public DataTable GetRecord(int maximumRows, int startRowIndex, string sortExpression)
    {
        //排序
        if(!string.IsNullOrEmpty(sortExpression))
        {
            dt.DefaultView.Sort = sortExpression;
        }

        DataRow[] drs = dt.Select();
        DataTable dt1 = dt.Clone();
        for (int i = startRowIndex; i < startRowIndex+maximumRows && i<drs.Length; i++)
        {
            dt1.Rows.Add(drs[i].ItemArray);
        }

        return dt1;
    }

    public int GetRecordCount()
    {
        return dt.Rows.Count;
    }

    public bool UpdateRecord(int ID, string Name, string Sex, string Country, string Hobby)
    {
        bool result = false;
        DataRow[] drs = dt.Select("ID=" + ID);
        if (drs.Length == 1)
        {
            drs[0]["Name"] = Name;
            drs[0]["Sex"] = Sex;
            drs[0]["Country"] = Country;
            drs[0]["Hobby"] = Hobby;

            result = true;
        }

        return result;
    }

    public bool DelRecord(int ID)
    {
        bool result = false;
        DataRow[] drs = dt.Select("ID=" + ID);
        if (drs.Length == 1)
        {
            dt.Rows.Remove(drs[0]);

            result = true;
        }

        return result;
    }

    public DataTable GetCountry()
    {
        return countryDt;
    }

    public DataTable GetHobby()
    {
        return hobbyDt;
    }
}

说明:

1.GetRecord方法绑定到ods的SelectMethod上,因为启用分页和排序功能,所以参数数组中必须有maximumRows(每 页记录数), startRowIndex(当前页首条记录在整个数据集中的索引), sortExpression(排序表达式,首次加载页面时为空字符串,postback时含排序字段和排序方向)。

 

3.数据缓存

  ods可以启用cache,该cache为应用程序级的,就是多个画面的ods只要SelectMethod和 SelectCountMethod、Select参数一样就可以共享缓存中的数据,在Cache有效时进行Select操作将会先根据前面说的三个要素 从Cache中获取数据,如果没有才执行SelectMethod方法。注意不同的要素组合会各自对应一份缓存的数据,当第二次请求时就直接读缓存。

  就是因为这样问题就来了,如果启用了cache那么上面的排序功能就会失效,而其他功能依然正常。原因在于排序操作是在 SelectMethod中实现,而在Cache生效时程序根本就不执行SelectMethod方法,除非说内存不足或其他原因令cache不够大来保 存数据而被迫执行SelectMethod方法。对于该问题目前还没找到解决的方法,望大哥们来告诉我啦^_^

目录
相关文章
|
数据安全/隐私保护
DevExpress-GridControl控件-GridView使用
DevExpress-GridControl控件-GridView使用
|
C#
WPF 实现 DataGrid/ListView 分页控件
原文:WPF 实现 DataGrid/ListView 分页控件 在WPF中,通常会选用DataGrid/ListView进行数据展示,如果数据量不多,可以直接一个页面显示出来。如果数据量很大,2000条数据,一次性显示在一个页面中,不仅消耗资源,而且用户体验也很糟糕。
1958 0
|
Web App开发 SQL 前端开发
|
Web App开发 前端开发 JavaScript