引用不存在的用户控件?

发布于 2024-09-26 08:28:37 字数 4549 浏览 0 评论 0原文

我创建了一个应用程序,它搜索目录并将所有用户控件加载到表单中,然后使用“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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

余厌 2024-10-03 08:28:37

好吧,所以我想通了。我已经有了一种方法,可以从表单中收集所有结果,然后将它们吐出到验证屏幕上。我操纵了该代码,以便现在将它们直接加载到我正在使用的对象中。现在,我的对象充满了控件所需的所有动态信息,并且我可以更轻松地管理它们。这是代码,以防其他人正在寻找答案。

MyClass

public class RequestForm
{
    public string Name { get; set; }
    public string ControlID { get; set; }
    public string StepID { get; set; }
    public string FilePath { get; set; }
    public string Emails { get; set; }
    public string Results { get; set; }
    public int Position { get; set; }
    public bool Visible { get; set; }

    /// <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 formEmails,string formResults, bool formVisible = false)
    {
        this.Name = formName;
        this.ControlID = formControlId;
        this.StepID = wizardStepID;
        this.Position = wizardStepPosition;
        this.FilePath = formFilePath;
        this.Emails = formEmails;
        this.Results = formResults;
        this.Visible = formVisible;
    }
}

这个包含所有控件的列表

    public List<RequestForm> requestForm
    {
        get
        {
            List<RequestForm> requestList = new List<RequestForm>();
            requestList = (List<RequestForm>)Session["RequestForms"];
            var v = Session["RequestForms"];
            return v != null ? (List<RequestForm>)v : null;
        }
        set
        {
            Session["RequestForms"] = value;
        }
    }

这是我用来收集结果然后将它们放入对象中的方法。

    private void GatherFormsData()
    {
        if (requestForm != null)
        {
            foreach (RequestForm rform in requestForm)
            {
                if (rform.Visible)
                {
                    WizardStepBase step = (WizardStep)wzAccessRequest.FindControl(rform.StepID);
                    FormUserControl form = (FormUserControl)step.FindControl(rform.ControlID);
                    rform.Results = String.Format("{0}<br>Email: {1}<br><br>", form.GetResults(), form.EmailContact());
                }
            }
        }
    }

希望这对某人有帮助。

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

public class RequestForm
{
    public string Name { get; set; }
    public string ControlID { get; set; }
    public string StepID { get; set; }
    public string FilePath { get; set; }
    public string Emails { get; set; }
    public string Results { get; set; }
    public int Position { get; set; }
    public bool Visible { get; set; }

    /// <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 formEmails,string formResults, bool formVisible = false)
    {
        this.Name = formName;
        this.ControlID = formControlId;
        this.StepID = wizardStepID;
        this.Position = wizardStepPosition;
        this.FilePath = formFilePath;
        this.Emails = formEmails;
        this.Results = formResults;
        this.Visible = formVisible;
    }
}

This list that holds all of the controls

    public List<RequestForm> requestForm
    {
        get
        {
            List<RequestForm> requestList = new List<RequestForm>();
            requestList = (List<RequestForm>)Session["RequestForms"];
            var v = Session["RequestForms"];
            return v != null ? (List<RequestForm>)v : null;
        }
        set
        {
            Session["RequestForms"] = value;
        }
    }

This is the method that I use to gather the results and then put them into the object.

    private void GatherFormsData()
    {
        if (requestForm != null)
        {
            foreach (RequestForm rform in requestForm)
            {
                if (rform.Visible)
                {
                    WizardStepBase step = (WizardStep)wzAccessRequest.FindControl(rform.StepID);
                    FormUserControl form = (FormUserControl)step.FindControl(rform.ControlID);
                    rform.Results = String.Format("{0}<br>Email: {1}<br><br>", form.GetResults(), form.EmailContact());
                }
            }
        }
    }

Hope this helps someone.

断肠人 2024-10-03 08:28:37

您需要解决几个问题 - 无论是在您的代码中还是在您当前的知识中:-) 从这里开始:

  1. 阅读一些有关 ASP.NET 页面生命周期的文章,以便您更加熟悉要做什么在每个生命周期事件处理程序中执行的操作(OnInitOnLoad、...)。 MSDN 概述可能是一个很好的起点。不过,请搜索“ASP.NET 页面生命周期”并阅读其他一些文章和示例。

    此外,您还需要熟悉 ASP.NET 页面处理的请求-响应性质。一开始,请记住,当用户点击某个“提交”按钮(进而导致发生 HTTP POST 请求)时,您有责任创建页面的控制树以匹配其结构、ID 等。之前的请求。否则ASP.NET不知道如何在哪些控件中绑定用户填写的数据。

  2. 在标记为 //Lost andfused here :/ 的行附近,您正在创建一个新控件并立即查询它的“结果”(我希望是其中某些编辑框的值) )。这是行不通的,因为表单从驱动请求处理的 Page 对象接收数据很可能为时过早。

  3. 您的 Results 属性设计不当。首先,您不应该使用实际“生成”数据的属性,因为它们可以在不通知的情况下进行更改。属性应用作“智能字段”,否则您最终会得到不太易于管理和可读的代码。其次,你留在那里的设置者,如“设置”;导致分配给属性的任何值实际上丢失,因为无法检索它。虽然在极少数情况下,这种行为可能是故意的,但在您的情况下,我猜这只是一个错误。

因此,虽然您目前可以留下任何“好的 OOP 方法”来解决您的问题,但您当然应该更加熟悉页面生命周期。理解它确实需要对 ASP.NET Web 应用程序的工作原理进行一些思考,但我确信它将为您提供实际需要的推动力。

更新:对于托尼的代码(请参阅注释),应执行以下操作来向前移动代码:

  1. requestForm 属性中的表单数据列表应具有[形成 ASCX 路径的元组,
    控件 ID,实际的 RequestForm 数据类]

  2. GatherForms 仅在页面初始加载时调用(即 if (Page.IsPostBack)),并且应使用可用 ASCX 表单的相应元组填充 requestForm


  3. chklApplications 和向导步骤均应根据 requestForm 的内容在 LoadForms 中创建。

  4. 当要收集结果时,存储在相应 requestForm 条目中的 ID 可用于查找实际的用户控件。

There are several problems you need to address — both in your code and both in your current knowledge :-) Start with this:

  1. 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.

  2. 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 the Page object that drives the request processing.

  3. 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:

  1. The list of form data in the requestForm property shall have tuple of [form ASCX path,
    control ID, the actual RequestForm data class]

  2. GatherForms shall be called only when the page is initially loaded (i.e. if (Page.IsPostBack)) and it shall fill requestForm with the respective tuples for available ASCX forms.

  3. Both chklApplications and wizard steps shall be created in LoadForms on the basis of requestForm's content.

  4. When results are to be gathered, the ID stored in the respective requestForm entry can be used to look-up the actual user control.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文