IDataErrorInfo, Infragistics WinGrid and Entities

Posts   
 
    
AlanD
User
Posts: 26
Joined: 19-Sep-2006
# Posted on: 28-Nov-2006 10:00:33   

Hi, I'm trying to display errors in an Infragistics UltraGrid pointing at an EntityCollection. I've seen an Infragistics doc that talks about exactly what I want. help @ infragistics

The crunch code is here:

    protected internal override void ultraGrid1_InitializeRow(object sender, InitializeRowEventArgs e)
    {
        foreach (UltraGridCell cell in e.Row.Cells)
        {
            if (e.Row.ListObject is ActivityDateEntity)
            {
                string rowError = "";
                string cellError = "";
                if (((DateTime)e.Row.Cells["DateVal"].Value) < DateTime.Parse("1995-1-1"))
                {
                    rowError = "Row contains errors.";
                    cellError = "Date is too early";
                }
                DataRowView drv = (DataRowView)e.Row.ListObject;
                drv.Row.RowError = rowError;
                drv.Row.SetColumnError("DateVal", cellError);
            }
        }
    }

Unfortunately, the "DataRowView drv = (DataRowView)e.Row.ListObject;" line throws this runtime error: Unable to cast object of type '...EntityClasses.ActivityDateEntity' to type 'System.Data.DataRowView'.

e.Row doesn't seem to have a RowError property; it's only the DataRowView Row that has this and I can't get one!

Any thoughts?

C# 2.0, VS2005 Self-servicing LLBLGen PRO designer: 1.0.2005.1.Final, July 6th 2006, SD.LLBLGen.Pro.ORMSupportClasses.NET20.dll version: 1.0.20051.60719

Thanks,

Alan

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39897
Joined: 17-Aug-2003
# Posted on: 28-Nov-2006 10:39:55   

What's the code you use to bind the data to the grid? Apparently you're not binding an entity collection to the grid but a typedlist/dynamiclist/typedview as the datasource seems to be a datatable.

Frans Bouma | Lead developer LLBLGen Pro
AlanD
User
Posts: 26
Joined: 19-Sep-2006
# Posted on: 28-Nov-2006 11:15:32   

Thanks for the prompt reply. OK, the binding method is generic because this grid is one of many, each one bound to a different entity collection type.

But I'm not intentionally binding to a typedlist/dynamiclist/typedview. Wouldn't that almost guarantee this to work as it is actually looking for an underlying DataTable and DataRow on which to base the DataRowView?

The actual binding line is this: ExpGrpBox.UltraGrid.DataSource = Collection; and Collection is of type IList when the binding method is called (I can't remember why I went for IList, probably trying to be ultra-generic for future-proofing).

Collection in this instance is an "activityEntity.ActivityDate" and is of type ....CollectionClasses.ActivityDateCollection

I tried changing the IList to CollectionBase and everything compiles fine, but I still get the error.

I do have some other things going on with the grid (dropdown lists via Infragistics ValueLists and a computed column), but the Date column should map straight through to the Entity's ActivityDate property.

Thanks,

Alan

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39897
Joined: 17-Aug-2003
# Posted on: 28-Nov-2006 12:17:17   

AlanD wrote:

Thanks for the prompt reply. OK, the binding method is generic because this grid is one of many, each one bound to a different entity collection type.

But I'm not intentionally binding to a typedlist/dynamiclist/typedview. Wouldn't that almost guarantee this to work as it is actually looking for an underlying DataTable and DataRow on which to base the DataRowView?

The actual binding line is this: ExpGrpBox.UltraGrid.DataSource = Collection; and Collection is of type IList when the binding method is called (I can't remember why I went for IList, probably trying to be ultra-generic for future-proofing).

Collection in this instance is an "activityEntity.ActivityDate" and is of type ....CollectionClasses.ActivityDateCollection

I tried changing the IList to CollectionBase and everything compiles fine, but I still get the error.

I do have some other things going on with the grid (dropdown lists via Infragistics ValueLists and a computed column), but the Date column should map straight through to the Entity's ActivityDate property. Thanks,

Alan

Well, one thing is clear: this particular routine you posted works with a datasource which is a datatable (which binds to a grid using its dataview (DefaultView). that's also why you get the cast error. So that's also why I asked for the binding code, I didn't ask that for nothing simple_smile Please check if the binding code indeed binds the collection and not a dynamiclist/typedlist or datatable.

Frans Bouma | Lead developer LLBLGen Pro
AlanD
User
Posts: 26
Joined: 19-Sep-2006
# Posted on: 28-Nov-2006 12:34:21   

Sorry, I'm lost here. I thought ExpGrpBox.UltraGrid.DataSource = Collection; _was _the binding code. I'm not sure what you want. Alan

AlanD
User
Posts: 26
Joined: 19-Sep-2006
# Posted on: 28-Nov-2006 12:55:24   

I'm sure the Grid is binding to the ActivityDateCollection. I'm sure it isn't binding directly to a typedlist or typedview (although at least one other column is bound to a valuelist to get a dropdown as explained above). I'm not clear what you mean by a dynamic list in this context unless it is a valuelist as above.

Could it be related to the fact that a different grid column is using a valuelist (although even that column is binding to an Entity property)?

Please check if the binding code indeed binds the collection and not a dynamiclist/typedlist or datatable.

Specifically - beyond me looking in the debugger and seeing that the grid is bound to an ActivityDateCollection, how should I do this?

Thanks, Alan

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39897
Joined: 17-Aug-2003
# Posted on: 28-Nov-2006 13:24:10   

Well, if you bind an entity collection to the grid, in the routine your code uses, then it indeed binds to a collection. HOWEVER, the routine you posted assumes the datasource is an entity collection but instead it's a datatable. An entity collection doesn't use datatables anywhere so it's either: - you accidently bound the wrong object to the grid or - the routine you posted is wrong as it should assume the datasource is a datatable because it works on a different datasource than the grid's one.

Now you said that there are more data-containing objects in the grid like value lists etc. and it could be your routine refers to these. I'm not an infragistics expert so I don't know what all their classes and routines do, but it's simply: if you bind an entity collection to the grid by setting its datasource property to the collection, the data in a row of the grid is an entity and the exception indeed shouldn't happen, so the routine you posted is refering to another object than the collection bound to the grid.

Frans Bouma | Lead developer LLBLGen Pro
AlanD
User
Posts: 26
Joined: 19-Sep-2006
# Posted on: 28-Nov-2006 16:44:33   

Hi, Thanks for your time on this - really! However, I can't correlate two things you've said: 1) .. An entity collection doesn't use datatables anywhere .. 2) .. if you bind an entity collection to the grid by setting its datasource property to the collection, the data in a row of the grid is an entity and the exception indeed shouldn't happen ..

Is not one of the following two options correct?

Either A) The grid is bound to a DataTable and therefore the cast of the ListObject to a DataRowView works or B) The Grid is bound to an EntityCollection, with no DataTables as you say above, and therefore the cast of an Entity in the Collection fails because, in its own words, it is Unable to cast object of type '...EntityClasses.ActivityDateEntity' to type 'System.Data.DataRowView'.

I believe the situation is B) and I'm unclear how the ListObject which is an Entity (with no DataTables or DataRows) can be cast to a DataRowView.

Obviously, the Grid has DataRows, albeit an Infragistics proprietary version, but I'm trying to cast from the ListObject, not the DataRow (the DataRow cast doesn't work either).

the routine you posted assumes the datasource is an entity collection but instead it's a datatable

I can't see how the datasource can be a DataTable; the debugger keeps telling me it's an ActivityDate Entity collection, which is what I think I've set it to. How could I prove or otherwise it's a DataTable?

Thanks,

Alan

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39897
Joined: 17-Aug-2003
# Posted on: 28-Nov-2006 17:47:12   

Ok, I decided to look again at the routine you posted, as I must have overlooked something. And then I saw this line: DataRowView drv = (DataRowView)e.Row.ListObject;

Now, as you are stating (correctly) you bound an entity collection to the grid, the ListObject of a Row is ofcourse an entity, and not a DataRowView object. Why did you write that?

So change that in: ActivityDateEntity activity = (ActivityDateEntity)e.Row.ListObject; and proceed with that simple_smile

Frans Bouma | Lead developer LLBLGen Pro
AlanD
User
Posts: 26
Joined: 19-Sep-2006
# Posted on: 29-Nov-2006 10:34:57   

Thanks Frans, Yes, e.Row.ListObject will cast to ActivityDateEntity as that is its type. We're saying that it isn't possible to use IDataErrorInfo because the underlying source isn't based on any sort of DataTable.

I realised that one of my (probably many!) confusions is that I was considering an UltraGrid.Row and a DataTable.Row to be almost the same thing and of course they aren't; the UltraGrid.Row is geared around display - the real data (and the error information) is in DataTable.Row which is absent in this case.

If it's not possible to use IDataErrorInfo and the associated DataRowView, is there another way?

I'm back to square one as what I want is to be able to display errors in the style shown in the Infragistics doc. I can do it manually by dropping my own error images into the cell, column caption and rowselector of the UltraGrid to get the Infragistics effect but is there a better more automated way?

Thanks,

Alan

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39897
Joined: 17-Aug-2003
# Posted on: 29-Nov-2006 11:32:54   

AlanD wrote:

Thanks Frans, Yes, e.Row.ListObject will cast to ActivityDateEntity as that is its type. We're saying that it isn't possible to use IDataErrorInfo because the underlying source isn't based on any sort of DataTable.

Huh? confused Every entity implements IDataErrorInfo, so you can cast an entity to IDataErrorInfo and call the IDataErrorInfo methods...

I realised that one of my (probably many!) confusions is that I was considering an UltraGrid.Row and a DataTable.Row to be almost the same thing and of course they aren't; the UltraGrid.Row is geared around display - the real data (and the error information) is in DataTable.Row which is absent in this case.

No!. There's no datatable, a datatable has nothing to do with it, you cast to DataRowView which is wrong as the data object is an entity, so change that and everything is fine. I got confused because you were casting to a DataRowView and I thought you had bound a datatable to the grid, but your code simply had a wrong cast.

There's NO datatable anywhere, just forget about datatables in this case, you're working with entity classes. simple_smile

The cast error you got can have two different causes: - Your routine is correct and you bound the wrong object - Your routine is wrong (it casts to the wrong type) and you bound the correct object (this is your situation).

I thought of option 1, hence my questions about datatables. As it's option 2, forget about datatables. LLBLGen Pro doesn't use datatables in entities.

If it's not possible to use IDataErrorInfo and the associated DataRowView, is there another way?

There's no dataview/datarowview or datatable. there's an entity and it implements IDataErrorInfo, please see the reference manual.

Frans Bouma | Lead developer LLBLGen Pro
AlanD
User
Posts: 26
Joined: 19-Sep-2006
# Posted on: 29-Nov-2006 17:28:07   

OK. I can't find any reference to IDataErrorInfo in the manual. Am I right in saying that IDataErrorInfo was implemented per entity in V2? As per the original email, I'm using V1.

Either way, I've spent most of today manually putting error indicators into grid cells so I'll probably go with that.

I'm happy to close this thread if you are.

Thanks for your help, Alan

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39897
Joined: 17-Aug-2003
# Posted on: 29-Nov-2006 18:32:25   

AlanD wrote:

OK. I can't find any reference to IDataErrorInfo in the manual. Am I right in saying that IDataErrorInfo was implemented per entity in V2? As per the original email, I'm using V1.

Aha, that's the cause then of our misunderstanding. Indeed, V2 entities contain IDataErrorInfo implementations, v1 entities do not.

Either way, I've spent most of today manually putting error indicators into grid cells so I'll probably go with that. I'm happy to close this thread if you are.

I'm sorry you had to spend most of your day with that boring work to get it to work. I can't think of an easy way to add it to v1 code. It's easy to implement the interface via a template change, though it also requires support from validation logic which is harder to do in v1. It is doable but not as simple.

Frans Bouma | Lead developer LLBLGen Pro