J'ai cette asp: gridview dans laquelle je montre des données en utilisant la procédure stockée mySql. J'ai cette liste nommée ddlstatus que j'utilise pour filtrer les données. J'utilise viewstate pour afficher les données sélectionnées dans la zone de liste. Le problème est que je veux faire une sélection multiple sur cette listbox et afficher les données pour chaque sélection effectuée dessus, mais quand elle n'affiche que les données de la sélection initiale.
Voici le code côté client:
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
Voici le code côté serveur:
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; }
Voici la procédure stockée MySql:
<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>
3 Réponses :
Tout d'abord, la publication automatique ne vous permet pas de sélectionner plusieurs éléments car jusqu'à ce que le deuxième élément soit sélectionné, la publication se produit déjà par le premier élément sélectionné,
Vous devez définir AutoPostBack = "false" code> pour votre zone de liste,
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
Pour collecter plusieurs éléments sélectionnés, nous choisissons simplement le bouton par exemple, vous pouvez collecter ces éléments où vous voulez,
Ensuite, ajoutez un bouton qui appellera le code ci-dessous
protected void Page_Load(object sender, EventArgs e) { if (!Page.IsPostBack) { //Populate your list box here } }
Sur le gestionnaire d'événements du bouton ci-dessus, ajoutez le code ci-dessous,
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.
Puis le les éléments séparés par des virgules dans votre ViewState
seront utilisés dans votre paramètre de procédure stockée
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; }
Si vous remplissez votre zone de liste sur Page Load code > puis assurez-vous de le remplir dans
! Page.IsPostBack
comme
<asp:Button ID="button1" runat="server" OnClick="button1_Click" Text="Click"/>
Et votre SP est
<asp:ListBox ID="ddlstatus" runat="server" AutoPostBack="false" AppendDataBoundItems="true" SelectionMode="Multiple"></asp:ListBox>
Avez-vous reçu plusieurs valeurs en cliquant sur le bouton? Ajouter un point d'arrêt sur la ligne => var selectedNames ..
J'obtiens l'erreur "La référence d'objet n'est pas définie sur une instance d'un objet."
Erreur Sur quelle ligne?
continuons cette discussion dans le chat .
Le tableau de chaînes passe-t-il au paramètre SP?
Hé frère, pouvons-nous nous connecter à ce sujet aujourd'hui?
@prkash, Oh votre commentaire n'apparaît pas dans ma notification donc je n'ai pas remarqué. Et oui, nous pouvons nous connecter demain, mais certaines personnes refusent ma réponse. Je vais donc le supprimer une fois votre problème résolu.
Lors de l'application du SP ci-dessus pour le filtrage de plusieurs listes déroulantes, je devrai créer autant de combinaisons pour que cela fonctionne, je dois encore trouver un moyen d'obtenir la même chose pour plusieurs listes déroulantes
Oui, je pense que le nombre de combinaisons est indispensable, mais SP fonctionne-t-il pour plusieurs combinaisons?
Je pense que si vous postez sur SO, vous obtiendrez probablement une meilleure réponse de la part des gars de my-sql. parce que son SP compliqué à écrire pour nous. Tout expert vous donnera une meilleure solution
Si vous prévoyez de publier sur SO, mentionnez ce que nous avons fait hier avec SP avec un seul paramètre et que vous souhaitez faire de même avec plusieurs paramètres.
ok bro, j'essaye quelque chose de différent maintenant, au lieu d'utiliser SP, j'écris la requête sur le code. Je vais vous mettre à jour comment ça se passe
Bro cette méthode semble fonctionner, mais il y a un problème mineur, pouvons-nous nous connecter?
stackoverflow.com/questions/55569672/...
Veuillez créer une listbox multiple
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 />"; } } }
Puis côté serveur void SubmitBtn_Click (Expéditeur de l'objet, EventArgs e) {
<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>
Il y a quelques problèmes que j'ai pu repérer et qui devront peut-être être résolus,
Assurez-vous que la méthode BindDropDownList
n'est appelée que sur une publication non (actualisation de la page), car votre méthode PopulateDropDown
efface les éléments de la liste, ce qui signifie cet état d'affichage ne peut pas être restauré dans une publication, d'où la raison probable pour laquelle un seul élément est sélectionné.
Je ne suis pas à 100% du schéma de la table, mais le SQL fourni ne semble pas pouvoir interroger correctement par plus d'un état, vous devriez probablement envoyer une liste de valeurs séparées par des virgules, et en SQL transformez-les en une table temporaire afin de rechercher efficacement les éléments avec plusieurs statuts (vous devriez probablement créer une nouvelle question pour cela).
N'utilisez pas SelectedItem
pour les sélections multiples, vous devez à la place itérer vos éléments de liste pour ceux qui sont sélectionnés, et vous n'avez pas besoin d'utiliser ViewState code > pour le transmettre (vous l'avez probablement fait à cause du point 1 ci-dessus). Par exemple, vous pouvez remplacer votre méthode
BindGrid
et DropDownChange
par:
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(); }
désolé, vous avez raison, j'espérais que ma réponse clarifierait le vote défavorable. En gros, vous n'avez pas besoin de changer l'interface utilisateur (ajouter un bouton, et désactiver l'autopostback sur la liste) si le problème principal réel est résolu, la liste déroulante étant rebondie sur une publication (1.) et que sur votre réponse vous avez gardé l'utilisation de viewstate pour passer la valeur de statut est également une surcharge inutile (et la taille de viewstate) et vous n'avez pas réussi à résoudre le problème avec la procédure (2.) car c'est mysql Je n'ai pas de réponse spécifique, mais je suis sûr que quelqu'un sinon.
J'ai donné une solution comme sur ma réponse au problème d'OP après avoir analysé le code source complet via un accès à distance via TeamViewer. L'état de vue est obligatoire pour lui. Je pense que vous devriez annuler ma réponse. Parce que vous donneriez une solution basée sur une approche primaire et directe sans connaître le code source complet d'OP. :)
cela signifie que si vous choisissez quatre éléments dans la zone de liste, vous ne recevez que la première valeur de l'élément sur la ligne
string selectedValue = dropdown.SelectedItem.Value;
dans le gestionnaire d'événementsDropDownChange
, n'est-ce pas? puis chargement des données pour cet élément uniquement@ er-sho oui et aussi après la publication, les trois autres éléments ne sont pas sélectionnés dans la liste
savez-vous comment passer plusieurs valeurs à un seul paramètre dans une procédure stockée, par exemple si je sélectionne
a
,b
,c
alors celles-ci seront transmises dans votre SP avec le paramètrestatusVal
?@ er-sho ouais nous devons utiliser IN, non? mais pouvons-nous le faire en utilisant foreach (ListItem Item1 in ddlstatus.items) {} à la place?
Alors, comment est le besoin d'entrée pour ce paramètre
statusVal
? signifie son tableau comme["a", "b", "c"]
ou seulement une chaîne commea, b, c
?@ er-sho chaîne normale uniquement
@ er-sho ok bro :)
Montrez-nous le SQL généré; Je pense que cela rendra le problème évident.