Несколько пользовательских элементов управления с различными данными, введенными, показывая те же данные - PullRequest
0 голосов
/ 11 апреля 2011

Работа на странице, где я создаю новые экземпляры пользовательского контроля, который я написал, основываясь на данных. Я передаю отфильтрованные данные в пользовательский элемент управления с помощью инжектора конструктора. Однако при визуализации пользовательских элементов управления для всех пользовательских элементов управления отображается только последний набор введенных данных. Похоже, я ссылаюсь на тот же экземпляр, а не создаю новый, независимый. Идеи?

 protected void Page_Init(object sender, EventArgs e)
        {
            var data = <my data comes from here>;
            var yearsInData = data.OrderByDescending(x=>x.Year).Select(x => x.Year).Distinct();

            foreach(var year in yearsInData)
            {
                var employers = data.OrderBy(x=>x.EmployerName).Where(x => x.Year == year).Select(x => x.EmployerName).Distinct();
                foreach (var employer in employers)
                {
                    var eob = data.Where(x => x.Year == year).Where(x => x.EmployerName == employer);
                    if (eob.Count() > 0)
                    {
                        var ctl = LoadControl(@"~\Shared\Controls\AnnualEOBControl.ascx", eob);
                        pnlMain.Controls.Add(ctl);
                    }
                }
            }
        }

Вот метод LoadControl:

private UserControl LoadControl(string userControlPath, params object[] constructorParameters)
        {
            var constParamTypes = new List<Type>();
            foreach (var constParam in constructorParameters)
            {
                constParamTypes.Add(constParam.GetType());
            }

            var ctl = Page.LoadControl(userControlPath) as UserControl;

            // Find the relevant constructor
            if (ctl != null)
            {
                var constructor = ctl.GetType().BaseType.GetConstructor(constParamTypes.ToArray());

                // And then call the relevant constructor
                if (constructor == null)
                {
                    throw new MemberAccessException("The requested constructor was not found on : " + ctl.GetType().BaseType);
                }
                constructor.Invoke(ctl, constructorParameters);
            }

            // Finally return the fully initialized UC
            return ctl;
        } 

Ответы [ 2 ]

0 голосов
/ 11 апреля 2011

Если бы у меня была эта проблема, и у меня был базовый класс, который я мог бы использовать, и какой-нибудь способ создать след без особых проблем, я бы

  • поместил бы член экземпляра const Guidи DateTime, оба инициализируют его в конструкторе
  • помещают сон в несколько мс между отдельными вызовами конструктора, поэтому временные метки

Я просто думаю, что подсказка может бытьк тому, что происходит и ведет к корню.

0 голосов
/ 11 апреля 2011

Пахнет проблемой закрытия. Я догадываюсь, что во время каждой итерации просто присваивается значение, а не воссоздается. Поскольку все ваши элементы управления ссылаются на eob, а не на данные, возвращаемые eob, все они будут использовать одно и то же значение, когда придет время рендеринга.

Как выглядит ваша перегрузка LoadControl? Я прочитал статью, на которую вы ссылались, но я хотел бы увидеть, что вы конкретно сделали. Интересно, если бы просто переназначение значений из eob переменной, объявленной в вашем методе LoadControl, помогло бы вам преодолеть все трудности. Заставьте элементы управления использовать переменную из более узкой области видимости, чтобы они не могли физически видеть аргументы друг друга.

Редактировать: Нашел SO ссылку на тему: Что такое «замыкания» в .NET?

Дайте этому водовороту:

private UserControl LoadControl(string userControlPath, params object[] constructorParameters)
    {
        var constParamTypes = new List<Type>();
        foreach (var constParam in constructorParameters)
        {
            constParamTypes.Add(constParam.GetType());
        }

        var ctl = Page.LoadControl(userControlPath) as UserControl;

        // Find the relevant constructor
        if (ctl != null)
        {
            var constructor = ctl.GetType().BaseType.GetConstructor(constParamTypes.ToArray());

            // And then call the relevant constructor
            if (constructor == null)
            {
                throw new MemberAccessException("The requested constructor was not found on : " + ctl.GetType().BaseType);
            }

            // constructor.Invoke(ctl, constructorParameters);
            object[] cp = constructorParameters;
            constructor.Invoke(ctl, cp);
        }

        // Finally return the fully initialized UC
        return ctl;
    } 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...