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

时间:2014-01-24 11:07:27

标签: c# asp.net gridview

我是asp.net的新手。我在sqlserver中创建了一个包含3列的数据库表; ImageID, Filename & Score

FileName是C:\pics\beads.png or C:\pics\moreimages\scenary.jpeg

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

(第1列)ImageID并从Filename(column2)获取图像,我有2个如下所示创建的Checkboxlist,它应该接受来自用户的图像的分数并将其保存到DB表中。

问题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;
}

谢谢你的时间 Rashmi

3 个答案:

答案 0 :(得分:1)

问题2 : 要访问您的复选框,您可以使用。

 GridViewRow row = GridView1.Rows[i];
 CheckBox Ckbox = (CheckBox)row.FindControl("test");

答案 1 :(得分:1)

  

问题1

您可以使用ASP:Image in Templatefield,而不是ImageField。

<asp:TemplateField HeaderText="Score" AccessibleHeaderText="CheckBoxList" ValidateRequestMode="Enabled">
   <ItemTemplate>
      <asp:Image ID="imageControl" runat="server" ImageUrl='<%# Eval("Filename") %>'></asp:Image>
   </ItemTemplate>
</asp:TemplateField>
  

问题2

这是如何访问gridview

中每个复选框列表的示例之一
    For Each gvr As GridViewRow In Gridview1.Rows
        If (CType(gvr.FindControl("CheckBox1"), CheckBox)).Checked = True Then
            ReDim uPrimaryid(iCount)
            uPrimaryid(iCount) = New Integer
            uPrimaryid(iCount) = gvr.Cells("uPrimaryID").Text
            iCount += 1
        End If
    Next

答案 2 :(得分:1)

您的代码存在一些问题,以下是应该修复的问题:

如何修复图片(问题1)

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

为此,您需要一个名为Images的文件夹,其中包含与.aspx文件位于同一目录级别的这两个文件。

在ASPX文件中调整GridView1声明

在GridView1声明中,您应该:

  1. 将处理程序附加到OnRowDataBound事件。这样您就可以将Score数据集列正确绑定到Score gridview列
  2. 将网格上的DataKeyNames属性设置为图像表的主键(在本例中为DataKeyNames="ImageID"
  3. 使用RadioButtonList代替CheckboxList,因为根据您的数据集,您只能设置一个值,这是RadioButtonList所做的。当需要多次选择时,通常使用CheckboxList
  4. 将处理程序附加到SelectedIndexChanged上的RadioButtonList事件。这将允许您将新值保存到数据库(问题2)
  5. 以下是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属性
    2. ,确保您只在IsPostBack事件中绑定到GridView一次
    3. (可选,但建议)将获取数据的逻辑(使用SQLConnection代码)移动到仅处理数据检索的单独方法中
    4. 实施OnRowDataBound事件的处理程序。这会将Score列中的所有值绑定到RadioButtonList控件
    5. SelectedIndexChecked控件的RadioButtonList事件实现处理程序。这将允许您将新值保存到数据库
    6. 最后,这是完整的代码隐藏代码:

      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方法应该可行,但我自己无法测试。