【问题标题】:C# + bindingsource value gets overwrittenC# + bindingsource 值被覆盖
【发布时间】:2014-11-11 14:16:13
【问题描述】:

这是我的要求:我有一个 datagridview,应该填充来自 sch.shift_detailsList(entity model-shift) 中的班次详细信息的员工班次数据。例如:shift for 1 week(nov 1 to nov 7) 保存在 sch.shift_detailsList 中。所以在 datagridview 中如果 weekcount=2(即 shift 要保存 2 周,即 cycledays=7*2 -1=13 ) ,bindingsource1(对于datagridview)应该填充2周的班次,即如果开始日期为nov1,那么sch.shift_detailsList中的班次详细信息也应该在第2周重复。因此,当循环完成第 1 周然后 i=7 时,它应该从 sch.shift_detailsList 的第一项开始,并且 bindingSource1 (8) 日期中的第 8 个条目应该是 nov 8th 。但我的问题是现在, bindingSource1 (0) 和 sch.shift_detailsList (0) 中的日期也设置为 11 月 8 日,并且直到第 6 行的所有后续行都相应地被新值覆盖。我不知道为什么会这样。如果有人可以帮助我,我将不胜感激。

List<Model.Shiftdetails> schdetails = new List<Model.Shiftdetails>();
bindingSource1.DataSource = schdetails;
gridControl1.DataSource = bindingSource1;

int k=0;

for (int i = 0,j=0; i <=cycledays; i+=7)
{
    foreach (Model.Shiftdetails detail in sch.shift_detailsList)
    {
        Model.Shiftdetails cycleschdetails = new Model.Shiftdetails();
        cycleschdetails = detail;
        cycleschdetails.shift_date = dtCycleStartDate.DateTime.Date.AddDays(j);

        j++;
        k++;

        if (cycleschdetails.schedule == null)
        {
            cycleschdetails.schedule = new Model.Schedule { id = -1, schedule_info = new Model.ScheduleInfo { schedule_name = crm.GetString("NoShift") }, schedule_flexible = true };
        }

        bindingSource1.Add(cycleschdetails);
        bindingSource1.MoveNext();

       if (k > cycledays)
           break;

    }

    if (k > cycledays)
        break;
} 


values of binding source are now:
datasource[0] date=nov 8
datasource[1] date=nov 9
datasource[2] date=nov 10
datasource[3] date=nov 11
datasource[4] date=nov 12
datasource[5] date=nov 13
datasource[6] date=nov 14
datasource[7] date=nov 8
datasource[8] date=nov 9
datasource[9] date=nov 10
datasource[10] date=nov 11
datasource[11] date=nov 12
datasource[12] date=nov 13`enter code here`
datasource[13] date=nov 14

谢谢

【问题讨论】:

  • 这可能是因为您放入bindingSource1 中的项目是对sch.shift_detailsList 中项目的引用,而不是新的Shiftdetail 对象。与其说cycleschdetails = detail,不如尝试为对象上的每个属性说cycleschdetails.someProp = detail.someProp。另外,只是一个友好的提示,请更正或标准化您的命名约定,这会让人难以阅读。
  • 非常感谢本。现在解决了。
  • 太棒了,我会发布这个答案。

标签: c# datagridview


【解决方案1】:

代码的问题是当你这样做时:

cycleschdetails = detail;

cycleschdetails 是对detail 的引用。因此,您在 cycleschdetails 上所做的任何更改也将在 detail 上进行。这第一次工作得很好,但是第二次,当你再次循环这些相同的对象时,detail 将再次被修改,导致两个引用它的对象都被更改。

解决这个问题的方法是:不要将对象设置为对细节的引用,而是将对象的属性设置为彼此相等。只要它们是原始类型(字符串、整数、小数等),它们之间就不会创建引用。

类似:

cycleschdetails.SomeString = detail.SomeString;
cycleschdetails.SomeInt = detail.SomeInt;

但是,如果您在其中有嵌套对象,您将遇到同样的问题,并且必须对这些对象执行相同的操作。

这很糟糕

cycleschdetails.CustomObject = detail.CustomObject;

这很好

cycleschdetails.CustomObject.SomeProperty = detail.CustomObject.SomeProperty;

你明白了 ;) 基本问题是,当对象被设置为等于其他东西时,它们具有绑定到它们的引用,但是原始类型没有。

提供一个完整的例子(只是因为我喜欢我自己的声音;))

class Program {
    static void Main(string[] args) {
        TestClass test1 = new TestClass() {
            SomeInt = 1
        };
        Console.WriteLine(test1.SomeInt); // outputs 1

        TestClass test2 = test1;
        test2.SomeInt = 2;
        Console.WriteLine(test1.SomeInt); // ouputs 2

        TestClass test3 = new TestClass();
        test3.SomeInt = test1.SomeInt;
        test3.SomeInt = 4;
        Console.WriteLine(test1.SomeInt); // ouputs 2 still

        Console.ReadLine();            
    }
}

public class TestClass {
    public int SomeInt { get; set; }
}

【讨论】:

  • 非常简洁,很好的答案!
猜你喜欢
  • 1970-01-01
  • 2016-12-27
  • 2013-09-02
  • 1970-01-01
  • 2010-12-07
  • 2013-01-05
  • 1970-01-01
  • 1970-01-01
  • 2020-03-23
相关资源
最近更新 更多