注入了不同数据的多个用户控件显示相同的数据

时间:2011-04-11 16:55:36

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

在我创建基于数据编写的用户控件的新实例的页面上工作。我使用构造函数注入将过滤后的数据传递给用户控件。但是,当用户控制渲染时,仅为所有用户控件呈现注入的最后一组数据。看来我引用的是同一个实例而不是创建一个新的独立实例。想法?

 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 :(得分:0)

它闻起来像一个封闭问题。我的预感是eob只是在每次迭代期间被重新赋值,而不是重新创建。由于你的控件都引用了eob而不是eob返回的数据,因此它们在渲染时都会使用相同的值。

您的LoadControl重载是什么样的?我仔细阅读了你引用的文章,但我想看看你做了什么,特别是。我想知道如果简单地将值从eob重新分配给在LoadControl方法中声明的变量会让你超过驼峰。强制控件使用较窄范围内的变量,以便它们无法在物理上看到彼此的参数。

编辑:找到有关该主题的SO参考:What are 'closures' in .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;
    } 

答案 1 :(得分:0)

如果我有这个问题并且有一个基类我可以检测并且可以产生某种痕迹而不会有太多麻烦,我会

  • 将const实例成员Guid和DateTime放在构造函数
  • 中进行初始化
  • 在对构造函数的单独调用之间进行几毫秒的睡眠,以便时间戳

我只是想这可能会暗示正在发生的事情并导致它的根源。