引用不存在的用户控件?
我创建了一个应用程序,它搜索目录并将所有用户控件加载到表单中,然后使用“GetResult()”方法从表单中获取答案。我没有采用这种 OOP 风格,因为我仍在学习如何充分利用 OOP,现在我要回去用 OOP 进行设计,这样我就可以进入下一部分,如果我使用对象,这会容易得多。现在我已经创建了“RequestForm”类,我希望 RequestForm.Result 进入 UC 并调用 GetResults() 方法。尽管由于我缺乏知识,我很难做到这一点,但也许有人可以指出我正确的方向。
FormUserControl - 抽象类
namespace AccessRequest
{
public abstract class FormUserControl : UserControl
{
public abstract string Name();
public abstract string GetResults();
public abstract string EmailUsers();
}
}
RequestForm - 对象类
namespace AccessRequest
{
public class RequestForm
{
public string Name { get; set; }
public string ControlID { get; set; }
public string StepName { get; set; }
public string FilePath { get; set; }
public string Results {
get
{
//How would I pull my usercontrol results with Control.GetReults() from within this area?
//I have since then turned this into a method. How would I get it to access my UserControl loaded on the asp page to grab the results?
}
set;
}
public string Emails { get; set; }
public int Position { get; set; }
public bool Visible { get; set; }
public RequestForm()
{
}
/// <summary>
/// FormResults gathers all needed information about the forms
/// </summary>
/// <param name="formName">Name of the Form</param>
/// <param name="formControlID">ID of the User Control </param>
/// <param name="wizardStepID">ID of the Wizard Step</param>
/// <param name="formFilePath">File path of the physical form</param>
/// <param name="formResults">Results from the form</param>
/// <param name="formEmails">Other emails to include</param>
public RequestForm(string formName, string formControlId, string wizardStepID, int wizardStepPosition, string formFilePath, string formResults, string formEmails)
{
this.Name = formName;
this.ControlID = formControlId;
this.StepName = wizardStepID;
this.Position = wizardStepPosition;
this.FilePath = formFilePath;
this.Results = formResults;
this.Emails = formEmails;
this.Visible = false;
}
public void SaveList(List<RequestForm> formList)
{
// HttpContext.Current.Session["FormList"] = formList;
}
}
}
这是我在 OnInit 中放入的 LoadForms() 方法,用于加载我的所有表单,我还没有完全实现 RequestForm 部分,但我相信它应该用来构建我的对象列表。
private void LoadForms()
{
string dotColor = "Black";
string formColor = "#808080";
int loc = 3;
foreach (ListItem item in chklApplications.Items)
{
string formPath = (string)item.Value;
WizardStepBase newStep = new WizardStep();
newStep.ID = "wzStep" + item.Text;
newStep.Title = String.Format("<font color='{0}'> ¤</font> <font color='{1}'>{2} Request</font>", dotColor, formColor, item.Text);
var form = LoadControl(formPath);
form.ID = "uc" + item.Text;
newStep.Controls.Add(form);
wzAccessRequest.WizardSteps.AddAt(loc, newStep);
requestForm.Add(new RequestForm(
item.Text, //Form name
form.ID.ToString(), //User Control ID
newStep.ID.ToString(), //Wizardstep ID
loc, //Wizardstep Position
item.Value.ToString(), //File Path
null, //Form Results
null //Form Emails
));
loc++;
}
}
我在这里设置它们在向导控件的侧面菜单中是否可见。顺便说一句,有谁知道我如何阻止它为此创建表标签?现在它正在增长一个很大的空间,我可以在其中插入表格。
protected void SideBarList_ItemDataBound(object sender, DataListItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
if (!ShowWizardStep(e.Item.DataItem))
{
e.Item.CssClass = "Hidden";
}
}
}
感谢我收到的任何建议! :D
I have created an application that searches a directory and loads all of the usercontrols into the form and then uses a "GetResult()" method to grab the answers from the form. I did not do this OOP style because I am still learning how to fully utilize OOP and I am now going back to design it with OOP so I can move onto the next part which will be a lot easier if I was working with objects. Right now I have created my "RequestForm" class and I want RequestForm.Result to reach into the UC and call the GetResults() method. I am having a difficult time getting it to do this though due to my lack of knowledge perhaps someone can point me in the right direction.
FormUserControl - Abstract Class
namespace AccessRequest
{
public abstract class FormUserControl : UserControl
{
public abstract string Name();
public abstract string GetResults();
public abstract string EmailUsers();
}
}
RequestForm - Object Class
namespace AccessRequest
{
public class RequestForm
{
public string Name { get; set; }
public string ControlID { get; set; }
public string StepName { get; set; }
public string FilePath { get; set; }
public string Results {
get
{
//How would I pull my usercontrol results with Control.GetReults() from within this area?
//I have since then turned this into a method. How would I get it to access my UserControl loaded on the asp page to grab the results?
}
set;
}
public string Emails { get; set; }
public int Position { get; set; }
public bool Visible { get; set; }
public RequestForm()
{
}
/// <summary>
/// FormResults gathers all needed information about the forms
/// </summary>
/// <param name="formName">Name of the Form</param>
/// <param name="formControlID">ID of the User Control </param>
/// <param name="wizardStepID">ID of the Wizard Step</param>
/// <param name="formFilePath">File path of the physical form</param>
/// <param name="formResults">Results from the form</param>
/// <param name="formEmails">Other emails to include</param>
public RequestForm(string formName, string formControlId, string wizardStepID, int wizardStepPosition, string formFilePath, string formResults, string formEmails)
{
this.Name = formName;
this.ControlID = formControlId;
this.StepName = wizardStepID;
this.Position = wizardStepPosition;
this.FilePath = formFilePath;
this.Results = formResults;
this.Emails = formEmails;
this.Visible = false;
}
public void SaveList(List<RequestForm> formList)
{
// HttpContext.Current.Session["FormList"] = formList;
}
}
}
Here is the LoadForms() method I put in OnInit to load all of my forms, I have not fully implemented the RequestForm piece but this is where I believe it should go to builder my object list.
private void LoadForms()
{
string dotColor = "Black";
string formColor = "#808080";
int loc = 3;
foreach (ListItem item in chklApplications.Items)
{
string formPath = (string)item.Value;
WizardStepBase newStep = new WizardStep();
newStep.ID = "wzStep" + item.Text;
newStep.Title = String.Format("<font color='{0}'> ¤</font> <font color='{1}'>{2} Request</font>", dotColor, formColor, item.Text);
var form = LoadControl(formPath);
form.ID = "uc" + item.Text;
newStep.Controls.Add(form);
wzAccessRequest.WizardSteps.AddAt(loc, newStep);
requestForm.Add(new RequestForm(
item.Text, //Form name
form.ID.ToString(), //User Control ID
newStep.ID.ToString(), //Wizardstep ID
loc, //Wizardstep Position
item.Value.ToString(), //File Path
null, //Form Results
null //Form Emails
));
loc++;
}
}
Here is where I set whether they are visible or not in my side menu of the Wizard Control. BTW, does anyone know how I can prevent it from even creating the table tags for this? Right now it is growing a large space where I am inserting the forms.
protected void SideBarList_ItemDataBound(object sender, DataListItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
if (!ShowWizardStep(e.Item.DataItem))
{
e.Item.CssClass = "Hidden";
}
}
}
Thanks for any advise I receive!! :D
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
好吧,所以我想通了。我已经有了一种方法,可以从表单中收集所有结果,然后将它们吐出到验证屏幕上。我操纵了该代码,以便现在将它们直接加载到我正在使用的对象中。现在,我的对象充满了控件所需的所有动态信息,并且我可以更轻松地管理它们。这是代码,以防其他人正在寻找答案。
MyClass
这个包含所有控件的列表
这是我用来收集结果然后将它们放入对象中的方法。
希望这对某人有帮助。
Ok, so I figured this out. I already had a method that would gather all the results from the form and then spit them out on the verification screen. I manipulated that code so that now it loads them directly into the object I was working with. Now my objects are full of all the dynamic information I need for my controls and I can manage them a lot easier. Here is the code in case anyone else is looking for the answer.
MyClass
This list that holds all of the controls
This is the method that I use to gather the results and then put them into the object.
Hope this helps someone.
您需要解决几个问题 - 无论是在您的代码中还是在您当前的知识中:-) 从这里开始:
阅读一些有关 ASP.NET 页面生命周期的文章,以便您更加熟悉要做什么在每个生命周期事件处理程序中执行的操作(
OnInit
、OnLoad
、...)。 MSDN 概述可能是一个很好的起点。不过,请搜索“ASP.NET 页面生命周期”并阅读其他一些文章和示例。此外,您还需要熟悉 ASP.NET 页面处理的请求-响应性质。一开始,请记住,当用户点击某个“提交”按钮(进而导致发生 HTTP POST 请求)时,您有责任创建页面的控制树以匹配其结构、ID 等。之前的请求。否则ASP.NET不知道如何在哪些控件中绑定用户填写的数据。
在标记为
//Lost andfused here :/
的行附近,您正在创建一个新控件并立即查询它的“结果”(我希望是其中某些编辑框的值) )。这是行不通的,因为表单从驱动请求处理的Page
对象接收数据很可能为时过早。您的
Results
属性设计不当。首先,您不应该使用实际“生成”数据的属性,因为它们可以在不通知的情况下进行更改。属性应用作“智能字段”,否则您最终会得到不太易于管理和可读的代码。其次,你留在那里的设置者,如“设置”;导致分配给属性的任何值实际上丢失,因为无法检索它。虽然在极少数情况下,这种行为可能是故意的,但在您的情况下,我猜这只是一个错误。因此,虽然您目前可以留下任何“好的 OOP 方法”来解决您的问题,但您当然应该更加熟悉页面生命周期。理解它确实需要对 ASP.NET Web 应用程序的工作原理进行一些思考,但我确信它将为您提供实际需要的推动力。
更新:对于托尼的代码(请参阅注释),应执行以下操作来向前移动代码:
requestForm
属性中的表单数据列表应具有[形成 ASCX 路径的元组,控件 ID,实际的
RequestForm
数据类]GatherForms
仅在页面初始加载时调用(即if (Page.IsPostBack)),并且应使用可用 ASCX 表单的相应元组填充
requestForm
。chklApplications
和向导步骤均应根据requestForm
的内容在LoadForms
中创建。当要收集结果时,存储在相应
requestForm
条目中的 ID 可用于查找实际的用户控件。There are several problems you need to address — both in your code and both in your current knowledge :-) Start with this:
Read a few articles about ASP.NET's page life-cycle, so you become more familiar with what to do in each life-cycle event handler (
OnInit
,OnLoad
, …). Good starting point might be this MSDN overview. However, google for “ASP.NET page life cycle” and read a few other articles and examples as well.Also, you will need to get familiar with the request-response nature of ASP.NET page processing. In the beginning, bear in mind that when the user hits some 'Submit' button which in turn causes an HTTP POST request to occur, you are responsible to creating the page's control tree to match its structure, IDs, etc. as they were in the previous request. Otherwise ASP.NET doesn't know how in which controls to bind the data the user filled-in.
Near the line tagged
//Lost and confused here :/
you are creating a new control and immediately querying it for the 'results' (which I expect to be values of some edit boxes within it). This cannot work, because it's most probably too early for the form to have the data received from thePage
object that drives the request processing.Your
Results
property is poorly designed. First, you shouldn't be using properties that actually 'generate' data in such a way they can change without notice. Properties shall be used as “smart fields”, otherwise you end up with less manageable and less readable code. Second, the setter you left there like “set;” causes any value assigned into the property to be actually lost, because there's no way to retrieve it. While in some rare cases this behavior may be intentional, in your case I guess it's just an error.So, while you can currently leave behind any “good OOP way” to approach your problem, you certainly should get more familiar with the page life-cycle. Understanding it really requires some thinking about the principles how ASP.NET web applications are supposed to work, but I'm sure it will provide you with the kick forward you actually need.
UPDATE: In respect to Tony's code (see comments) the following shall be done to move the code forward:
The list of form data in the
requestForm
property shall have tuple of [form ASCX path,control ID, the actual
RequestForm
data class]GatherForms
shall be called only when the page is initially loaded (i.e.if (Page.IsPostBack)
) and it shall fillrequestForm
with the respective tuples for available ASCX forms.Both
chklApplications
and wizard steps shall be created inLoadForms
on the basis ofrequestForm
's content.When results are to be gathered, the ID stored in the respective
requestForm
entry can be used to look-up the actual user control.