У меня есть список со списком элементов, которые загружаются при переходе на определенную страницу. Затем у меня есть щелчок, который передает параметры методу AddProducts. Этот метод перебирает все выбранные элементы и вставляет значения из заполненных полей, а также берет значения из listItems и добавляет их в качестве параметров в хранимую процедуру.
Проблема, с которой я сталкиваюсь, заключается в том, что при циклическом просмотре listItems if (selectedItem.Selected) возвращает false, но в моем методе, где я загружаю список, я инициализирую SelectedValue, поэтому я не уверен, почему он дает мне сообщение об ошибке, которое у меня есть для выбранных элементов. Вчера мне удалось заставить его работать, прежде чем я переместил LoadListBoxCategories за пределы LoadAddData, но не уверен, почему это повлияет на if (listItem.Selected).
Я относительно новичок в asp.net, поэтому любая помощь/объяснение того, почему мой код не работает, чрезвычайно ценится. Я провел последние три дня, пытаясь понять это, и не нашел решения, которое работает.
Код:
Страница_Загрузка:
protected void Page_Load(object sender, EventArgs e)
{
if (Session[IS_LOGGED_IN] == null)
{
Response.Redirect("/utilities/companydata/login.aspx", true);
return;
}
gvTextInputs.RowEditing += new GridViewEditEventHandler(gvTextInputs_RowEditing);
if (!IsPostBack)
{
string pageId = Request.QueryString["pageid"];
string productId = Request.QueryString["productid"];
/* Add Mode */
if (!string.IsNullOrEmpty(pageId))
{
SetMode(MODE_ADD, "");
LoadAddData(pageId);
LoadListBoxCategories(pageId);
}
else if (!string.IsNullOrEmpty(productId))
{
string imageServer;
if (LoadProductData(productId, out imageServer))
{
InitImageGridview();
InitTextGridview();
InitStaticGridview();
SetMode(MODE_EDIT, imageServer);
SetImageServer(imageServer);
}
else
{
//TO DO - Return Error
}
}
}
else
{
InitImageGridview();
InitTextGridview();
InitStaticGridview();
}
}
Загрузить список:
private void LoadListBoxCategories(string pageId)
{
listBoxCategories.Visible = true;
//This gets query is so I can store the CompanyId and the CombinedValue data from pageId
string select = "SELECT companyName, cl.GbsCompanyId, cl.companyId, wpt.productTypeId, productName, (CAST(wp.pageId as varchar(200)) +'|'+ CAST(wp.productTypeId as varchar(200)) + '|' ) AS CombinedValue FROM CompanyList cl, WtpPages wp, WtpProductTypes wpt WHERE cl.companyId=wp.companyId AND wpt.productTypeId=wp.productTypeId AND wp.pageId=@pageId";
SqlDataSource connectionId = new SqlDataSource(DB_CONNECT, select);
connectionId.SelectParameters.Add("pageId", pageId);
DataView dView = (DataView)connectionId.Select(DataSourceSelectArguments.Empty);
if (dView.Table.Rows.Count == 1)
{
string companyId = dView.Table.Rows[0]["companyId"].ToString();
string curCategoryProductTypeId = dView.Table.Rows[0]["CombinedValue"].ToString();
// EXEC MCAdmin_GetAllCategoriesByCompanyId @companyId
// Lists All Categories @companyId has Active
string selectLoadData = "EXEC MCAdmin_GetAllCategoriesByCompanyId @companyId";
SqlDataSource conn = new SqlDataSource(DB_CONNECT, selectLoadData);
conn.SelectParameters.Add("companyId", companyId);
lstCategoriesBox.Items.Clear();
lstCategoriesBox.Items.Add(new ListItem("--Select--", null));
lstCategoriesBox.DataTextField = "productName";
lstCategoriesBox.DataValueField = "CombinedValue";
// Pre-selects the value of the productTypeId you are trying to add a product for
// to send later run against a foreach insert in AddProduct()
lstCategoriesBox.SelectedValue = curCategoryProductTypeId;
testOutcomeCategory.InnerText = curCategoryProductTypeId;
lstCategoriesBox.DataSource = conn;
lstCategoriesBox.DataBind();
}
}
ДобавитьПродукт:
private string AddProduct(string companyId, out string errMsg)
{
foreach (ListItem selectedItem in lstCategoriesBox.Items)
{
if (selectedItem.Selected)
{
// assign current productTypeId & pageId from selected Categories new CombinedValue column
string[] splitColumnValue = selectedItem.Value.Split('|');
string selectedPageId = splitColumnValue[0].ToString();
string selectedProductTypeId = splitColumnValue[1].ToString();
SqlDataSource connnection = new SqlDataSource(DB_CONNECT, "");
connnection.InsertCommand = "EXEC MCAdmin_AddProductFromClassic @pageId, @productTypeId, @productCode, @imgDirectory, @numSides, @sortOrder, @isActive, @template, @template2, @template3, @EditorJson, @MockupTemplateBase, @MockupTemplateTreatment, @BorderDefault ";
connnection.InsertParameters.Add("pageId", selectedPageId);
connnection.InsertParameters.Add("productTypeId", selectedProductTypeId);
connnection.InsertParameters.Add("productCode", txtProductCode.Text);
connnection.InsertParameters.Add("numSides", ddlNumSides.SelectedValue);
connnection.InsertParameters.Add("sortOrder", txtSortOrder.Text);
connnection.InsertParameters.Add("isActive", ddlActive.SelectedValue);
connnection.InsertParameters.Add("template", txtTemplate1.Text);
connnection.InsertParameters.Add("template2", txtTemplate2.Text);
connnection.InsertParameters.Add("template3", txtTemplate3.Text);
connnection.InsertParameters.Add("EditorJson", txtJson.Text);
connnection.InsertParameters.Add("MockupTemplateBase", txtMockupTemplateBase.Text);
connnection.InsertParameters.Add("MockupTemplateTreatment", txtMockupTemplateTreatment.Text);
connnection.InsertParameters.Add("BorderDefault", txtBorderDefault.Text);
/* Special Product Code for Upload Artwork Business Card */
if (txtProductCode.Text.ToUpper() == "BPFAH1-001-100")
{
connnection.InsertParameters.Add("imgDirectory", "/images/business-cards/general/");
}
else
{
connnection.InsertParameters.Add("imgDirectory", ddlImgDir.SelectedValue);
}
int result = connnection.Insert();
if (result > 0)
{
SqlDataSource connect = new SqlDataSource(DB_CONNECT, "");
connect.SelectCommand = "SELECT TOP 1 wtpProductId FROM WtpProducts ";
connect.SelectCommand = "WHERE productTypeId=@productTypeId AND pageId=@pageId DESC ";
connect.SelectParameters.Add("pageId", selectedPageId); //
connect.SelectParameters.Add("productTypeId", selectedProductTypeId); //
DataView dView = (DataView)connect.Select(DataSourceSelectArguments.Empty);
if (dView.Table.Rows.Count == 1)
{
string wtpProductId = dView.Table.Rows[0]["wtpProductId"].ToString();
errMsg = "";
return wtpProductId;
}
else
{
errMsg = "ERROR: Could not get productId of newly created Product.";
return "0";
}
}
else
{
errMsg = "ERROR: Could not add WtpProduct record to DB";
return "0";
}
}
else
{
errMsg = "ERROR: You must select a Category";
return "0";
}
}
errMsg = "ERROR: Did not make it into the foreach loop";
return "0";
}
Метод OnClick:
protected void OnClick_btnAddProduct(object sender, EventArgs e)
{
string pageId = Request.QueryString["pageid"];
testOutcomeCategory.InnerText = lstCategoriesBox.SelectedValue; // This proves that I have something selected!!!
string select = "SELECT companyName, cl.GbsCompanyId, cl.companyId, wpt.productTypeId, productName, baseImgDirectory, templateDirectory, wp.imageServer FROM CompanyList cl, WtpPages wp, WtpProductTypes wpt WHERE cl.companyId=wp.companyId AND wpt.productTypeId=wp.productTypeId AND wp.pageId=@pageId";
SqlDataSource conn = new SqlDataSource(DB_CONNECT, select);
conn.SelectParameters.Add("pageId", pageId);
DataView dView = (DataView)conn.Select(DataSourceSelectArguments.Empty);
if (dView.Table.Rows.Count == 1)
{
string companyId = dView.Table.Rows[0]["companyId"].ToString();
if (!string.IsNullOrEmpty(pageId))
{
string errMsg;
string productId = AddProduct(companyId, out errMsg);
if (productId != "0")
{
Response.Redirect("/utilities/companydata/add-edit-wtp-product.aspx?productid = " + productId, true);
SetStatusMsg("Success", false);
}
else
{
SetStatusMsg(errMsg, true);
}
}
}
}
Это не изменилось, я думал, что вчера, но это было все так же. @jdweng
Является ли pageId строкой или целым числом?
@jdweng это строка
Что они делают? InitImageGridview(); InitTextGridview(); InitStaticGridview();
Если они изменяют список, то этот код будет запущен еще до того, как вы нажмете кнопку. Помните, что сначала будут запускаться события Page_Load, а затем событие нажатия кнопки.
Эти методы обрабатывают только элементы HTML, которые не имеют ничего общего с ListBox. @JohnPete22
Это «I» в нижнем или верхнем регистре pageId? string pageId = Request.QueryString["pageid"];
Почему у вас есть проверка !PostBack
внутри вашей функции LoadListBoxCategories
? Если вы отлаживаете, вызывается ли эта функция при обратных передачах? Кажется, что функция вызывается только внутри проверки !PostBack
на Page_Load
, но дополнительная логическая проверка внутри этой функции выглядит так, как будто она может быть вызвана где-то еще.
Извините, но это нужно спросить, вы прошли весь процесс с помощью отладчика?
@mxmissile Я не понял, как подключить отладчик к ASP-сайту хоста iisexpress
ОБНОВЛЕНИЕ: я только что понял это! Так глупо, но когда я проверяю if (selectedItem.Selected), так как я перебираю элементы ListBox, он начинается с первого индекса ListBox, а поскольку первый не выбран, то если он переходит в блок else. Удалите остальное, и все заработает.
Экземпляр списка воссоздается на стороне сервера во время обратной передачи (как и вся страница). Вы не устанавливаете выбранные элементы в обработчике события Page_Load - if (!IsPostBack)
переходит в другую ветку. Вот почему вы их не видите.
Я знаю, что if (!IsPostBack)
никогда не переходит в else, потому что вызываемые методы просто делают HTML-элементы видимыми, и при каждой загрузке эти HTML-элементы невидимы, при загрузке и после OnClick. Также для ListBox SelectionMode установлено значение Multiple, поэтому даже когда я нажимаю несколько элементов списка, я все равно получаю ту же ошибку.
В порядке,
lstCategoriesBox.Items.Clear();
Хорошо, выше идет ядерный - выдувает список, выдувает выбор.
Хорошо, это нормально
lstCategoriesBox.Items.Add(new ListItem("--Select--", null));
lstCategoriesBox.DataTextField = "productName";
lstCategoriesBox.DataValueField = "CombinedValue";
Хорошо, выше добавляет новый элемент. Должно быть в порядке, но нужно настроить lb ПЕРЕД добавлением любых данных, включая эту строку «--select--».
Просто имеет смысл «настроить» lb, а ЗАТЕМ начать добавлять данные, верно? Однако, но, если вышеприведенное работает - хорошо, тогда давайте продолжим, но я бы настроил lb перед добавлением каких-либо строк данных. Скажите так:
lstCategoriesBox.DataTextField = "productName";
lstCategoriesBox.DataValueField = "CombinedValue";
lstCategoriesBox.Items.Add(new ListItem("--Select--", null));
Теперь следующая строка:
lstCategoriesBox.SelectedValue = curCategoryProductTypeId;
Ой! - мы только что очистили фунт, а теперь пытаемся установить для него значение? Вы не можете этого сделать - фунт только что был очищен, верно? Вам нужно сначала загрузить фунты, а ЗАТЕМ вы можете установить выбранное значение, верно?
Я мог бы что-то упустить здесь, но этот lb должен быть загружен действительными данными ДО того, как вы попытаетесь установить выбранное значение?
Думаю, я следую. Итак, вы говорите это, потому что у меня есть lstCategoriesBox.Clear();
, когда срабатывает OnClick, мой список очищается до того, как будет установлено какое-либо значение? Итак, если я удалю Clear () и перестрою данные для загрузки перед добавлением нового элемента, тогда можно установить lstCategoriesBox.SelectedValue = curCategoryProductId;
?
да, вы, вероятно, хотите загрузить lb только один раз и только при загрузке первой страницы (isPostBack = false). но да, похоже, вы очищаете lb, а затем пытаетесь установить значение до того, как оно будет загружено. Возможно, я не следую всему коду, но этот код только что очистил lb, а затем мы пытаемся установить для него значение — это не сработает.
Хорошо, я удалил очистку и переставил нагрузку в фунтах, чтобы данные добавлялись первыми перед добавлением элемента. Хотя я все еще получаю ту же ошибку, когда нажимаю кнопку, которая вызывает AddProduct. Я отредактирую пост и добавлю метод OnClick
Я отредактировал исходный пост. Надеюсь, это даст немного больше информации о том, что происходит.
Чтобы сначала протестировать, измените следующее
Outcome Category.InnerText = list CategoriesBox.SelectedValue;
к
Category.InnerText = Request.Form["CategoriesBox-ClientID"]
Если данные поступают правильно, представление списка очищается или перезагружается между событиями перезагрузки и клика на странице.
В Form[""]
я бы поместил идентификатор формы или идентификатор ListBox?
Я пробовал оба и ничего не заселено
Нет, в элементах формы aspx есть другой идентификатор, например contentplaceholder1_ListBox1, который вы можете получить в исходном коде html.
Вот это я тоже поменял testOutcomeCategory.InnerText = Request.Form["listBoxCategories-ClientID"];
И ничего не получил
ОБНОВЛЕНИЕ: я только что понял это! Так глупо, но когда я проверяю if (selectedItem.Selected), так как я перебираю элементы ListBox, он начинается с первого индекса ListBox, а поскольку первый не выбран, то если он переходит в блок else. Убери остальное и все заработает
Изменился ли идентификатор страницы при перемещении кода?