Click here to Skip to main content
11,702,130 members (65,522 online)
Click here to Skip to main content

Embedding Controls in WPF DataGrid

, 24 Sep 2009 CPOL 23K 1K 9
Rate this:
Please Sign up or sign in to vote.
Sample program shows how to embed controls in a WPF DataGrid using VB.NET

Introduction

WPF ListView and DataGrid controls are very powerful but rather mysterious to program in VB.NET (VS 2010 Beta 1) without using XAML. This article shows how to embed various controls into cells of ListView and DataGrid. The sample program demonstrates how to embed TextBlock, TextBox, FlowDocument, and RichTextBox. The data source for the demonstration program is a LINQ query that obtains process information (process name, id, etc.). The grids are built using either the LINQ query either directly or indirectly via DataTables. Data binding, control factories, IValueConverter and INotifyPropertyChange are used to build the sample program. The demonstration program presents a matrix of options which are used to generate grids of various data sources and data types.

Background

While working on a project which required displaying rich text in a grid, I became very frustrated by the lack of information about the WPF DataGrid control. I wanted to build the control in code (VB.NET, no XAML). There were few examples. Hence I decided to create a mega sample program that demonstrates many combinations of LINQ queries, controls and data binding.

Using the Code 

The attached program uses three different ways to capture a LINQ query. The query uses GetProcess to obtain information about the currently running processes.

  1. Captures a query result to an anonymous type.
  2. Captures a query result as an instance of a class (ProcessInfo).
  3. Uses the above to create a collection class (ProcessInfoCollection) which uses INotifyPropertyChange to enable dynamic binding. 

The user can select any or all of the above LINQ query methods to create a binding. The binding can be used to directly feed ListView or DataGrid controls or indirectly by creating DataTables from the query and then binding the DataTables. The program allows the user to create DataTables of nine data types.

  1. Source data type. The DataTable columns inherit their type from the data source.
  2. All columns are String types.
  3. All columns are TextBlock controls. TextBlocks have some rich text ability. Since TextBlocks can't be created using FrameworkElementFactory (they lack a InlinesProperty), the program contains BindableTextBlock class to allow FrameworkElementFactory to work.
  4. All columns are BindableTextBlocks.
  5. All columns are TextBoxes. TextBox lacks rich text ability.
  6. All columns are a string representation of FlowDocument.
  7. All columns are FlowDocument controls.
  8. All columns are RichTextBox controls. Since RichTextBoxes can't be created using FrameworkElementFactory (they lack a DocumentProperty), the program contains BindableRichTextBox class to allow FrameworkElementFactory to work. 
  9. All columns are BindableRichTextBox

The user can select the data type of the columns of the ListView or DataGrid control. Essentially the same choices as above. This means that any of the above data types may have to be converted into any of the others (e.g. TextBlock into RichTextBox). All these combinations are handled by the Convert method of the IValueConverter interface.

To demonstrate how to style individual cells, the user can select text styling according to the contents of the cell (using regular expressions). For example, all process names beginning with the letter b have their process names bolded, names beginning with i are italicized, letters beginning with r have a red foreground, and processes with a u are underlined. Otherwise, all cells are given black foreground and light gray backgrounds in the FrameworkElementFactory code.

The Refresh button will cause new data to appear in the grids but only for the INotify class when fed directly into the ListView or DataGrid (not via a DataTable).

The final option allows the user to generate windows of ListViews and/or DataGrids. Be careful, it's easy to get carried away with options thus generating dozens of windows which will deplete your computer of CPU and memory.

To build the project, just create a new VS 2010 WPF Application project and paste/copy Window1.xaml.vb and Window1.xaml. There are no references to add.

Points of Interest

The key to the program's magic is the Convert method of IValueConverter interface. The method contains the goodness to convert from many types (datatypes and controls) to other types. Other challenges were dynamic binding (INotifyPropertyChange) as implemented in the ProcessInfoCollection class, column binding, and supporting the three types of LINQ results.

History

  • 24-Sept-2009: Version 0.1

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

BSalita
United States United States
No Biography provided

You may also be interested in...

Comments and Discussions

 
GeneralMy vote of 2 Pin
Dave Kreskowiak24-Sep-09 13:18
mvpDave Kreskowiak24-Sep-09 13:18 
GeneralRe: My vote of 2 Pin
BSalita25-Sep-09 3:53
memberBSalita25-Sep-09 3:53 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web04 | 2.8.150819.1 | Last Updated 24 Sep 2009
Article Copyright 2009 by BSalita
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid