Creating a simple Pivot table using LINQ and Telerik RadTreeView for Silverlight
2011-06-20 15:51
806 查看
This article is compatible with the latest version of Silverlight.
What is a Pivot table/grid? According to Wikipedia it is a data summarization tool found in spreadsheet applications. Still when I was a child I learned that people understand the best when they see an example.
Consider you have a table that contains the nutrition of given food, say a pizza:
In the data above you see that every nutrition is contained in a specific Group - 3 groups and 21 nutrition in total. To display the nutrition in a more meaningful way in most cases you need to group the nutrition (rows in the general case) by their Group attribute and display them in columns instead of in rows. Now we are closer to what we call a Pivot table - group and turn rows into columns.
So the above table displayed in a Pivot would look like that:
I searched for a 3rd party control that can help me achieve this goal out of the box, but I couldn't find one. Looking for a way to do it I finally made it work with the help of LINQ - for grouping and the Telerik RadTreeView for Silverlight - for displaying.
Create a business object Nutrition that will be used later when loading the XML with LINQ.
and NutritionGroup:
Now, it's time to load the XML document with LINQ. Martin Mihaylov published a great article on using LINQ to XML in Silverlight so if you are not familiar you'd better go read it first.
[/code]
We need to group by the Group attribute.
Now, each nutrition group should be a root node in the tree and each nutrition in this group should be added to the nutritions in the corresponding root. When the ItemSource property is set to the collection of nutrition groups, the RadTreeView will be populated with the corresponding data:
Ok, we are almost over. Let's take a look at the NutritionGroupTemplate and NutritionTemplate that we will use. First, we will need the following schema:
Having that, follows both the templates:
NutritionGroupTemplate
NutritionTemplate
The default orientation of the nodes in the RadTreeView, as expected, is vertical. However in our case it makes more sense to arrange the root nodes on the horizontal and only the child elements to the vertical:
And the RadTreeView element:
http://www.silverlightshow.net/items/Creating-a-simple-Pivot-table-using-LINQ-and-RadTreeView-for-Silverlight.aspx
文章转载from:
What is a Pivot table/grid? According to Wikipedia it is a data summarization tool found in spreadsheet applications. Still when I was a child I learned that people understand the best when they see an example.
Consider you have a table that contains the nutrition of given food, say a pizza:
Group | Name | Quantity |
Carbohydrates | Total carbohydrates | 27.3 |
Carbohydrates | Total disaccharides | 5.7 |
Carbohydrates | Total polysaccharides | 21.6 |
Minerals | Calcium | 147 |
Minerals | Phosphorus | 150 |
Minerals | Potassium | 201 |
Minerals | Copper | 0.13 |
Minerals | Magnesium | 19 |
Minerals | Sodium | 582 |
Minerals | Selenium | 4 |
Minerals | Total iron | 0.7 |
Minerals | Zinc | 1.07 |
Vitamins | Beta-carotene | 173.8 |
Vitamins | Nicotinic | 1.5 |
Vitamins | Total vitamin B6 | 0.127 |
Vitamins | Total vitamin D | 0.3 |
Vitamins | Total vitamin E | 2.1 |
Vitamins | Vitamin B1 | 0.1 |
Vitamins | Vitamin B12 | 0.59 |
Vitamins | Vitamin B2 | 0.16 |
Vitamins | Vitamin C | 10 |
So the above table displayed in a Pivot would look like that:
Carbohydrates | Minerals | Vitamins | |||
Total carbohydrates | 27.3 | Calcium | 147 | Beta-carotene | 173.8 |
Total disaccharides | 5.7 | Phosphorus | 150 | Nicotinic | 1.5 |
Total polysaccharides | 21.6 | Potassium | 201 | Total vitamin B6 | 0.127 |
Copper | 0.13 | Total vitamin D | 0.3 | ||
Magnesium | 19 | Total vitamin E | 2.1 | ||
Sodium | 582 | Vitamin B1 | 0.1 | ||
Selenium | 4 | Vitamin B12 | 0.59 | ||
Total iron | 0.7 | Vitamin B2 | 0.16 | ||
Zinc | 1.07 | Vitamin C | 10 |
Loading the data with LINQ
First, consider we have the initial table of nutrition exported to XML. The output look like that:<?
xml
version
=
"1.0"
encoding
=
"utf-8"
?>
<
Nutritions
>
<
Nutrition
Group
=
"Carbohydrates"
Name
=
"Total carbohydrates"
Quantity
=
"27.3"
></
Nutrition
>
<
Nutrition
Group
=
"Carbohydrates"
Name
=
"Total disaccharides"
Quantity
=
"5.7"
></
Nutrition
>
<
Nutrition
Group
=
"Carbohydrates"
Name
=
"Total polysaccharides"
Quantity
=
"21.6"
></
Nutrition
>
<
Nutrition
Group
=
"Minerals"
Name
=
"Calcium"
Quantity
=
"147"
></
Nutrition
>
<
Nutrition
Group
=
"Minerals"
Name
=
"Phosphorus "
Quantity
=
"150"
></
Nutrition
>
Create a business object Nutrition that will be used later when loading the XML with LINQ.
public
class
Nutrition
{
public
string
Group{
get
;
set
;}
public
string
Name{
get
;
set
;}
public
string
Quantity{
get
;
set
;}
}
and NutritionGroup:
public
class
NutritionGroup
{
public
string
NutritionGroupHeader{
get
;
set
;}
public
Collection<Nutrition>Nutritions{
get
;
set
;}
}
Now, it's time to load the XML document with LINQ. Martin Mihaylov published a great article on using LINQ to XML in Silverlight so if you are not familiar you'd better go read it first.
List data = ( from nutrition
in
nutritionsDoc.Descendants(
"Nutrition"
)
select
new
Nutrition
{
Group = nutrition.Attribute(
"Group"
).Value,
Name = nutrition.Attribute(
"Name"
).Value,
Quantity = nutrition.Attribute(
"Quantity"
).Value
} ).ToList();
[/code]
Grouping the data with LINQ and building the tree
Ok, this is the core of this article. The ability to group is a great feature in LINQ. It really does simplify the code to minimum.We need to group by the Group attribute.
IEnumerable<string, Nutrition>>query = data.GroupBy( nutrition =>nutrition.Group );
Now, each nutrition group should be a root node in the tree and each nutrition in this group should be added to the nutritions in the corresponding root. When the ItemSource property is set to the collection of nutrition groups, the RadTreeView will be populated with the corresponding data:
Collection<NutritionGroup>nutritions =
new
Collection<NutritionGroup>();
foreach
( IGrouping<
string
, Nutrition>nutritionGroup
in
query )
{
NutritionGroup group =
new
NutritionGroup()
{
NutritionGroupHeader = nutritionGroup.Key,
};
group.Nutritions =
new
Collection<Nutrition>();
foreach
( Nutrition nutrition
in
nutritionGroup )
{
group.Nutritions.Add( nutrition );
}
nutritions.Add( group );
}
nutritionTree.ItemsSource = nutritions;
Ok, we are almost over. Let's take a look at the NutritionGroupTemplate and NutritionTemplate that we will use. First, we will need the following schema:
xmlns:telerik="http://schemas.telerik.com/2008/xaml/presentation"
Having that, follows both the templates:
NutritionGroupTemplate
<
telerik:HierarchicalDataTemplate
x:Key
=
"NutritionGroupTemplate"
ItemsSource
=
"{Binding Nutritions}"
ItemTemplate
=
"{StaticResource NutritionTemplate}"
>
<
Border
BorderThickness
=
"1"
BorderBrush
=
"#ececec"
CornerRadius
=
"4"
>
<
Border
BorderThickness
=
"1"
BorderBrush
=
"White"
Padding
=
"1"
CornerRadius
=
"4"
>
<
Border.Background
>
<
LinearGradientBrush
EndPoint
=
"0.5,1"
StartPoint
=
"0.5,0"
>
<
GradientStop
Color
=
"#f8f8f8"
/>
<
GradientStop
Color
=
"#ececec"
Offset
=
"1"
/>
</
LinearGradientBrush
>
</
Border.Background
>
<
TextBlock
Text
=
"{Binding NutritionGroupHeader}"
FontWeight
=
"Bold"
/>
</
Border
>
</
Border
>
</
telerik:HierarchicalDataTemplate
>
NutritionTemplate
<
telerik:HierarchicalDataTemplate
x:Key
=
"NutritionTemplate"
>
<
StackPanel
Orientation
=
"Horizontal"
>
<
TextBlock
Text
=
"{Binding Name}"
Width
=
"150"
></
TextBlock
>
<
TextBlock
Text
=
"{Binding Quantity}"
FontWeight
=
"Bold"
></
TextBlock
>
</
StackPanel
>
</
telerik:HierarchicalDataTemplate
>
The default orientation of the nodes in the RadTreeView, as expected, is vertical. However in our case it makes more sense to arrange the root nodes on the horizontal and only the child elements to the vertical:
<
Style
TargetType
=
"telerik:RadTreeViewItem"
x:Key
=
"TreeViewItemStyle"
>
<
Setter
Property
=
"IsExpanded"
Value
=
"True"
></
Setter
>
<
Setter
Property
=
"ItemsPanel"
>
<
Setter.Value
>
<
ItemsPanelTemplate
>
<
StackPanel
HorizontalAlignment
=
"Center"
Margin
=
"4,6"
Orientation
=
"Vertical"
/>
</
ItemsPanelTemplate
>
</
Setter.Value
>
</
Setter
>
</
Style
>
And the RadTreeView element:
<
telerik:RadTreeView
x:Name
=
"nutritionTree"
ItemTemplate
=
"{StaticResource NutritionGroupTemplate}"
ItemContainerStyle
=
"{StaticResource TreeViewItemStyle}"
>
<
telerik:RadTreeView.ItemsPanel
>
<
ItemsPanelTemplate
>
<
StackPanel
VerticalAlignment
=
"Top"
Orientation
=
"Horizontal"
/>
</
ItemsPanelTemplate
>
</
telerik:RadTreeView.ItemsPanel
>
</
telerik:RadTreeView
>
http://www.silverlightshow.net/items/Creating-a-simple-Pivot-table-using-LINQ-and-RadTreeView-for-Silverlight.aspx
文章转载from:
相关文章推荐
- 在Telerik for silverlight控件radtreeview、textBox、RadGridView中实现拖拉控件的操作
- Calling sequence for creating and configuring a table view
- Reference Pivot Fields and Pivot Items in an Excel Pivot Table, using VBA
- Creating and Using Static Libraries for iPhone using Xcode 4.3
- Silverlight:telerik RadControls for Silverlight 主题使用心得
- [Silverlight] How to make a simple PivotTable extended from Silverlight DataGrid
- silverlight:telerik RadControls for Silverlight 主题使用心得
- Table View Programming Guide for iOS---(五)---Creating and Configuring a Table View
- 14. 59. 2. 用抽象表创建一个简单table Creating simple JTable using AbstractTableModel
- Telerik RadControls for Silverlight Q3 2008可用,要是有20081117就更好了,有DATAGRID用
- Using Pythonbrew and Virtualenv(with pip) for creating sandboxed Python development environments.
- Steps for creating android applications using NDK and ARM assembly language
- A Beginner Tutorial for Writing Simple COM/ATL DLL and Using it with .NET
- ArcGIS API for Silverlight 点击地图上的要素,弹出窗口(使用Telerik RadWindow)
- Telerik RadControls for Silverlight 4
- THE DEAD-SIMPLE STEP-BY-STEP GUIDE FOR FRONT-END DEVELOPERS TO GETTING UP AND RUNNING WITH NODE.JS,
- [Esri官方声明]ArcGIS APIs / Viewers for Flex and Silverlight的产品周期
- create encode function and decode function for using
- Word representations: A simple and general method for semi-supervised learning
- Creating editable ALV using webdynpro for ABAP