WPF中从数据库填充ListBox并获取选中项对应数据的问题
WPF ListBox选中项获取完整UserInfo数据解决方案
问题根源
你当前的代码只把modCode字符串添加到ListBox中,丢失了对应行的其他字段信息,所以选中时无法直接获取完整数据。需要修改填充逻辑,让ListBox的每个Item携带整条记录的信息,同时保持显示modCode。
方案一:直接绑定DataRow(快速实现)
1. 修改数据填充代码
首先修改SQL查询,获取完整的用户信息行,然后将DataRow添加到ListBox,同时指定显示modCode字段:
// 改用参数化查询避免SQL注入 string com = "SELECT * FROM UserInfo WHERE UserID = @UserID"; SqlDataAdapter adpt = new SqlDataAdapter(com, con); // 添加参数 adpt.SelectCommand.Parameters.AddWithValue("@UserID", CommonClass.userID); DataSet myDataSet = new DataSet(); adpt.Fill(myDataSet, "UserInfo"); DataTable myDataTable = myDataSet.Tables[0]; // 设置ListBox显示modCode字段 listbox.DisplayMemberPath = "modCode"; // 将整个DataRow添加到Items,而不是只加modCode字符串 foreach (DataRow row in myDataTable.Rows) { listbox.Items.Add(row); }
2. 处理SelectionChanged事件
在XAML中给ListBox添加SelectionChanged事件:
<ListBox x:Name="listbox" SelectionChanged="ListBox_SelectionChanged"/>
然后在后台代码中实现事件逻辑,获取选中的DataRow并提取其他字段:
private void ListBox_SelectionChanged(object sender, SelectionChangedEventArgs e) { if (listbox.SelectedItem is DataRow selectedRow) { // 获取其他字段值,注意字段名要和数据库表一致 string modName = selectedRow["modName"].ToString(); int credits = Convert.ToInt32(selectedRow["credits"]); int? classPW = selectedRow["ClassPW"] != DBNull.Value ? Convert.ToInt32(selectedRow["ClassPW"]) : null; // 这里可以将数据显示到界面控件,比如TextBox、Label等 // 示例:modNameLabel.Content = modName; } }
方案二:使用自定义实体类(更规范的MVVM友好方式)
1. 创建UserInfo实体类
public class UserInfo { public int UserID { get; set; } public string ModName { get; set; } public string ModCode { get; set; } public int Credits { get; set; } public int? ClassPW { get; set; } }
2. 修改填充代码,映射到实体类
string com = "SELECT * FROM UserInfo WHERE UserID = @UserID"; SqlDataAdapter adpt = new SqlDataAdapter(com, con); adpt.SelectCommand.Parameters.AddWithValue("@UserID", CommonClass.userID); DataTable dt = new DataTable(); adpt.Fill(dt); // 将DataTable转换为UserInfo列表 List<UserInfo> userInfoList = new List<UserInfo>(); foreach (DataRow row in dt.Rows) { userInfoList.Add(new UserInfo { UserID = Convert.ToInt32(row["UserID"]), ModName = row["modName"].ToString(), ModCode = row["modCode"].ToString(), Credits = Convert.ToInt32(row["credits"]), ClassPW = row["ClassPW"] != DBNull.Value ? Convert.ToInt32(row["ClassPW"]) : null }); } // 绑定到ListBox listbox.DisplayMemberPath = "ModCode"; listbox.ItemsSource = userInfoList;
3. 处理选中事件
private void ListBox_SelectionChanged(object sender, SelectionChangedEventArgs e) { if (listbox.SelectedItem is UserInfo selectedInfo) { // 直接访问实体类属性 string modName = selectedInfo.ModName; int credits = selectedInfo.Credits; // 后续逻辑... } }
重要提醒
- 永远不要用字符串拼接SQL语句,改用参数化查询避免SQL注入风险,上面的代码已经做了修改。
- 如果使用MVVM模式,可以绑定
SelectedItem到ViewModel的属性,无需手动处理SelectionChanged事件。
内容的提问来源于stack exchange,提问作者Prof. Gaming
相关产品推荐
相关产品推荐

