Using The Silverlight DataGrid
This post has been updated to work with the RTW version of the Silverlight 2 DataGrid. The code examples are not guaranteed to work with previous Beta versions of the DataGrid. Read more about the features that the Silverlight 2 DataGrid has to offer... |
If you have ever worked on an application that displayed large amounts of data, one of the cornerstones of your application was probably a DataGrid control. We have provided four .NET DataGrids over the years, two for ASP.NET and two for Windows Forms, but until now Silverlight and WPF were left out of the party.
At MIX 2008 we shipped the first preview of the Silverlight DataGrid and a preview of it in WPF was also shown. Now that it is out there people want to know how to use it. If you are one of those people, then you have come to the right place. Here's a quick guide on how to get up and running with a Silverlight DataGrid.
Step 0: Create A Silverlight Project
Start a new Silverlight Application as outlined in my previous post. When given the option, choose the default "Add a new ASP.NET Web project" option.
Step 1: Add a DataGrid
If everything went smoothly in the previous step, your project should be loaded and opened to Page.xaml. Now just find the DataGrid on the Toolbox and drag it into the root layout Grid named "LayoutRoot".
This does a few things behind the scenes:
It adds a reference in your Silverlight project to System.Windows.Controls.Data
It adds an xmlns called "data" to the root UserControl that specifies that the DataGrid is in the System.Windows.Controls namespace and located in the System.Windows.Controls.Data assembly
-
xmlns:data="clr-namespace:System.Windows.Controls; assembly=System.Windows.Controls.Data"
-
It adds an instance of the DataGrid as a child of "LayoutRoot"
-
<data:DataGrid></data:DataGrid>
-
If you are the type of the person who likes to see things working after each step, feel free to F5 (choose the option to allow debugging in the popup) and take in the awesome sight that is an empty DataGrid.
Not much here, so lets fill it with something.
Step 2: Set the ItemsSource and AutoGenerateColumns
The way to make a DataGrid interesting is by giving it some data. This is done through the DataGrid's ItemsSource property. This is same property that other controls in WPF and Silverlight, such as ListBox, use to specify where they will get their data. The one difference here is that you cannot place arbitrary content in it and have it create a collection for you.
Instead you need to provide it a collection of anything that implements IEnumerable such as a List or ObservableCollection.
The ItemsSource can be specified inline in XAML such as:
<data:DataGrid x:Name="dg">
<data:DataGrid.ItemsSource>
<!--Something that implements IEnumerable -->
</data:DataGrid.ItemsSource>
</data:DataGrid>
However, it is more commonly set in code behind, which is what we will do in this example.
Step 2 A: Name the DataGrid and build
Before we go to the code behind you will want to be sure to give the DataGrid a name such as "dg". Also be sure to build so that you can reference the DataGrid in code:
<my:DataGrid x:Name="dg" ></my:DataGrid>
Step 2 B: Create and Set the Items Source
Now that the DataGrid is ready to have its ItemsSource set, go to the Page's constructor located in the code behind file for Page.xaml (A handy shortcut to do this from within Page.xaml is F7) and add the following line below InitializeComponent:
C#
public Page()
{
InitializeComponent();
dg.ItemsSource = "H e l l o W o r l d !".Split();
}
VB
Public Sub New()
InitializeComponent()
dg.ItemsSource = "H e l l o W o r l d !".Split()
End Sub
(If you get the build error: "The name 'dg' does not exist in the current context" with the code above be sure to build a second time so that the name has a chance to propagate)
One of the easiest ways to generate an IEnumerable collection is String.Split. When the resulting array is set as the ItemsSource of the DataGrid a column will be automatically generated since AutoGenerateColumns is true. When you run the application, it will look like this:
This is a little better, but so far this could be done with a ListBox. Lets add some more complicated data so that we actually need to use a DataGrid.
Add a new class to your Silverlight project (not the Web project) and name it "Data".
Then add a few properties to bind to.
C#
If you are using C#, you can use the great 3.0 Automatic Properties feature.
public class Data
{
public string FirstName { get; set; }
public string LastName { get; set; }
public int Age { get; set; }
public bool Available { get; set; }
}
VB
Public Class Data
Private _firstName As String
Private _lastName As String
Private _age As Integer
Private _available As Boolean
Property FirstName() As String
Get
Return _firstName
End Get
Set(ByVal value As String)
_firstName = value
End Set
End Property
Property LastName() As String
Get
Return _lastName
End Get
Set(ByVal value As String)
_lastName = value
End Set
End Property
Property Age() As Integer
Get
Return _age
End Get
Set(ByVal value As Integer)
_age = value
End Set
End Property
Property Available() As Boolean
Get
Return _available
End Get
Set(ByVal value As Boolean)
_available = value
End Set
End Property
End Class
Once the Data class is defined, it can now be used to provide data for the DataGrid. Go back to the code behind file for Page.xaml and replace the previous ItemsSource assignment with the following. A useful trick here is to use the C# and VB 3.0 Object Initializer feature to initialize the Data objects as we add them to the List.
C#
public Page()
{
InitializeComponent();
//dg.ItemsSource = "H e l l o W o r l d !".Split();
List<Data> source = new List<Data>();
int itemsCount = 100;
for (int i = 0; i < itemsCount; i++)
{
source.Add(new Data()
{
FirstName = "First",
LastName = "Last",
Age = i,
Available = (i % 2 == 0)
});
}
dg.ItemsSource = source;
}
VB
Public Sub New()
InitializeComponent()
'dg.ItemsSource = "H e l l o W o r l d !".Split()
Dim Source As List(Of Data) = New List(Of Data)
Dim ItemsCount As Integer = 100
For index As Integer = 1 To ItemsCount
Source.Add(New Data() With _
{ _
.FirstName = "First", _
.LastName = "Last", _
.Age = index, _ .Available = (index Mod 2 = 0) _
})
Next
dg.ItemsSource = Source
End Sub
When you run this you will notice that columns are created for you. This is because auto-generation takes over, using reflection to create a column for each property in Data, setting the column header to the name of the property, and choosing default column types based on the property type. For instance the Available column is a DataGridCheckBoxColumn. (If you did not want this behavior, but rather wanted to choose your own columns, you can do this by setting the DataGrid's AutoGenerateColumns property to false. For information on choosing your own columns see my post on Defining Columns for a Silverlight DataGrid)
Step 3: Simple Customization of the DataGrid
The easiest way to customize the DataGrid is through a variety of properties. The other two ways are through Styles and Templates which will be covered in future posts. Some of the most useful properties for customization are:
GridLinesVisibility & HeadersVisibility
These properties are enumerations that control what gridlines and headers are displayed.
RowBackground & AlternatingRowBackground
These properties are shortcuts to setting the background color for both rows and alternating rows.
ColumnWidth & RowHeight
These properties set the default column width and default row height.
IsReadOnly & CanUserResizeColumns
These properties control if the end user can edit the data in the grid and if the columns can be resized.
For instance if you set the following properties to the following values:
<data:DataGrid x:Name="dg" AutoGenerateColumns="True"
GridlinesVisibility="None" HeadersVisibility="All"
RowBackground="Cornsilk" AlternatingRowBackground="LemonChiffon"
ColumnWidth="85" RowHeight="30"
IsReadOnly="True" CanUserResizeColumns="False"
>
</data:DataGrid>
Step 4: Enjoy
Now that you have the basics, enjoy using the DataGrid. Next time I'll go into how to explicitly define and customize columns instead of using auto generation.
Also, you can read more about the features that the Silverlight 2 DataGrid has to offer...
Comments
Anonymous
March 20, 2008
Great! Silverlight DataGrid Silmal asp.net datagrid!Anonymous
March 20, 2008
Hi Scott - thanks for this blog post. When do you gyus plan to virtualize the Grid? Now it is practicaly unusable with large data. What are your plans in this area? Thanks! Keep up the great work :)Anonymous
March 21, 2008
Hi Valentin - Currently we do have UI virtualization but not data virtualization. We have been testing the DataGrid with millions of rows and have been seeing favorable results. Also we plan to continue to make performance enhancements throughout development. I would love to hear any specific scenarios where you are seeing performance issues. Please email me through the Email link above so that we can dig into the specifics. Thanks for the feedback!Anonymous
March 21, 2008
Scott Morrison ( the PM for the Silverlight DataGrid) recently posted a very good walk through of usingAnonymous
March 21, 2008
How can i fill my datagrid with a query of sql? i can't use directly ..i don't know why =( Please, show me an example =DAnonymous
March 21, 2008
The comment has been removedAnonymous
March 21, 2008
Shawn Wildermuth creates Linkable SL Apps, Scott Morrison on Getting Started with SL2 and a walk-thruAnonymous
March 21, 2008
Hi Scott; You mentioned you have tested the grid with a million records. I've been waiting for SL 2.0 for over a year and now that is out, I don't have any database capabilities to develop business applications that works with data files from SL. My first question is, how are you getting a million of records into SL and secondly, when are we going to have database programming incapabilities to develop t-tier apps with SL? Thank you and if you can't answer my second question, could you please point to the right person?Anonymous
March 21, 2008
Over at Scott Morrison's blog he has a great entry on how to setup and use the datagrid control in SilverlightAnonymous
March 21, 2008
I highly recommend if you are interested in adding a SQL data source, yes you can do this by creating a webservice and using the LINQ2SQL functions. Remember SL 2.0 is client side so you are going to have to do something still serving it that sql data.. In fact with LINQ you can use any kind data you want.. Check out this video blog tutorial from the Swiss MSDN TEAM.. http://blogs.msdn.com/swiss_dpe_team/archive/2008/03/17/silverlight-2-beta1-wcf-linq-to-sql-a-powerfull-combination.aspx After watching this you should find it very easy to be mapping SQL data to the datagrid... -DonAnonymous
March 21, 2008
Hi Don; Thank you for the link. Before I get started to develop a complex middle tier data server (using WCF) for my SL client (which can become fairly complex, I like to know what are the plans from MSFT to provide us with some tools for the middle tier. I like to know if Astoria is the solution for SL or id SL team have a more customized solution for SL? Again, I don't want to re-invent the wheel, if the team is already working on it. I'm going to watch the video now, thank you again!Anonymous
March 22, 2008
Hi, I wrote a very small article on how one can make the DataGrid show up in Blend ... http://marlongrech.wordpress.com/2008/03/22/how-can-i-get-the-datagrid-control-for-silverlight-2-beta-1-to-show-up-in-blend/ RegardsAnonymous
March 23, 2008
You've been kicked (a good thing) - Trackback from DotNetKicks.comAnonymous
March 24, 2008
The comment has been removedAnonymous
March 24, 2008
Hi Diego, Based on what you are saying I'm guessing that what you have the DataGrid bound to is something like an IEnumerable which does not persist changes made to it. If this is the case, then when you scroll a row out of view and then back in the row's data is being refreshed from the data source due to a performance increasing process called UI virtualization. Since the IEnumerable doesn't accept the changes, you get the original value. To fix this behavior, instead bind your DataGrid to a List or ObservableCollection. If you are using XLinq to query your XML then you can use the shortcut method .ToList<T> on the collection that was returned from the Linq expression. Hope this helps. -ScottAnonymous
March 24, 2008
Hi, Scott, thanks for the post. I'm attempting to implement sorting using the DataGrid, do you have an example as a starting point? Thus far I've found it challenging and haven't found an example (yet) that implements this basic feature.Anonymous
March 24, 2008
A very nice walkthrough on using the new Silverlight DataGrid can be reached here: Using The SilverlightAnonymous
March 24, 2008
Hi Scott, Since I attempt binding with adding row dynamicly using List<T> I found that we have to set ItemSource property of datagrid to null value before we set again with correspondence List<T>, do you have any solution other than this...? Thanks for your attention -MalkyAnonymous
March 25, 2008
I'm currently unable to test this myself, but does the silverlight datagrid support freezepanes? And if not are there any future plans to add this support?Anonymous
March 25, 2008
I don't see any mention of paging in this post or in the docs. Is paging not supported by the SL2 DataGrid?Anonymous
March 25, 2008
Ethan, I'll be posting a topic on it however there are a dozen or so topics in the queue before it so it could be a while. To get you started, be sure to bind to an ObservableCollection<T> or some other collection that implements INotifyCollectionChanged. Then you can change the contents of the collection (such as sorting it) and have these changes reflected in your DataGrid. Malky, The answer to your question is actually the same as Ethan's. To avoid the behavior that you are seeing you need to bind to something that gives collection changed notifications so that the DataGrid knows to update itself. Go ahead and use an ObservableCollection and you should see the behavior that you want. -ScottAnonymous
March 27, 2008
Is there a way to set "dinamically" just the shown values... let's say i want the list work under a List<myIds> but when those ids will be presented then i will "catch" the other data that i will present form any source i want...Anonymous
March 27, 2008
If you read my last post , you might have noticed how easy it is to get a Silverlight DataGrid up andAnonymous
March 27, 2008
The comment has been removedAnonymous
March 29, 2008
Scott Guthrie lists a number of posts and videos about the Silverlight 2.0 DataGrid in March 28th LinksAnonymous
April 01, 2008
I'll be using this page to link to Silverlight 2 articles and posts (both ones I write as well ones byAnonymous
April 02, 2008
Silverlight 2 DataGrid 示范教程发布了Anonymous
April 03, 2008
Scott, I appreciate the blogs and the great work y'all are doing on the framework. But, I'm really lost on one thing: I want to make a DataGrid with 7 columns, the value of which each come from a separate table. All tables are related. So, I'm struggling with figuring out how I am supposed to get that data into a List or Collection of non-anonymous, non-DataRow objects from the server to the client. I'm trying to do the whole SL/WCF/EF thing here, I can't seem to figure out this piece.Anonymous
April 08, 2008
Firstly, what controls can I place in a DataGrids column? I would like to add a date picker, a button, a list (for simple lookups). Secondly, does (or when will) the DataGrid support Drag and Drop. Thanks RichieAnonymous
April 09, 2008
Hi Richie, Using a DataGridTemplateColumn you can essentially put any FrameworkElement in a column. Go ahead and read my next post http://blogs.msdn.com/scmorris/archive/2008/03/27/defining-columns-for-a-silverlight-datagrid.aspx for more info. As far as drag and drop, it is currently not a planned feature. Thanks, ScottAnonymous
April 10, 2008
The comment has been removedAnonymous
April 11, 2008
For information how how to use specific column types such as the CheckBox column, please read: http://blogs.msdn.com/scmorris/archive/2008/03/27/defining-columns-for-a-silverlight-datagrid.aspx for more info. Let me know if you have any questions that were not covered there. Thanks, ScottAnonymous
April 12, 2008
Una nueva cuadrícula de datos entra en liza Después de instalar el conjunto de herramientas necesariasAnonymous
April 13, 2008
Nice intro... are you going to write a part 2 talking about the details view? Thanks BraulioAnonymous
April 14, 2008
Now that you know the basics of the Silverlight DataGrid and how to specify the Columns in XAML , youAnonymous
April 14, 2008
Hi Braulio, Row Details is on the list of upcoming posts and should show up soon. Thanks for reading. -ScottAnonymous
April 17, 2008
Can a column have an icon/image? What type would it be?Anonymous
April 17, 2008
Any updates yet on the paging issue? thanks guysAnonymous
April 21, 2008
Gulsen, You can use a TemplateColumn for that. See http://blogs.msdn.com/scmorris/archive/2008/03/27/defining-columns-for-a-silverlight-datagrid.aspx for how to use them. Hope this helps. -ScottAnonymous
April 21, 2008
Scott Morrison has a great post on basic DataGrid usage in Silverlight. Check it out!Anonymous
April 28, 2008
I've been OOF on vacation (Hawaii, where it's warm!). But I'm back now and here's a few new sample applicationsAnonymous
May 20, 2008
NowthatyouknowthebasicsoftheSilverlightDataGridandhowtospecifytheColumnsinXAML,you...Anonymous
May 20, 2008
Ifyoureadmylastpost,youmighthavenoticedhoweasyitistogetaSilverlightDataGridupand...Anonymous
May 21, 2008
Can I use it with ASP.NET MVC Framework?Anonymous
May 27, 2008
Hello Scott, Thank you very much for this post! It provides a good introduction to the DataGrid. Playing with the DataGrid we encountered a challenge, that we do not succeed to overcome: Is there a way to have different RowHeight per row? And is it possible to define a functionality that will act like: "RowHeight=Auto"? Thanks a lot! YevgenyAnonymous
May 30, 2008
Hi Yevgeny, The autosizing feature for rows is coming soon, so stay tuned. -ScottAnonymous
May 30, 2008
What about data from and to SQL???Anonymous
June 03, 2008
Hi Chris, There are a few links to the Swiss MSDN Blog who have some great walkthroughs on how to do that here: http://blogs.msdn.com/scmorris/archive/2008/06/02/new-posts-coming-soon.aspx Hope this helps. -ScottAnonymous
June 03, 2008
its gud but explain it more its beneficial for beginner. thnxAnonymous
June 04, 2008
DefiningColumnsforaSilverlightDataGridAnonymous
June 04, 2008
今天找到關於SilverlightDataGrid的一些技巧,記錄下來,以備後用.Anonymous
June 04, 2008
DefiningSilverlightDataGridColumnsatRuntime NowthatyouknowthebasicsoftheSilverlightD...Anonymous
June 06, 2008
The comment has been removedAnonymous
June 15, 2008
The comment has been removedAnonymous
June 21, 2008
Silverlight2.0beta中据说对DataGrid控件有了不少增强,于是在网上搜了下,找到该项目的PM写的一个介绍帖子:http://blogs.msdn.com/scmor...Anonymous
June 23, 2008
How one can make the DataGrid show up in Blend June 2008 Preview ?Anonymous
June 26, 2008
can i change single row style at runtime when i select any row then style of that row should be chagedAnonymous
June 26, 2008
Nice post, Do you know if a grouping feature is planned for the DataGrid?Anonymous
June 29, 2008
Hey, Nice work, I have a question here, Last night i was playing with the datagrid and i could find 2 most important feature, which should be there anyway,
- There is no rowdatabound event, the closest thing i found was RowLoading event, which fires only once, I was able to change the data using the PropertyChanged event, but I was not able to change the row style.
- I was unable to access the Cells property of the DataGridRow class, later i found it but marked as internal, why is that?
Anonymous
August 21, 2008
can you access SL Datagrid rowtype like asp.net datagrid? and could you list all SL Datagrid event? thanksAnonymous
September 08, 2008
can you update a specific position in a data grid .. ie column 6 row 5 with code behind routine as oposed to doing it manually? My hope is to update the grid without updating the source?Anonymous
September 30, 2008
I find that I can not get the DataGrid to work in the RC0 release. I drag it from the toolbox to the XAML and it is placed in the XAML, but then an error occurs: "The type 'DataGrid' was not found...". The assembly System.Windows.Controls.Data v2.0.5.0 is referenced. My installation: VS 2008 SP1, .Net 3.5 SP1, Silverlight 2 RC0 Any ideas? GregAnonymous
September 30, 2008
I solved the problem. There is a bug in dragging items from the toolbox to the XAML. I already had a TabControl in the XAML which created the appropriate reference at the top. Apparently when you do this again with a control that references a different assembly it fails. nothing is added to the top (i.e. xmlns:data="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data" should be added). If I temporarily delete the reference for the TabControl add the DataGrid - everything works correctly and then I add the reference for the TabControl back in. gregAnonymous
October 14, 2008
As you might have heard , we just released Silverlight 2 , and with it the first version of the SilverlightAnonymous
October 28, 2008
Hi guy, Nice post about this ! Hawever, I have a little question about the grid: How can I be notified that the grid has been sorted (after clicking a header) ? I haven't found any event for that? thanks again ! DjoDjoAnonymous
November 14, 2008
may be datagrid's scroll system is something wrong in the loading_row event, i had creat new binding object and bind DataGrid's RowVisibility property so some row to be not displayed(visibility.collapsed) but when scrolling scrollbar do not work visibility binding, by result all row display Scrollbar may be handling DataGrid Row's RowVisibility property internally.. my english skil so poor , do understand.Anonymous
November 19, 2008
Your Story is Submitted - Trackback from DotNetShoutoutAnonymous
November 23, 2008
Hey Scott, great post and well put together. I am just learning Silverlight, and this was very helpful. Thanks for taking the time and providing such a clear example.Anonymous
November 24, 2008
Scott, How can I disable virtualization? In WPF we can access the VirtualizingStackPanel, but in this case it seems to be something internal to the datagrid and I can't find how to disable it.Anonymous
January 20, 2009
Last week, I released the ComputeFileHashes tool for calculating file checksums . (To read more aboutAnonymous
February 25, 2009
The comment has been removedAnonymous
March 05, 2009
Hi Scott, Thanks for your article about silverlight datagrid . I’m learning silverlight datagrid , having some problems. How to add a hyperlink column in a silverlight datagrid and the hyperlink column can pass different parameter to it’s asp.net page. Thanks .Anonymous
April 16, 2009
hi scotttt its nice to see the example code and ur explaination... its helps me a lot... keep it upAnonymous
April 28, 2009
Do you have any article for SL Datagrid Sorting and Paging? - ThanksAnonymous
May 11, 2009
This is greate for beginners :o) Thank you!Anonymous
May 12, 2009
Hey Scott, just saw your session on Data Driven RIA's. Good talk. Nice stuff. I need to ask you though if you could elaborate on the groupby functionality in the out of band release of the datagrid. To me, that seems more like a reporting type of tool and not as useful as a master - detail - detail relationship that I could have built in traditional datasets. For example, if you have a collection of Authors who have each have a collection of books and also a collection of videos. In ASP.Net I would just build a relationship object between those three tables. It would be nice to be able to decompose that master record into the many collections which it may contain. I would also appreciate any feedback you could provide on performing this functionality on a UDF which throws up a table. In my real world, I might need to pull together 7 different tables for my forms which might involve unions, and the best way to do that is through a UDF. Forget about ASP Entity Framework at the moment as feel it is only about half backed.Anonymous
May 21, 2009
For a datagrid, how can I bind data without any code behind I mean my data will be defined in the xaml file. I don't want code anything in the c# or VB class. I know, in a c# code behind class, it is easy to do that. But, what I am trying to do is to dynamic generate xaml file in a string on server side, and send the string to the client side by using WCF service, then, load the xaml file string using XmlReader.Load(fileString), finally the xaml file will be displayed in the client side browser. There're so many reasons that I can't send data to client side and using c# class to load data to the class properties and sign it to the Datagrid.ItemSource. So, I have to build everything in the xaml file string. Can I do it? Thanks.Anonymous
June 15, 2009
Hi Scott, Is it possible to display a new column instead of new row when you display your data in datagrid? I want my data to display from left to right dynamically in a single row.Anonymous
September 11, 2009
Hello, The grid is awesome, but there are definately times when you want to dynamically build the grid. Also ...DataSet/DataTable? The serialization can happen, you just need to find a way to put the string indexers on the DataRow after serialization. Just replace the underlying ListDictionary<oibject> with a Dictionary<string, object>. Actually, don't sweat the serialization, just put the Data Objects in the Silverlight side and support them in the grid.Anonymous
December 09, 2009
Excellent Grid Example for silver Light.Anonymous
March 31, 2010
Thanks mate. It's really useful post for beginners. Cheers.Anonymous
April 12, 2010
This series of articles is truely great! Solved a number of problems for me to do with a silverlight control I am building. Many Many thanks!Anonymous
May 12, 2010
thank u for ur great n simple tutorial...:)Anonymous
September 14, 2010
IMO, data virtualization is a must have for the grid. I don't care whether it performs nicely with millions of rows. For one thing, I don't want to keep them in memory, and - more importantly - I don't want to fetch them from my server at once. This is quite a show stopper for us I'm afraid.Anonymous
September 29, 2010
thanks, this very helpfull for me,,Anonymous
October 31, 2010
Useless information. I need to know how to enable scroll bars in a Siverlight datagrid. It's simply nowhere to be found in Microsoft's documentation. I would think that something that baisic would be well documented, heck it should be automatic but it's not. Thanks for wasting a full day and starting another one...Anonymous
February 07, 2011
Scott -- Please help. That is a nice article. Can you please explain a bit more? If one sets AutoGenerateColumns=false then how can one add columns programmatically to a Silverlight DataGrid? Please advise. Thank you. -- Mark KamoskiAnonymous
February 08, 2011
Hi Mac, To enable scrollbars, make sure that your DataGrid is either in a control that constrains its height (like a Grid) or explicitly set a height. Mark, Looks like you already found the article, but for others who are interested: blogs.msdn.com/.../defining-columns-for-a-silverlight-datagrid.aspx Hope this helps! -ScottAnonymous
March 27, 2013
Hi, And if I don't know the exact number of columns at design time? how do I fullfill the datagrid dynamically without a class? Regards
- Ezequias