asp: фильтр вида сетки с использованием списка не может сделать множественный выбор - PullRequest
0 голосов
/ 27 февраля 2019

У меня есть asp: gridview, в котором я показываю данные, используя хранимую процедуру mySql.У меня есть этот список с именем ddlstatus, который я использую для фильтрации данных.Я использую viewstate, чтобы показать данные, которые выбраны из списка.Проблема в том, что я хочу сделать множественный выбор в этом списке и показать данные для каждого сделанного в нем выбора, но когда он показывает только данные для первоначального выбора.

Ниже приведен код на стороне клиента:

<asp:Label ID="lblstat" Text="status" Visible="false" runat="server"></asp:Label>
<asp:ListBox ID="ddlstatus" runat="server" OnSelectedIndexChanged="DropDownChange" AutoPostBack="true" AppendDataBoundItems="true" SelectionMode="Multiple"></asp:ListBox>

<asp:GridView ID="gdvTM" runat="server" ControlStyle-Width="100%"  AutoGenerateColumns="False" DataKeyNames="ID" OnRowDeleting="gdvTM_RowDeleting" PageSize="5" CssClass="cssgridview" AlternatingRowStyle-BackColor="#d5d8dc">
    <Columns >
       <asp:TemplateField HeaderText="Current Status">
         <ItemTemplate >
             <asp:Label ID="lblcstat" runat="server" Text='<%# Eval("status") %>'></asp:Label>
        </ItemTemplate>
      </asp:TemplateField>
    </Columns>
</asp:GridView>

Ниже приведен код на стороне сервера:

private void BindDropDownList()
{
    PopulateDropDown(ddlstatus, lblstat.Text);
}
private void PopulateDropDown(ListBox ddl, string columnName)
{
    ddl.Items.Clear();
    ddl.DataSource = BindDropDown(columnName);
    ddl.DataTextField = columnName;
    ddl.DataValueField = columnName;
    ddl.DataBind();
    ddl.Items.Insert(0, new ListItem("Please select", "0"));
}
private void BindGrid()
{
    DataTable dt = new DataTable();
    String strConnString = System.Configuration.ConfigurationManager.ConnectionStrings["connStr"].ConnectionString;
    MySqlConnection con = new MySqlConnection(strConnString);
    MySqlDataAdapter sda = new MySqlDataAdapter();
    MySqlCommand cmd = new MySqlCommand("GetTMData");
    cmd.CommandType = CommandType.StoredProcedure;  
    string statusVal = null;
    if (ViewState["stat"] != null && ViewState["stat"].ToString() != "0")
    {
        statusVal = ViewState["stat"].ToString();
    }
    cmd.Parameters.AddWithValue("statusVal", statusVal);
    cmd.Connection = con;
    sda.SelectCommand = cmd;
    sda.Fill(dt);
    gdvTM.DataSource = dt;
    int i = dt.Rows.Count;
    gdvTM.DataBind();
    this.BindDropDownList();
    TableCell cell = gdvTM.HeaderRow.Cells[0];
    setDropdownselectedItem(ViewState["stat"] != null ? (string)ViewState["stat"] : string.Empty, ddlstatus);
}
private void setDropdownselectedItem(string selectedvalue, ListBox ddl)
{
    if (!string.IsNullOrEmpty(selectedvalue))
    {
         ddl.Items.FindByValue(selectedvalue).Selected = true;

    }
}
protected void DropDownChange(object sender, EventArgs e)
 {
      ListBox dropdown = (ListBox)sender;
      string selectedValue = dropdown.SelectedItem.Value;
      switch (dropdown.ID.ToLower())
      {
          case "ddlstatus":
             ViewState["stat"] = selectedValue;
             break;
      }

      this.BindGrid();
 }

private DataTable BindDropDown(string columnName)
{
    string username = uName.Text;
    String strConnString = System.Configuration.ConfigurationManager.ConnectionStrings["connStr"].ConnectionString;
    MySqlConnection con = new MySqlConnection(strConnString);
    MySqlCommand cmd = new MySqlCommand("SELECT DISTINCT (" + columnName + ") FROM approved WHERE tm = @tm AND " + columnName + " IS NOT NULL", con);
    MySqlDataAdapter sda = new MySqlDataAdapter(cmd);
    cmd.Parameters.AddWithValue("@tm", username);
    DataTable dt = new DataTable();
    sda.Fill(dt);
    return dt;
}

Ниже представлена ​​хранимая процедура MySql:

CREATE DEFINER=`root`@`localhost` PROCEDURE `GetTMData`(in statusVal varchar(45))
BEGIN
SELECT *
   FROM approved
   WHERE (statusVal IS NULL
                OR status = statusVal)
         order by date desc;
END

Как это сделать?Заранее спасибо.

Ответы [ 3 ]

0 голосов
/ 04 марта 2019

Пожалуйста, сделайте список несколько ...

<asp:ListBox id="ListBox1" 
           Rows="6"
           Width="100px"
           **SelectionMode="Multiple"** 
           runat="server">

         <asp:ListItem Selected="True">Item 1</asp:ListItem>
         <asp:ListItem>Item 2</asp:ListItem>
         <asp:ListItem>Item 3</asp:ListItem>
         <asp:ListItem>Item 4</asp:ListItem>
         <asp:ListItem>Item 5</asp:ListItem>
         <asp:ListItem>Item 6</asp:ListItem>

      </asp:ListBox>

Затем на стороне сервера void SubmitBtn_Click (Отправитель объекта, EventArgs e) {

     Message.Text = "You chose: <br />";

     // Iterate through the Items collection of the ListBox and 
     // display the selected items.
     foreach (ListItem item in ListBox1.Items)
     {

        if(item.Selected)
        {

           Message.Text += item.Text + "<br />";

        }

     }

  }
0 голосов
/ 06 марта 2019

Есть несколько проблем, которые я мог бы заметить, которые, возможно, нужно будет решить,

  1. Убедитесь, что метод BindDropDownList вызывается только без обратной передачи (обновление страницы), потому чтоВаш метод PopulateDropDown очищает элементы списка, что означает, что состояние представления не может быть восстановлено в обратной передаче, следовательно, возможная причина, по которой выбирается только один элемент.

  2. Яне 100% от схемы таблицы, но предоставляемый SQL, по-видимому, не способен правильно запрашивать более чем один статус, вам, вероятно, следует отправить список значений через запятую, а в SQL превратить их во временную таблицу, чтобы вы моглиэффективно выполнять поиск элементов с несколькими статусами (вам, вероятно, следует создать новый вопрос для этого).

  3. Не используйте SelectedItem для множественного выбора, вместо этого вам нужно выполнить итерации элементов списка дляте, которые выбраны, и вам не нужно использовать ViewState, чтобы передать его (вы, вероятно, сделали это из-за пункта 1. выше).Например, вы можете заменить ваш метод BindGrid и DropDownChange на:

private void BindGrid()
{
    DataTable dt = new DataTable();
    String strConnString = System.Configuration.ConfigurationManager.ConnectionStrings["connStr"].ConnectionString;
    MySqlConnection con = new MySqlConnection(strConnString);
    MySqlDataAdapter sda = new MySqlDataAdapter();
    MySqlCommand cmd = new MySqlCommand("GetTMData");
    cmd.CommandType = CommandType.StoredProcedure;  
    string statusVal = null;
     foreach (ListItem item in ddlstatus.Items)
     {
        if(item.Selected)
        {
           if(statusVal.length > 0)
               statusVal += ",";
           statusVal += item.Value;
        }
     }
    cmd.Parameters.AddWithValue("statusVal", statusVal);
    cmd.Connection = con;
    sda.SelectCommand = cmd;
    sda.Fill(dt);
    gdvTM.DataSource = dt;
    gdvTM.DataBind();

}

protected void DropDownChange(object sender, EventArgs e)
 {
      this.BindGrid();
 }
0 голосов
/ 27 февраля 2019

Прежде всего, автоматическая отправка назад не позволяет вам выбрать несколько элементов, поскольку до выбора второго элемента обратная передача уже происходит по первому выбранному элементу, поэтому

Вы должны установить AutoPostBack="false" для своего списка,

<asp:ListBox ID="ddlstatus" runat="server" AutoPostBack="false" AppendDataBoundItems="true" SelectionMode="Multiple"></asp:ListBox>

Для сбора нескольких выбранных элементов мы просто выбираем, например, кнопку, вы можете собирать эти элементы в любом месте,

Затем добавьте одну кнопку, которая будет вызывать код ниже

<asp:Button ID="button1" runat="server" OnClick="button1_Click" Text="Click"/>

В указанном выше обработчике события кнопки добавьте следующий код:

protected void button1_Click(object sender, EventArgs e)
{
    var selectedNames = ddlstatus.Items.Cast<ListItem>()
                         .Where(i => i.Selected)
                         .Select(i => i.Value)
                         .ToList();

    string selectedValue = string.Join("','", selectedNames);

    selectedValue = "'" + selectedValue + "'";

    ViewState["stat"] = selectedValue;
}

Тогда разделенные запятыми элементы в вашем ViewState будут использоваться в параметре вашей хранимой процедуры

string statusVal = null;
if (ViewState["stat"] != null && ViewState["stat"].ToString() != "0")
{
    statusVal = ViewState["stat"].ToString();
}
cmd.Parameters.AddWithValue("statusVal", statusVal);  //<= Now this string variable contains comma separated list box items values.

Если вы заполняете свой список в Page_Load, убедитесь, что вы должны заполнить его в !Page.IsPostBack, как

protected void Page_Load(object sender, EventArgs e)
{
    if (!Page.IsPostBack)
    {
        //Populate your list box here
    }
}

И ваш SP будет

CREATE DEFINER=`root`@`localhost` PROCEDURE `GetTMData1`(in statusVal varchar(255))
BEGIN

IF statusVal = '\'\'' THEN 
   select * from approved;
ELSE
  SET @sql = CONCAT('SELECT * FROM approved WHERE status IN (', statusVal, ')');
  PREPARE stmt FROM @sql;
  EXECUTE stmt;
  DEALLOCATE PREPARE stmt;    
END IF ;        
END

Если вы выберите несколько элементовиз раскрывающегося списка данные параметров вашего SP выглядят как '\'apple\',\'banana\''.Если нет, то это выглядит как '\''.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...