简体   繁体   English

引用不存在的用户控件?

[英]Referencing a non-existent user Control?

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. 我创建了一个应用程序,该应用程序搜索目录并将所有用户控件加载到表单中,然后使用“ GetResult()”方法从表单中获取答案。 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. 我之所以没有这种OOP风格,是因为我仍在学习如何充分利用OOP,现在我将回头用OOP进行设计,因此我可以继续进行下一部分,如果我使用对象,这会容易得多。 Right now I have created my "RequestForm" class and I want RequestForm.Result to reach into the UC and call the GetResults() method. 现在,我已经创建了我的“ RequestForm”类,并且我希望RequestForm.Result可以进入UC并调用GetResults()方法。 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 FormUserControl-抽象类

namespace AccessRequest
{
    public abstract class FormUserControl : UserControl
    {
        public abstract string Name();
        public abstract string GetResults();
        public abstract string EmailUsers();
    }
}

RequestForm - Object Class 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;
    }
}

}

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. 这是我在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++;
        }

    }

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 :D

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. 希望这对某人有帮助。

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 , …). 阅读有关ASP.NET页面生命周期的几篇文章,以便您更加熟悉每个生命周期事件处理程序( OnInitOnLoad …)中的操作。 Good starting point might be this MSDN overview . 良好的起点可能是此MSDN概述 However, google for “ASP.NET page life cycle” and read a few other articles and examples as well. 但是,对于“ ASP.NET页面生命周期”,谷歌也要阅读其他一些文章和示例。

    Also, you will need to get familiar with the request-response nature of ASP.NET page processing. 另外,您将需要熟悉ASP.NET页面处理的请求-响应特性。 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. 刚开始时,请记住,当用户单击某个“提交”按钮进而导致HTTP POST请求发生时,您有责任创建页面的控件树以匹配其结构,ID等。先前的要求。 Otherwise ASP.NET doesn't know how in which controls to bind the data the user filled-in. 否则,ASP.NET不知道如何在哪个控件中绑定用户填写的数据。

  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). 在标记为//Lost and confused here :/造成//Lost and confused here :/的行附近//Lost and confused here :/您正在创建一个新控件,并立即向其查询“结果”(我希望它是其中的某些编辑框的值)。 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. 这行不通,因为对于表单而言,从驱动请求处理的Page对象接收数据可能为时过早。

  3. Your Results property is poorly designed. 您的“ Results属性设计不佳。 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. 其次,您像“ set;”一样留在那儿的setter导致分配给属性的任何值实际上都丢失了,因为无法检索它。 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. 因此,尽管您目前可以抛弃任何“好的OOP方法”来解决问题,但您当然应该更加熟悉页面生命周期。 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. 理解它确实需要对ASP.NET Web应用程序应该如何工作的原理进行一些思考,但是我敢肯定,它将为您提供您实际需要的动力。

UPDATE: In respect to Tony's code (see comments) the following shall be done to move the code forward: 更新:关于Tony的代码(请参阅注释),应进行以下操作以使代码向前移动:

  1. The list of form data in the requestForm property shall have tuple of [form ASCX path, control ID, the actual RequestForm data class] requestForm属性中的表单数据列表应具有[表单ASCX路径,控件ID,实际RequestForm数据类]的元组

  2. GatherForms shall be called only when the page is initially loaded (ie if (Page.IsPostBack) ) and it shall fill requestForm with the respective tuples for available ASCX forms. GatherForms仅在最初加载页面时(即, if (Page.IsPostBack) )被调用,并且应使用可用ASCX表单的相应元组填充requestForm

  3. Both chklApplications and wizard steps shall be created in LoadForms on the basis of requestForm 's content. chklApplications和向导步骤均应基于requestForm的内容在LoadForms创建。

  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. 当要收集结果时,可以使用存储在各个requestForm条目中的ID来查找实际的用户控件。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM