Ссылка на несуществующий пользовательский элемент управления? - PullRequest
0 голосов
/ 07 октября 2010

Я создал приложение, которое ищет каталог и загружает все пользовательские элементы управления в форму, а затем использует метод «GetResult ()», чтобы получить ответы из формы. Я не использовал этот стиль ООП, потому что я все еще изучаю, как полностью использовать ООП, и сейчас я возвращаюсь к разработке его с ООП, чтобы перейти к следующей части, которая будет намного проще, если я буду работать с объектами. Прямо сейчас я создал свой класс 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;
    }
}

}

Вот метод LoadForms (), который я вставил в OnInit для загрузки всех моих форм. Я не полностью реализовал часть 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

Ответы [ 2 ]

1 голос
/ 21 октября 2010

Хорошо, я понял это. У меня уже был метод, который собирал все результаты из формы и затем выплевывал их на экране проверки. Я манипулировал этим кодом так, что теперь он загружает их прямо в объект, с которым я работал. Теперь мои объекты заполнены всей динамической информацией, необходимой для управления, и я могу управлять ими намного проще. Вот код на случай, если кто-то еще ищет ответ.

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

Надеюсь, это кому-нибудь поможет.

0 голосов
/ 07 октября 2010

Есть несколько проблем, которые вам нужно решить - и в вашем коде, и в ваших текущих знаниях :-) Начните с этого:

  1. Прочтите несколько статей о жизненном цикле страницы ASP.NET, чтобы лучше узнать, что делать в каждом обработчике событий жизненного цикла (OnInit, OnLoad,…). Хорошей отправной точкой может быть Обзор MSDN . Тем не менее, поищите в Google «жизненный цикл страницы ASP.NET» и прочитайте несколько других статей и примеров.

    Кроме того, вам необходимо ознакомиться с природой обработки запросов ASP.NET. Вначале имейте в виду, что когда пользователь нажимает какую-либо кнопку «Отправить», которая, в свою очередь, вызывает HTTP-запрос POST, вы несете ответственность за создание дерева элементов управления страницы, соответствующего его структуре, идентификаторам и т. Д., Как они были в предыдущий запрос. В противном случае ASP.NET не знает, как в какие элементы управления связывать данные, введенные пользователем.

  2. Рядом со строкой, помеченной //Lost and confused here :/, вы создаете новый элемент управления и немедленно запрашиваете его для «результатов» (которые, как я ожидаю, будут значениями некоторых полей редактирования внутри него). Это не может работать, потому что, скорее всего, слишком рано для формы получать данные, полученные от объекта Page, который управляет обработкой запроса.

  3. Ваша собственность Results плохо спроектирована. Во-первых, вы не должны использовать свойства, которые на самом деле «генерируют» данные таким образом, что они могут изменяться без уведомления. Свойства должны использоваться как «интеллектуальные поля», в противном случае вы получите менее управляемый и менее читаемый код. Во-вторых, сеттер, который вы оставили там как «set;», приводит к тому, что любое значение, присвоенное свойству, будет фактически потеряно, потому что нет способа получить его. Хотя в некоторых редких случаях такое поведение может быть преднамеренным, в вашем случае, я думаю, это просто ошибка.

Итак, хотя вы в настоящее время можете оставить любой «хороший ООП-подход» для решения своей проблемы, вы, безусловно, должны лучше ознакомиться с жизненным циклом страницы. Чтобы понять это, нужно подумать о принципах работы веб-приложений ASP.NET, но я уверен, что это даст вам тот толчок, который вам действительно нужен.

ОБНОВЛЕНИЕ: Что касается кода Тони (см. Комментарии), то для продвижения кода необходимо сделать следующее:

  1. Список данных формы в свойстве requestForm должен иметь кортеж [путь ASCX формы, контрольный идентификатор, фактический RequestForm класс данных]

  2. GatherForms вызывается только при начальной загрузке страницы (т. Е. if (Page.IsPostBack)), и она должна заполнять requestForm соответствующими кортежами для доступных форм ASCX.

  3. И chklApplications, и шаги мастера должны быть созданы в LoadForms на основе содержимого requestForm.

  4. При получении результатов идентификатор, сохраненный в соответствующей записи requestForm, можно использовать для поиска фактического пользовательского элемента управления.

...