引用不存在的用户控件?

时间:2010-10-07 14:13:26

标签: c# asp.net user-controls dynamic formwizard

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

    }

这是我在Wizard Control的侧边菜单中设置它们是否可见的位置。顺便说一下,有谁知道我怎么能阻止它甚至为此创建表标签?现在它正在增加一个大空间,我正在插入表格。

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

2 个答案:

答案 0 :(得分:1)

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

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());
                }
            }
        }
    }

希望这有助于某人。

答案 1 :(得分:0)

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

  1. 阅读一些关于ASP.NET页面生命周期的文章,这样您就可以更熟悉每个生命周期事件处理程序中的操作(OnInitOnLoad,...) 。好的起点可能是MSDN overview。但是,google用于“ASP.NET页面生命周期”并阅读其他一些文章和示例。

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

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

  3. 您的Results财产设计不佳。首先,您不应该使用实际“生成”数据的属性,这些属性可以在不事先通知的情况下进行更改。属性应用作“智能字段”,否则最终会导致代码不易管理且可读性降低。其次,你在那里留下的setter就像“set;”一样,导致分配到属性中的任何值实际上都会丢失,因为无法检索它。虽然在极少数情况下这种行为可能是故意的,但在我看来这只是一个错误。

  4. 因此,虽然您现在可以留下任何“良好的OOP方式”来解决您的问题,但您当然应该更熟悉页面生命周期。理解它确实需要考虑ASP.NET Web应用程序应该如何工作的原则,但我相信它会为您提供实际需要的启动。

    更新:关于Tony的代码(请参阅注释),应该执行以下操作以移动代码:

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

    2. GatherForms只有在最初加载页面时才会被调用(即if (Page.IsPostBack)),并且应该为requestForm填充可用ASCX表单的相应元组。

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

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