protected void BrochureOptions_SelectedIndexChanged(object sender, EventArgs e) { // Get a reference to the RadioButtonList and its Parent RadioButtonList BrochureOptions = (RadioButtonList)sender; Control parent = BrochureOptions.Parent; // Now use FindControl("controlID") to get a reference of the // FileUpload control FileUpload BrochureUpload = (FileUpload)parent.FindControl("BrochureUpload"); // Only show BrochureUpload if SelectedValue = "3" BrochureUpload.Visible = (BrochureOptions.SelectedValue == "3"); }
由于RadioButtonList控件和FileUpload控件同时出现在一个模板里,我们需要通过编程来访问这2个控件。在SelectedIndexChanged事件处理器里,我们通过输入参数sender来引用RadioButtonList控件。为了获取FileUpload控件,我们需要使用RadioButtonList的父控件(parent control),并使用FindControl("controlID")方法。一旦我们同时获取了RadioButtonList和FileUpload控件时,只要RadioButtonList控件的SelectedValue值等于3,即“Upload new brochure” ListItem的值时,将FileUpload控件的Visible属性设置为true 。
添加完上述代码后,花几分钟时间来测试编辑页面。点击某行的Edit按钮,默认是选中“Use current brochure”项,改选另一项,页面产生回传,如果是选择第3项,则FileUpload控件将会显示出来,否则处于隐身状态。图14显示点击Edit按钮的情形,而图15则是选择“Upload new brochure”时的情形。
图14:默认选择“Use current brochure”项
图15:选择“Upload new brochure”时FileUpload控件显示出来
保存Brochure文件并更新BrochurePath列
当点击GridView控件的Update按钮时,触发RowUpdating事件,调用ObjectDataSource控件的update命令,然后触发GridView控件的RowUpdated事件。跟deleting流程类似,我们需要创建这些事件的处理器。在RowUpdating事件处理器里,我们需要根据RadioButtonList的SelectedValue值来判断下一步怎么做。
.如果SelectedValue值为1,我们将保持rochurePath不变。所以我们将ObjectDataSource控件的brochurePath参数设置为当前处于编辑状态记录的BrochurePath值,方法为e.NewValues["brochurePath"] = value.
.如果SelectedValue值为2,意味着将BrochurePath设为NULL。为此,我们需要将ObjectDataSource控件的brochurePath参数设为Nothing,结果就是在UPDATE命令里使用NULL。如果存在对应的brochure文件,我们必须将其删除,前提是没有抛出任何的异常。
.如果SelectedValue值为3,我们必须确保用户已经上传了一个PDF文件并将其保存在文件系统,然后更新记录的BrochurePath值。我们要先将被替换的前一个文件删除掉,当然前提是没有引发异常。
在上一章里,当在DetailsView控件里添加新记录时,触发DetailsView控件的ItemInserting事件。在本章,当RadioButtonList控件的SelectedValue为3时(即我们选择Upload new brochure时),接下来要采取的步骤实际上与DetailsView控件的ItemInserting事件处理器实现的功能相似。根据实现的功能,我划分为2个方法:
.ProcessBrochureUpload(FileUpload, out bool):它以一个FileUpload控件实例为输入参数,结果为一个布尔值(Boolean)。根据该布尔值判断是否继续更新或删除操作,抑或取消操作。如果存在上传文件该方法就返回其路径,反之返回null。
.DeleteRememberedBrochurePath:如果页面变量deletedCategorysPdfPath不为null,则删除该参数指定的文件。
下面是上述2种方法的代码。注意ProcessBrochureUpload方法和DetailsView控件的ItemInserting事件处理器有某些相似性,在本章,我们更新DetailsView控件的事件处理器以使用这些新方法。下载本章的代码,查看我们对DetailsView控件的事件处理器所做的修改。
private string ProcessBrochureUpload (FileUpload BrochureUpload, out bool CancelOperation) { CancelOperation = false; // by default, do not cancel operation if (BrochureUpload.HasFile) { // Make sure that a PDF has been uploaded if (string.Compare(System.IO.Path.GetExtension(BrochureUpload.FileName), ".pdf", true) != 0) { UploadWarning.Text = "Only PDF documents may be used for a category's brochure."; UploadWarning.Visible = true; CancelOperation = true; return null; } const string BrochureDirectory = "~/Brochures/"; string brochurePath = BrochureDirectory + BrochureUpload.FileName; string fileNameWithoutExtension = System.IO.Path.GetFileNameWithoutExtension(BrochureUpload.FileName); int iteration = 1; while (System.IO.File.Exists(Server.MapPath(brochurePath))) { brochurePath = string.Concat(BrochureDirectory, fileNameWithoutExtension, "-", iteration, ".pdf"); iteration++; } // Save the file to disk and set the value of the brochurePath parameter BrochureUpload.SaveAs(Server.MapPath(brochurePath)); return brochurePath; } else { // No file uploaded return null; } } private void DeleteRememberedBrochurePath() { // Is there a file to delete? if (deletedCategorysPdfPath != null) { System.IO.File.Delete(Server.MapPath(deletedCategorysPdfPath)); } }
在GridView控件的RowUpdating和RowUpdated事件处理器里使用上面2个方法,如下: