我应该如何使用 GridView?

发布于 2024-09-24 15:35:08 字数 3143 浏览 0 评论 0原文

我最近遇到的问题让我质疑我关于 GridView 的整个哲学和假设。

目前,我使用了类似于以下模型的东西。

在标记中:

<asp:UpdatePanel ID="pnlSearch" UpdateMode="Conditional" runat="server">
    <ContentTemplate>
            <asp:TextBox ID="txtSearch" runat="server" 
                ontextchanged="txtSearch_TextChanged"></asp:TextBox>
    </ContentTemplate>
</asp:UpdatePanel>

<asp:UpdatePanel ID="pnlGridView" UpdateMode="Conditional" runat="server">
    <ContentTemplate>
        <asp:GridView ID="GridView1" EnableViewState="false" AllowPaging="true" PageSize="20" DataSourceID="MyDataSource" runat="server" AutoGenerateColumns="False">
            <Columns>
                <asp:BoundField DataField="COL_1" HeaderText="Happy Data" SortExpression="COL_1" />
                <asp:BoundField DataField="COL_2" HeaderText="Happy Related Data" SortExpression="COL_2" DataFormatString="{0:M/dd/yyyy}" />
            </Columns>
        </asp:GridView>
    </ContentTemplate>
    <Triggers>
        <asp:AsyncPostBackTrigger ControlID="txtSearch" EventName="TextChanged" />
    </Triggers>
</asp:UpdatePanel>
<asp:SqlDataSource ID="MyDataSource" runat="server"></asp:SqlDataSource>

非常基本的东西。一个网格视图。一个数据源。用于搜索结果的文本框。我包含 UpdatePanel 只是因为我有点相信它们可能是我的问题的一部分。

在我的代码后面,我通常会做这样的事情:

protected void Page_Load(object sender, EventArgs e)
{

    if (!IsPostBack)
    {
        MyDataSource.ConnectionString = ConfigurationManager.ConnectionStrings["OracleConnectionString"].ConnectionString;
        MyDataSource.ProviderName = ConfigurationManager.ConnectionStrings["OracleConnectionString"].ProviderName;
        GridView1.EmptyDataText = "No comments found.";
        PopulateGridView();
    }
}

protected void PopulateGridView()
{
    string strQuery = @"SELECT  COL_1,
                          COL_2
                    FROM  some_table
                   WHERE  COL_3 = :important_filter";

    MyDataSource.SelectCommand = strQuery;
    MyDataSource.SelectParameters.Clear();
    MyDataSource.SelectParameters.Add(":important_filter", Request.QueryString["filter"]);
    GridView1.DataBind();
    GridView1.PageIndex = 0;
}

protected void txtSearch_TextChanged(object sender, EventArgs e)
{
    string strQuery = @"SELECT  COL_1,
                          COL_2
                    FROM  some_table
                   WHERE  COL_3 = :important_filter AND lower(COL_2) LIKE :search";
    MyDataSource.SelectCommand = strQuery;
    MyDataSource.SelectParameters.Clear();
    MyDataSource.SelectParameters.Add(":important_filter", Request.QueryString["filter"]);
    MyDataSource.SelectParameters.Add(":search", "%" + txtSearch.Text.Trim().ToLower() + "%");
    GridView1.DataBind();
    GridView1.PageIndex = 0;
}

没什么太花哨的。我最初将数据源连接到配置文件中的连接字符串(在多实例环境中这是必需的),连接查询和数据绑定。在搜索时,我更改查询并重新绑定。

唯一的问题是什么?

上面的方法不起作用。为什么?数据源在回发时会丢失其查询、连接字符串、提供程序名称等。所以gridview自杀了。当我尝试更改页面时,无论是在初始加载时还是在填充搜索时,都会发生同样的事情。

我上周通过手动添加数据源来控制状态并重新填充控制状态中的值来“解决”了这个问题,但这看起来很黑客。

我不明白什么?

Recent problems I've had are making me question my whole philosophy and assumptions regarding GridViews.

Currently, I have used something along the lines of the following model.

In Markup:

<asp:UpdatePanel ID="pnlSearch" UpdateMode="Conditional" runat="server">
    <ContentTemplate>
            <asp:TextBox ID="txtSearch" runat="server" 
                ontextchanged="txtSearch_TextChanged"></asp:TextBox>
    </ContentTemplate>
</asp:UpdatePanel>

<asp:UpdatePanel ID="pnlGridView" UpdateMode="Conditional" runat="server">
    <ContentTemplate>
        <asp:GridView ID="GridView1" EnableViewState="false" AllowPaging="true" PageSize="20" DataSourceID="MyDataSource" runat="server" AutoGenerateColumns="False">
            <Columns>
                <asp:BoundField DataField="COL_1" HeaderText="Happy Data" SortExpression="COL_1" />
                <asp:BoundField DataField="COL_2" HeaderText="Happy Related Data" SortExpression="COL_2" DataFormatString="{0:M/dd/yyyy}" />
            </Columns>
        </asp:GridView>
    </ContentTemplate>
    <Triggers>
        <asp:AsyncPostBackTrigger ControlID="txtSearch" EventName="TextChanged" />
    </Triggers>
</asp:UpdatePanel>
<asp:SqlDataSource ID="MyDataSource" runat="server"></asp:SqlDataSource>

Pretty basic stuff. A GridView. A data source. A text box for searching results. I include the UpdatePanels only because I'm somewhat convinced they could be part of my problems.

Over in my code behind, I usually would do something like this:

protected void Page_Load(object sender, EventArgs e)
{

    if (!IsPostBack)
    {
        MyDataSource.ConnectionString = ConfigurationManager.ConnectionStrings["OracleConnectionString"].ConnectionString;
        MyDataSource.ProviderName = ConfigurationManager.ConnectionStrings["OracleConnectionString"].ProviderName;
        GridView1.EmptyDataText = "No comments found.";
        PopulateGridView();
    }
}

protected void PopulateGridView()
{
    string strQuery = @"SELECT  COL_1,
                          COL_2
                    FROM  some_table
                   WHERE  COL_3 = :important_filter";

    MyDataSource.SelectCommand = strQuery;
    MyDataSource.SelectParameters.Clear();
    MyDataSource.SelectParameters.Add(":important_filter", Request.QueryString["filter"]);
    GridView1.DataBind();
    GridView1.PageIndex = 0;
}

protected void txtSearch_TextChanged(object sender, EventArgs e)
{
    string strQuery = @"SELECT  COL_1,
                          COL_2
                    FROM  some_table
                   WHERE  COL_3 = :important_filter AND lower(COL_2) LIKE :search";
    MyDataSource.SelectCommand = strQuery;
    MyDataSource.SelectParameters.Clear();
    MyDataSource.SelectParameters.Add(":important_filter", Request.QueryString["filter"]);
    MyDataSource.SelectParameters.Add(":search", "%" + txtSearch.Text.Trim().ToLower() + "%");
    GridView1.DataBind();
    GridView1.PageIndex = 0;
}

Nothing too fancy. I initially connect up the data source to a connection string from the config file (as is necessary in a multi instance environment), wire up the query and databind. On searches, I change the query and rebind.

The only problem?

The above doesn't work. Why? The data source loses it's query, connection string, provider name, etc on post back. So the gridview commits suicide. The same thing happens when I try to change pages...either on initial load or with a search populated.

I "solved" this problem last week by manually adding the datasource to control state and repopulating the values from control state, but that seems hackish.

What am I not understanding?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

你的呼吸 2024-10-01 15:35:08

您将更新模式设置为有条件,因此您需要在“pnlGridView”上调用更新

GridView1.DataBind();
GridView1.PageIndex = 0;
pnlGridView.Update();

我还将重新审视您如何使用数据源

 <asp:SqlDataSource ID="ProductsDataSource" runat="server"
    ConnectionString="<%$ ConnectionStrings:OracleConnectionString %>"
    SelectCommand="SELECT  COL_1, COL_2 FROM  some_table WHERE  COL_3 = @important_filter">

  <SelectParameters>
     <asp:ControlParameter ControlID="textBox?not sure where this is coming from" PropertyName="SelectedValue" Name="important_filter" Type="string" DefaultValue="" />
   </SelectParameters>
 </asp:SqlDataSource>

您还可以使用服务器端事件处理程序并手动设置重要的过滤器。

protected void SQLDataSource_Selecting(object sender, SQLDataSourceSelectingEventArgs e) {
    e.InputParameters["important_filter"] = "whatever";
 }

并将事件添加到 SQLDataSource 的标记中。

<asp:SqlDataSource ID="MyDataSource" runat="server"     OnSelecting="SQLDataSource_Selecting" />

You have the update mode set to conditional so you need to call update on 'pnlGridView'

GridView1.DataBind();
GridView1.PageIndex = 0;
pnlGridView.Update();

I would also revist how you are using your DataSource

 <asp:SqlDataSource ID="ProductsDataSource" runat="server"
    ConnectionString="<%$ ConnectionStrings:OracleConnectionString %>"
    SelectCommand="SELECT  COL_1, COL_2 FROM  some_table WHERE  COL_3 = @important_filter">

  <SelectParameters>
     <asp:ControlParameter ControlID="textBox?not sure where this is coming from" PropertyName="SelectedValue" Name="important_filter" Type="string" DefaultValue="" />
   </SelectParameters>
 </asp:SqlDataSource>

You could also use a server side event handler and set the important filter manually.

protected void SQLDataSource_Selecting(object sender, SQLDataSourceSelectingEventArgs e) {
    e.InputParameters["important_filter"] = "whatever";
 }

And add the event to your markup for your SQLDataSource.

<asp:SqlDataSource ID="MyDataSource" runat="server"     OnSelecting="SQLDataSource_Selecting" />
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文