This is a migrated thread and some comments may be shown as answers.

Binding to DataTable cells with complex objects

10 Answers 816 Views
GridView
This is a migrated thread and some comments may be shown as answers.
Kyle
Top achievements
Rank 1
Kyle asked on 31 May 2012, 05:54 PM

Hi,

I’m trying to use a data grid view to bind to a data table where each cell holds an object of a known type.  I would like to bind the grid cells’ values to a particular property of these objects and bind colours and other attributes to other properties.

For example, each cell might have the following as its value:

interface ICellObject

{

                object Value {get;set;}

                bool IsDirty {get;set;}

}

When someone edits a cell, I would like it to store the value in the Value property.  The cell colour would be bound to an expression using the IsDirty property.  The actual ICellObject reference would never be changed. Would this be possible, and how would I do it?

Thanks,

Kyle

10 Answers, 1 is accepted

Sort by
0
Kyle
Top achievements
Rank 1
answered on 02 Jun 2012, 12:52 AM
Hi,

I thought that I would have been able to solve this using DataTemplates, but it doesn't seem to be enough.  I created a simple DataTemplate like this:

<DataTemplate x:Key="FieldValueTemplate" >
            <TextBox Text="{Binding CurrentValue}"/>
</DataTemplate>

and set it as the CellTemplate for the columns (added in code, so I don't have XAML for that).  The object stored in each cell has an object propety called CurrentValue.  The idea is to evenutally provide a custom control in the template that supports value reverting.  

I do get text boxes for each cell, but they aren't bound to the CurrentValue property.  When I bind the grid to a DataTable and set the cell template, is the template binding to the DataRow object, DataColumn object, or the value stored in the cell?

Thanks,

Kyle 
0
Dimitrina
Telerik team
answered on 04 Jun 2012, 12:07 PM
Hi Kyle,

 The DataContext for the TextBox inside the CellTemplate is the DataObject bound to the corresponding row.
For example if you have a Collection<RowObject> and RowObject has a property "CurrentValue", then the context of the TextBox will be a "RowObject" and the Path of the binding will be "CurrentValue". The same applies for the DataMemberBinding of the column.

I hope this helps.

Greetings,
Didie
the Telerik team

Explore the entire Telerik portfolio by downloading the Ultimate Collection trial package. Get it now >>

0
Kyle
Top achievements
Rank 1
answered on 04 Jun 2012, 03:39 PM
Thanks Didie,

That makes sense, and I was able to confirm it.  I played around with it this morning and was able to get around it by creating a custom data column that overrides the control creation to index the data row and pass the column of interest to the object.  I can now style the cell nicely based on the properties of each cell in the DataTable.

Thanks,

Kyle
0
Dimitrina
Telerik team
answered on 05 Jun 2012, 10:06 AM
Hi Kyle,

As you want to style the cell based on the properties of each cell, then I would suggest you use CellStyleSelector as explained in this help article.

Kind regards,
Didie
the Telerik team

Explore the entire Telerik portfolio by downloading the Ultimate Collection trial package. Get it now >>

0
Kyle
Top achievements
Rank 1
answered on 08 Jun 2012, 04:03 PM
Thanks for the help, Didie.

I read the article that you sent, and it does look promising.  It's a little more code and less XAML than I would like, but it would allow me to use the default grid column behaviour with custom styles.  

I would still need to create a custom grid column to perform custom binding to bind each cell not to a row, but to the object contained in the column, but I can see how that would work.

Thanks,

Kyle
0
Kyle
Top achievements
Rank 1
answered on 08 Jun 2012, 07:10 PM
Hi,

I tried out the styling, and unfortunately it doesn't quite solve the problem.  I'm sorry for continually posting on this, but our project hinges on how to do something like the following:

We want to data bind the grid to a list of objects, where each object will be a row.  The object can have a dynamic number of fields, each of which will be a column in the grid.  As an example, let's use a Person, which can have multiple ways to contact it.

Person
- FirstName : string
- LastName : string
- ContactMethods : ObservableCollection<ContactMethod>

ContactMethod
- MethodName : string
- Data : object

We want to put this in the grid so that the firstname, lastname, and each contact method are columns.  The column names for the ContactMethods would be the MethodName field.  The actual binding and setting up the columns would not be a problem.  That can be done through code.
 
Where it becomes tricky is in the requirement that we style the grid on a per cell level.  For instance, we would want the ContactMethod to store an original value and colour the cell based on whether or not the user had entered a new value and if that value was valid (correct in form, and not a duplicate of any other value).  My first instinct would be to modify ContactMethod to have:

ContactMethod
- MethodName : string
- Data : object
- OriginalData : object
- IsModified : bool
- IsAddressValid : bool

The trick is that we want the cell to be bound to the ContactMethod object, not the Address, such that changing the cell value changes the Address property, but that the cell is styled based on the IsModified and IsAddressValid properties.  It's this binding behaviour that we can't quite figure out.  We don't want to use a cell template or create our own control because the Data could be any type of object, and we want to use the grid's controls.  

Specifically, although the cell is bound to a ContactMethod, we want to have the cell control chosen based on the type of the Data object (and bound to it), but we want the cell styling to come from the other properties on the bound ContactMethod.

If this type of binding isn't possible, could you suggest another way to tackle this?

Thanks,

Kyle




0
Vlad
Telerik team
answered on 11 Jun 2012, 06:21 AM
Hello,

 Have you tried your scenario with plain WPF DataGrid? Do you have something working with the standard grid and not working with RadGridView? Any limitations?

Kind regards,
Vlad
the Telerik team

Explore the entire Telerik portfolio by downloading the Ultimate Collection trial package. Get it now >>

0
Kyle
Top achievements
Rank 1
answered on 11 Jun 2012, 03:51 PM
Hi Vlad,

The regular WPF grid handles this more naturally because it respects DataTemplates.  In the WPF grid, I can set up a DataTemplate to always show a NameView object every time that a NameViewModel is shown in any view.  In this way, if I have:

PersonViewModel
- FirstName : NameViewModel
- LastName : NameViewModel

I can put a collection of PersonViewModel in the grid, and each cell will show a NameView control which will be bound to the NameViewModel. If I do the same thing in RadGrid, it just shows the type name of NameViewModel.    

In the end, I was able to get things working in a bit of a round-about fashion.  Assume that NameViewModel looks like this:

NameViewModel
- Name : string
- Colour : Color

So that the name is always shown in the colour.  The tricky part was to get the editing to be based on the Name property but the Colour to be based on the Colour property.  To do this, I created a GridViewColumn in code, binding it to "FirstName.Name", so that it would edit the Name.  I then created a custom style selector in code and bound it to "FirstName", so that it could inspect the whole NameViewModel (doing my own binding evaluation) to create a style based on the Colour on the fly.  It gets much more complicated that that, but that's the basic idea.  

Thanks for your help,

Kyle
0
Raza
Top achievements
Rank 1
answered on 23 Apr 2015, 01:48 PM

Hi Any updates on this topic..? Actually I am stuck with the same issue. I am trying to bind my datagrid with datatable and the number of columns generated in the grid is on run time. So I cannot provide celltemplate or cellstyle or even celltemplateselector as there is no columns define in xaml or code behind. columns are generated through datatable on run time. Any idea. How to bind a daynamically generated column of custom data type fields in telerik radgridview thanks..

 

0
Dimitrina
Telerik team
answered on 24 Apr 2015, 12:58 PM
Hi,

You can subscribe for the AutoGeneratingColumn event and replace the auto-generated column or configure it as you wish.
As side note, my recommendation would be to set RadGridView's ItemsSource to be DataTable.DefaultView. 


Regards,
Dimitrina
Telerik
 

See What's Next in App Development. Register for TelerikNEXT.

 
Tags
GridView
Asked by
Kyle
Top achievements
Rank 1
Answers by
Kyle
Top achievements
Rank 1
Dimitrina
Telerik team
Vlad
Telerik team
Raza
Top achievements
Rank 1
Share this question
or