c# - 模板字段中的 ASP.NET c# 复选框列表

标签 c# asp.net gridview

我是 asp.net 的新手。我在 sqlserver 中创建了一个包含 3 列的数据库表; ImageID、文件名和分数

文件名是 C:\pics\beads.png 或 C:\pics\moreimages\scenary.jpeg

我使用 C# asp.net 创建了一个 GridView。这个 Gridview 应该填充

(第 1 列)ImageID 并从文件名(第 2 列)获取图像,我创建了 2 个复选框列表,如下所示,它应该接受来自用户的图像分数并将其保存到数据库表中。

问题 1 .

我能够填充图像 ID,但图像没有被填充。

问题 2.

我不知道如何访问 checkboxlist 因为它在模板中。选中的是默认选择,即使我点击它也不会改变。应使用哪种方法/属性将选择保存到数据库中。这是我的代码

<form id="form1" runat="server">
    <p style="height: 391px">
        <asp:GridView ID="GridView1" runat="server" Caption="Logos" Height="299px" Width="577px" AutoGenerateColumns="False">
            <Columns>
                <asp:BoundField DataField="ImageID" HeaderText="ImageID" />
                <asp:ImageField DataImageUrlField="FileName" ControlStyle-Width="100"
                    ControlStyle-Height="100" HeaderText="Image" AlternateText="No image">
                    <ControlStyle Height="100px" Width="100px"></ControlStyle>
                </asp:ImageField>
                <asp:TemplateField HeaderText="Score" AccessibleHeaderText="CheckBoxList" ValidateRequestMode="Enabled">
                    <ItemTemplate>
                        <asp:CheckBoxList runat="server" AutoPostBack="true" RepeatColumns="3" ID="test">
                            <asp:ListItem Selected="True" Value="5">Good</asp:ListItem>
                            <asp:ListItem Value="0">Not Good </asp:ListItem>
                            <asp:ListItem Value="3">OK</asp:ListItem>
                        </asp:CheckBoxList>
                    </ItemTemplate>
                </asp:TemplateField>
            </Columns>
        </asp:GridView>         

        <asp:Button ID="Button1" runat="server" OnClick="Button1_Click" Text="Save" Width="130px" />
        <asp:Button ID="Button2" runat="server" OnClientClick="javaScript:window.close(); return false;" Text="Exit" Width="102px" />

        <asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>

    </p>
</form>

public string sqlSel = @"SELECT TOP 3 [ImageID],FileName FROM [db1].[ImagesTest] where [Score] is null";

protected void Page_Load(object sender, EventArgs e)
{
   
    using (SqlConnection connection = new SqlConnection(ConfigurationManager.ConnectionStrings["SQLConnectionString"].ConnectionString))
        {
            connection.Open();
            SqlCommand cmdSel = new SqlCommand(sqlSel, connection);
            SqlDataReader reader1 = cmdSel.ExecuteReader();
           
            while (reader1.Read())
            {
                DataSet ds = GetData(sqlSel);

                if (ds.Tables.Count > 0)
                {
                    GridView1.DataSource = ds;
                    GridView1.DataBind();              
                }
                else
                {
                    Response.Write("Unable to connect to the database.");
                }

            }
            
        }
    
}

private DataSet GetData(string cmdSel)
{
   
    String strConnString = System.Configuration.ConfigurationManager.ConnectionStrings["SQLConnectionString"].ConnectionString;
    DataSet ds = new DataSet();

    try
    {
        SqlConnection con = new SqlConnection(strConnString);
        SqlDataAdapter sda = new SqlDataAdapter(cmdSel,con);
        sda.Fill(ds);
        
    }
    catch (Exception ex)
    {
        Response.Write("IN EXCEPTION "+ex.Message);
        return null;
    }

    return ds;
}

谢谢你的时间 拉什米

最佳答案

您的代码有几个问题,这里是应该修复的地方:

如何修复图片(问题1)

正如@Guilherme 在评论中所说,图像使用 URL 而不是磁盘路径。 替换图像磁盘路径 C:\pics\beads.pngC:\pics\moreimages\scenary.jpeg类似于 Images/beads.pngImages/scenary.jpeg .

为此,您需要有一个名为 Images 的文件夹在与您的 .aspx 相同的目录级别包含这两个文件文件。

在 ASPX 文件中调整您的 GridView1 声明

在您的 GridView1 声明中,您应该:

  1. 将处理程序附加到 OnRowDataBound事件。这将允许您正确绑定(bind) Score数据集列到 Score GridView 列
  2. 设置DataKeyNames将网格上的属性设置为图像表的主键(在本例中为 DataKeyNames="ImageID")
  3. 使用RadioButtonList而不是 CheckboxList , 因为根据你的数据集你只能设置一个值,这就是 RadioButtonList做。 CheckboxList通常在需要多选时使用。
  4. 将处理程序附加到 SelectedIndexChanged RadioButtonList 上的事件.这将允许您将新值保存到数据库中(问题 2)

GridView 声明应如下所示:

<asp:GridView ID="GridView1" runat="server" Caption="Logos" Height="299px" Width="577px" AutoGenerateColumns="False" OnRowDataBound="GridView1_RowDataBound" DataKeyNames="ImageID">
        <Columns>
            <asp:BoundField DataField="ImageID" HeaderText="ImageID" />
            <asp:ImageField DataImageUrlField="FileName" ControlStyle-Width="100"
                ControlStyle-Height="100" HeaderText="Image" AlternateText="No image">
                <ControlStyle Height="100px" Width="100px"></ControlStyle>
            </asp:ImageField>
            <asp:TemplateField HeaderText="Score" AccessibleHeaderText="RadioButtonList" ValidateRequestMode="Enabled">
                <ItemTemplate>                        
                    <asp:RadioButtonList runat="server" AutoPostBack="true" RepeatColumns="3" ID="test" OnSelectedIndexChanged="test_SelectedIndexChanged">
                        <asp:ListItem Value="5">Good</asp:ListItem>
                        <asp:ListItem Value="0">Not Good </asp:ListItem>
                        <asp:ListItem Value="3">OK</asp:ListItem>
                    </asp:RadioButtonList>

                    <!-- UPDATED! - keep the old values in a hidden field -->
                    <asp:HiddenField runat="server" ID="hfOldScore" Value='<%# Eval("Score") %>' />                    
                </ItemTemplate>
            </asp:TemplateField>
        </Columns>
    </asp:GridView>         

调整 .ASPX.CS 文件中的代码隐藏值(问题 2)

在后面的代码中,您还需要:

  1. 确保在 Page_Load 中只绑定(bind)到 GridView 一次事件,通过检查 IsPostBack属性(property)
  2. (可选,但推荐)将获取数据的逻辑(使用 SQLConnection 代码)移动到一个单独的方法中,该方法将仅处理数据检索
  3. 实现 OnRowDataBound 的处理程序事件。这将绑定(bind)来自 Score 的任何值列到 RadioButtonList控制
  4. 实现 SelectedIndexChecked 的处理程序RadioButtonList 事件控制。这将允许您将新值保存到数据库中

最后,这是完整的代码隐藏代码:

protected void Page_Load(object sender, EventArgs e)        
    {
        //bind only the first time the page loads
        if (!IsPostBack)
        {                
            DataSet ds = GetData(sqlSel);

            if (ds.Tables.Count > 0)
            {
                GridView1.DataSource = ds;
                GridView1.DataBind();
            }
            else
            {
                Response.Write("Unable to connect to the database.");
            }
        }
    }

    private DataSet GetData(string cmdSel)
    {
        //normally you should query the data from the DB
        //I've manually constructed a DataSet for simplification purposes
        DataSet ds = new DataSet();
        DataTable dt = new DataTable();
        dt.Columns.Add(new DataColumn("ImageID", typeof(int)));
        dt.Columns.Add(new DataColumn("FileName", typeof(string)));
        dt.Columns.Add(new DataColumn("Score", typeof(int)));

        dt.Rows.Add(100, @"Images/beads.png", 0);
        dt.Rows.Add(200, @"Images/moreimages/scenary.jpeg", 3);
        dt.Rows.Add(300, @"Images/moreimages/scenary.jpeg", 5);


        ds.Tables.Add(dt);

        return ds;
    }

    protected void Button1_Click(object sender, EventArgs e)
    {
        //UPDATED - iterate through all the data rows and build a dictionary of items
        //to be saved
        Dictionary<int, int> dataToUpdate = new Dictionary<int, int>();
        foreach (GridViewRow row in GridView1.Rows)
        {
            if (row.RowType == DataControlRowType.DataRow)
            {
                int imageID = (int)GridView1.DataKeys[row.RowIndex].Value;
                int oldScore;
                int newScore; 

                int.TryParse((row.FindControl("hfOldScore") as HiddenField).Value, out oldScore);
                int.TryParse((row.FindControl("test") as RadioButtonList).SelectedValue, out newScore);

                if (oldScore != newScore)
                {
                    dataToUpdate.Add(imageID, newScore);
                }
            }
        }

        //update only the images that were changed
        foreach (var keyValuePair in dataToUpdate)
        {
            SaveToDB(keyValuePair.Key, keyValuePair.Value);
        }
    }

    protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
    {
        //we are only interested in the data Rows
        if (e.Row.RowType == DataControlRowType.DataRow)
        {
            DataRow dataRow = (e.Row.DataItem as DataRowView).Row;
            //manually bind the Score column to the RadioButtonlist
            int? scoreId = dataRow["Score"] == DBNull.Value ? (int?)null : (int)dataRow["Score"];
            if (scoreId.HasValue)
            {
                RadioButtonList test = e.Row.FindControl("test") as RadioButtonList;
                test.ClearSelection();                    
                test.SelectedValue = scoreId.Value.ToString();
            }
        }
    }

    protected void test_SelectedIndexChanged(object sender, EventArgs e)
    {
        RadioButtonList test = sender as RadioButtonList;
        GridViewRow gridRow = test.NamingContainer as GridViewRow;

        //obtain the current image Id
        int imageId = (int)GridView1.DataKeys[gridRow.RowIndex].Value;

        //obtain the current selection (we will take the first selected checkbox
        int selectedValue = int.Parse(test.SelectedValue);

        //UPDATED! - saves are now handled on the Save button click
        //SaveToDB(imageId, selectedValue);

    }

    private void SaveToDB(int imageId, int score)
    {
        //UPDATED!
        using (SqlConnection connection = new SqlConnection(ConfigurationManager.ConnectionStrings["SQLConnectionString"].ConnectionString))
        {
            connection.Open();
            using (SqlCommand command = connection.CreateCommand())
            {
                command.Parameters.Add("@ImageID", imageId);
                command.Parameters.Add("@Score", score);
                command.CommandText = @"update [db1].[ImagesTest] set Score = @Score where [ImageID] = @ImageID";
                command.ExecuteNonQuery();
            }
        }

    }

已更新!

  • 声明GridView1现在包含一个包含分数值的隐藏字段。您可以使用此隐藏字段来确定哪一行发生了更改,因此您可以仅在更改的行上触发保存
  • 通过遍历网格的行并构建一个 Dictionary<int,string>,现在单击“保存”按钮即可完成保存。只保留更改。
  • SaveToDB方法应该有效,但我无法自己测试。

关于c# - 模板字段中的 ASP.NET c# 复选框列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21331085/

相关文章:

c# - 如果枚举用作方法参数,是否始终需要在 C# 中进行强制转换?

c# - A* 表示认识到实现目标是不可能的

c# - 无法找到该资源。 MVC4

ASP.NET SPA 作为 Silverlight 的替代品?

android - 如何在android中的Gridview中实现图片库?

c# - MVVM 中的 DataGridComboBoxColumn SelectionChanged 事件

c# - 您如何声明类型为 'enum' 的参数(即它可以采用任何枚举)?

html - <hr> 在页脚上方的页面底部

android - Tab+滑动手势、自定义 GridView 、 fragment

asp.net - 当文本框值与特定 gridview 列值匹配时,更改 Gridview 行的颜色