DataTable internal index is corrupted

前端 未结 18 1396
轻奢々
轻奢々 2020-12-04 15:55

I am working with a .NET WinForms app in C#, running against the 3.5 .NET framework. In this app, I am setting the .Expression member of a DataColumn in a

18条回答
  •  有刺的猬
    2020-12-04 16:19

    In my case the Framework version is 2.0. The source of a problem was in DataView ListChanged event. The code below initializes the new row with some default values.

    private void dataView_ListChanged(object sender, ListChangedEventArgs e)
    {
        if (e.ListChangedType == ListChangedType.ItemAdded)
        {
            DataView v = (DataView)sender;
            DataRowView drv = v[e.NewIndex];
    
            // This "if" works fine
            if (drv["Foo"] == DBNull.Value)
            {
                drv["Foo"] = GetFooDefault();
            }
    
            // This "if" brakes the internal index     
            if (drv["Bar"] == DBNull.Value && drv["Buz"] != DBNull.Value)
            {
                drv["Bar"] = drv["Buz"];
            }
        }
    }
    

    After some investigation it became clear that ItemAdded event is called at least twice per row. First time when the UI creates new line for entering data and second time, well I'm not sure, but looks like when the DataRowView is added to a DataView.

    The first "if" works only when the ItemAdded is called first time. On second call "Foo" column is already populated and left as is.

    However the "Bar" column defaulting code can be executed on both calls. Actually in my case it was executed only on second ItemAdded event, when the user had a chance to fill in the data for "Buz" column (initially "Buz" has DBNull value).

    So here is recommendations based on my findings:

    • The data in ListChanged event can be changed only when e.ListChangedType == ListChangedType.ItemAdded.
    • Prior to setting the column value the check should be performed to ensure that this is the first ItemAdded event (e.g. if the value cannot be null on second call, check if it is DBNull.Value etc.)

提交回复
热议问题