You’ll implement the control in the following exercise.
Exercise: Implementing ProductDetailsAdmin.ascx
1. Create a new user control named ProductDetailsAdmin in the UserControls folder.
2. You need to add controls to the form, as shown in Figure 8-32. Here you meet for the first time the FileUpload control.
Figure 8-32. The product details admin page
The following is the associated source code:
<span class="AdminPageText">
<asp:Label ID="productNameLabel" runat="server" CssClass="AdminTitle" />
<asp:HyperLink ID="goBackLink" runat="server">(go back to products)
</asp:HyperLink>
<br /><br />
<asp:Label ID="statusLabel" runat="server" CssClass="AdminPageText"
Text="Product Details Loaded" ForeColor="Red"></asp:Label><br />
<br />
Product belongs to these categories:
<asp:Label ID="categoriesLabel" runat="server"></asp:Label>
<br />
Remove product from this category:
<asp:DropDownList ID="categoriesListRemove" runat="server">
</asp:DropDownList>
<asp:Button ID="removeButton" runat="server" Text="Go!"
OnClick="removeButton_Click" />
<asp:Button ID="deleteButton" runat="server" Text="DELETE FROM CATALOG"
OnClick="deleteButton_Click" /><br />
Assign product to this category:
<asp:DropDownList ID="categoriesListAssign" runat="server">
</asp:DropDownList>
<asp:Button ID="assignButton" runat="server" Text="Go!"
OnClick="assignButton_Click" />
<br />
<asp:Label ID="moveLabel" runat="server" Text="Move product to this category:"/>
<asp:DropDownList ID="categoriesListMove" runat="server" />
<asp:Button ID="moveButton" runat="server" Text="Go!"
OnClick="moveButton_Click" />
<br />
Image1 file name:
<asp:Label ID="image1FileNameLabel" runat="server" />
<asp:FileUpload ID="image1FileUpload" runat="server" />
<asp:Button ID="upload1Button" runat="server" Text="Upload" /><br />
<asp:Image ID="image1" runat="server" />
<br />
Image2 file name:
<asp:Label ID="image2FileNameLabel " runat="server" />
<asp:FileUpload ID="image2FileUpload" runat="server" />
<asp:Button ID="upload2Button" runat="server" Text="Upload" /><br />
<asp:Image ID="image2" runat="server" />
</span>
3. Open the code-behind file and complete the ProductDetailsAdmin class, as shown in the code snippet:
public partial class ProductDetailsAdmin : System.Web.UI.UserControl {
// store product, category and department IDs as class members
private string currentProductId, currentCategoryId, currentDepartmentId;
protected void Page_Load(object sender, EventArgs e) {
// Get DepartmentID, CategoryID, ProductID from the query string // and save their values
currentDepartmentId = Request.QueryString["DepartmentID"];
currentCategoryId = Request.QueryString["CategoryID"];
currentProductId = Request.QueryString["ProductID"];
// Assign buttons to the combo boxes
Utilities.TieButton(this.Page, categoriesListRemove, removeButton);
Utilities.TieButton(this.Page, categoriesListAssign, assignButton);
Utilities.TieButton(this.Page, categoriesListMove, moveButton);
// Fill the controls with data only on the initial page load if (!IsPostBack)
{
// Fill controls with data PopulateControls();
} }
// Populate the controls private void PopulateControls() {
// Set the "go back to products" link
goBackLink.NavigateUrl = Request.ApplicationPath +
String.Format("/CatalogAdmin.aspx?DepartmentID={0}&CategoryID={1}", currentDepartmentId, currentCategoryId);
// Retrieve product details and category details from database ProductDetails productDetails =
CatalogAccess.GetProductDetails(currentProductId);
CategoryDetails categoryDetails =
CatalogAccess.GetCategoryDetails(currentCategoryId);
// Set up labels and images
productNameLabel.Text = productDetails.Name;
moveLabel.Text = "Move product from category <b>" + categoryDetails.Name + "</b> to this category: ";
image1.ImageUrl = Request.ApplicationPath + "/ProductImages/" + productDetails.Image1FileName;
image2.ImageUrl = Request.ApplicationPath + "/ProductImages/" + productDetails.Image2FileName;
// Clear form
categoriesLabel.Text = "";
categoriesListAssign.Items.Clear();
categoriesListMove.Items.Clear();
categoriesListRemove.Items.Clear();
// Fill categoriesLabel and categoriesListRemove with data string categoryId, categoryName;
DataTable productCategories =
CatalogAccess.GetCategoriesWithProduct(currentProductId);
for (int i = 0; i < productCategories.Rows.Count; i++) {
// obtain category id and name
categoryId = productCategories.Rows[i]["CategoryId"].ToString();
categoryName = productCategories.Rows[i]["Name"].ToString();
// add a link to the category admin page
categoriesLabel.Text += (categoriesLabel.Text == "" ? "" : ", ") + "<a href=\"" + Request.ApplicationPath + "/CatalogAdmin.aspx" + "?DepartmentID=" +
CatalogAccess.GetCategoryDetails(currentCategoryId).DepartmentId + "&CategoryID=" + categoryId + "\">" +
categoryName + "</a>";
// populate the categoriesListRemove combo box
categoriesListRemove.Items.Add(new ListItem(categoryName, categoryId));
}
// Delete from catalog or remove from category?
if (productCategories.Rows.Count > 1) {
deleteButton.Visible = false;
removeButton.Enabled = true;
} else {
deleteButton.Visible = true;
removeButton.Enabled = false;
}
// Fill categoriesListMove and categoriesListAssign with data productCategories = CatalogAccess.GetCategoriesWithoutProduct (currentProductId);
for (int i = 0; i < productCategories.Rows.Count; i++) {
// obtain category id and name
categoryId = productCategories.Rows[i]["CategoryId"].ToString();
categoryName = productCategories.Rows[i]["Name"].ToString();
// populate the list boxes
categoriesListAssign.Items.Add(new ListItem(categoryName, categoryId));
categoriesListMove.Items.Add(new ListItem(categoryName, categoryId));
} } }
4. Open ProductDetailsAdmin.ascx in Design View, double-click the first button (removeButton), and then complete its Click event handler method like this:
// Remove the product from a category
protected void removeButton_Click(object sender, EventArgs e) {
// Check if a category was selected
if (categoriesListRemove.SelectedIndex != -1) {
// Get the category ID that was selected in the DropDownList string categoryId = categoriesListRemove.SelectedItem.Value;
// Remove the product from the category
bool success = CatalogAccess.RemoveProductFromCategory
(currentProductId, categoryId);
// Display status message
statusLabel.Text = success ? "Product removed successfully" :
"Product removal failed";
// Refresh the page PopulateControls();
} else
statusLabel.Text = "You need to select a category";
}
5. While in Design View, double-click the second button (deleteButton), and then complete its Click event handler method like this:
// delete a product from the catalog
protected void deleteButton_Click(object sender, EventArgs e) {
// Delete the product from the catalog
CatalogAccess.DeleteProduct(currentProductId);
// Need to go back to the categories page now
Response.Redirect(Request.ApplicationPath + "/CatalogAdmin.aspx" + "?DepartmentID=" + currentDepartmentId +
"&CategoryID=" + currentCategoryId);
}
6. While in Design View, double-click the third button (assignButton), and then complete its Click event handler method like this:
// assign the product to a new category
protected void assignButton_Click(object sender, EventArgs e) {
// Check if a category was selected
if (categoriesListAssign.SelectedIndex != -1) {
// Get the category ID that was selected in the DropDownList string categoryId = categoriesListAssign.SelectedItem.Value;
// Assign the product to the category
bool success = CatalogAccess.AssignProductToCategory(currentProductId, categoryId);
// Display status message
statusLabel.Text = success ? "Product assigned successfully" :
"Product assignation failed";
// Refresh the page PopulateControls();
} else
statusLabel.Text = "You need to select a category";
}
7. While in Design View, double-click the fourth button (moveButton), and then complete its Click event handler method like this:
// move the product to another category
protected void moveButton_Click(object sender, EventArgs e) {
// Check if a category was selected
if (categoriesListMove.SelectedIndex != -1) {
// Get the category ID that was selected in the DropDownList string newCategoryId = categoriesListMove.SelectedItem.Value;
// Move the product to the category
bool success = CatalogAccess.MoveProductToCategory(currentProductId, currentCategoryId, newCategoryId);
// If the operation was successful, reload the page, // so the new category will reflect in the query string if (!success)
statusLabel.Text = "Couldn't move the product to the specified category";
else
Response.Redirect(Request.ApplicationPath + "/CatalogAdmin.aspx" + "?DepartmentID=" + currentDepartmentId +
"&CategoryID=" + newCategoryId + "&ProductID=" + currentProductId);
} else
statusLabel.Text = "You need to select a category";
}
8. While in Design View, double-click the two Upload buttons and complete their Click event handler code like this:
// upload product's first image
protected void upload1Button_Click(object sender, EventArgs e) {
// proceed with uploading only if the user selected a file if (image1FileUpload.HasFile)
{ try {
string fileName = image1FileUpload.FileName;
string location = Server.MapPath("./ProductImages/") + fileName;
// save image to server
image1FileUpload.SaveAs(location);
8213592a117456a340854d18cee57603
// update database with new product details
ProductDetails pd = CatalogAccess.GetProductDetails(currentProductId);
CatalogAccess.UpdateProduct(currentProductId, pd.Name, pd.Description, pd.Price.ToString(), fileName, pd.Image2FileName, pd.OnDepartmentPromotion.ToString(), pd.OnCatalogPromotion.ToString());
// reload the page
Response.Redirect(Request.ApplicationPath + "/CatalogAdmin.aspx" + "?DepartmentID=" + currentDepartmentId +
"&CategoryID=" + currentCategoryId + "&ProductID=" + currentProductId);
} catch {
statusLabel.Text = "Uploading image 1 failed";
} } }
// upload product's second image
protected void upload2Button_Click(object sender, EventArgs e) {
// proceed with uploading only if the user selected a file if (image2FileUpload.HasFile)
{ try {
string fileName = image2FileUpload.FileName;
string location = Server.MapPath("./ProductImages/") + fileName;
// save image to server
image2FileUpload.SaveAs(location);
// update database with new product details
ProductDetails pd = CatalogAccess.GetProductDetails(currentProductId);
CatalogAccess.UpdateProduct(currentProductId, pd.Name, pd.Description, pd.Price.ToString(), pd.Image1FileName, fileName, pd.OnDepartmentPromotion.ToString(), pd.OnCatalogPromotion.ToString());
// reload the page
Response.Redirect(Request.ApplicationPath + "/CatalogAdmin.aspx" + "?DepartmentID=" + currentDepartmentId +
"&CategoryID=" + currentCategoryId + "&ProductID=" + currentProductId);
} catch {
statusLabel.Text = "Uploading image 2 failed";
} } }
9. Test your new catalog admin page to see that everything works as expected.
How It Works: ProductDetailsAdmin.ascx
It’s worth taking a second look at the bits that are different from the previous exercises:
• The TieButton method tied the drop-down lists to their associated Go! buttons.
• The FileUpload control uploaded product pictures to the server. The code is pretty clear, so take a closer look at the Click event handlers of the two Upload buttons to see how the FileUpload control is used in practice.
• Various tests are made in the buttons’ Click event handlers to display accurate status messages to the visitor. A novelty in this control is checking whether a value of the drop-down lists has been selected before trying to read its value (this is useful especially in the situation when the list is empty).
• The DropDownList controls are populated in the PopulateControls method, and they are capable of storing a key for each of their entries, similar to what the DataKeyNames property does for the GridView. In our case, this key retains the IDs of the listed categories. You read this ID from the DropDownList controls when the user tries to move, assign, or remove the product from a selected category, by reading the SelectedItem.Value property of the list.