Бележки на Telerik
With our upcoming service pack (Q3 2009 SP2) you will be able to populate distinct values asynchronously using the DistinctValuesLoading event. To achieve this you can assign any INotifyCollectionChanged collection for distinct values ItemsSource and RadGridView will update the UI immediately on any change.
I’ve made small demo on how to achieve this using WCF RIA Services and RadGridView bound to DomainDataSource with DataPager – in this case the grid distinct values are populated from the entire collection server-side not only from the current downloaded page:
server-side:
public List<DistinctValue> GetDistinctValues(string propertyName) { var list = new List<DistinctValue>(); var values = this.DataContext.Customers.Select(propertyName).OfTy pe<string>().Distinct().To List(); for (var i = 0; i < values.Count; i++) { list.Add(new DistinctValue() { ID = i, Value = values[i] }); } return list; }
...
public class DistinctValue { [Key] public int ID { get; set; } public string Value { get; set; } } ...
client-side:
private void RadGridView1_DistinctValuesLoading(object sender, Telerik.Windows.Controls.G ridView.GridViewDistinctVa luesLoadingEventArgs e) { var collection = new RadObservableCollection<st ring>(); e.ItemsSource = collection; var context = (NorthwindDomainContext)Do mainDataSource1.DomainCont ext; context.DistinctValues.Cle ar(); context.Load(context.GetDi stinctValuesQuery(e.Column .UniqueName)).Completed += (s, args) => { collection.AddRange(contex t.DistinctValues.OfType<Di stinctValue>().Select(dv => dv.Value)); }; }
As people become more aware of the fantastic things you can do with Silverlight, they’ve also realized one of the downsides of this can be increased XAP size. The default way that Silverlight handles a XAP is to include all the required assemblies into that single compressed file. This isn’t that bad when you’re working with a barebones Silverlight project, but once you start adding in different controls or 3rd party assemblies you are increasing your XAP size quite a bit in some cases. And as we all know, a larger XAP leads to longer load times, and although people have been dealing with long load times on desktop programs for a while now (Hello, Visual Studio!), the average end user does not want to see this in Rich Internet Applications (RIAs).
The answer to this came in Silverlight 3 in the form of Application Library Caching (or as I’ll refer to it, assembly caching). This is explained in pretty extensive detail by both the MSDN documentation as well as this post by Tim Heuer, but the gist of it is that you can move your assemblies outside of your XAP and just have them referenced by the application. Once you’ve downloaded the assemblies once, they are present on your machine and you won’t have to re-download them in another XAP.
To make this a little more visible, let’s look at my super test application in all its glory:
In this, I’m making use of a handful of Telerik assemblies along with a few other more generic Silverlight ones. I’ve also added another project to my solution, including the exact same assemblies, so here is a look at my solution explorer as well as ClientBin of the web application so you can see the size of the XAP files:
If you can’t see that too well, the sizes for each SL app are 1989KB and 2252KB respectively- but wait, aren’t they sharing a lot of assemblies inside of those XAP files?
Indeed they are- which is where assembly caching comes in. For starters, we click the magic checkbox in Visual Studio:
The “magic” here is that we’ve done the work for you and included the corresponding .extmap files for every Telerik Silverlight assembly, meaning that once you click that checkbox, you now have all the behind the scenes plumbing taken care of and you get an end result which looks something like this:
I know what you might be thinking- my ClientBin folder exploded with all this extra stuff! The extra stuff is actually all of the assemblies that were previously packed into the XAP files, leaving our actual XAP file sizes at 91KB and 92KB (for you math geeks, the XAPs are now around 4% of their previous size). Everything else is outside of the XAP files now and downloaded apart from the XAP.
Now what are some advantages of this? This solution shows one of the best examples I can think of… Say you are using Silverlight to create different islands of functionality in your app (like a stylin’ RadChart, for example), you don’t really want each XAP file to take a while to load up on the page. With assembly caching, once you load the first XAP that includes those assemblies all of the compressed versions will be downloaded to the client machine. Then when each additional XAP file will be able to load those cached assemblies instead of re-downloading them in each XAP file you have.
To put the numbers together, say you go to the TelerikAssemblyCachingTest
So in summary, use caching when available, you’ll save yourself download time and your users will thank you. And courtesy of the team here at Telerik, adding cached Telerik assemblies is as easy as clicking a checkbox in your project properties.
Auto Generating Hierarchy
Setting up an auto generating hierarchy is probably the easiest route you can take when working with hierarchies and the RadGridView. The only downside to automatically generating the hierarchy is that you must use DataSets. To show you how this works, I've created a small demo application that uses a music collection access database. In my project, I've created a DataSet based on this database and its three tables called MusicCollectionDataSet. The relationships defined in this DataSet are what the RadGridView is going to use to automatically generate the hierarchy.
Figure 1. The MusicCollectionDataSet
As you can see in Figure 1, the relationships that the hierarchy grid will be based on are the AlbumsSongs and ArtistsAlbums relationships. Setting up the hierarchy to automatically generate is quite simple. You need an instance of the MusicCollectionDataSet and instances of its various table adapters that have been filled with data from the database. After this, all you need to do is set the AutoGenerateHierarchy property of the RadGridView to true, specify the DataSource as the MusicCollectionDataSet, and specify the DataMember as the top leveltable to display in the hierarchy. In this case, the top leveltable is the "Artists" table.
radGridView1.AutoGenerateH ierarchy = true; radGridView1.DataSource = this.musicCollectionDataSet; radGridView1.DataMember = "Artists";Running the application yields a hierarchy, three levels deep, that has been automatically generated.
Figure 2. The Auto Generated Hierarchy Application
Click hereto download the source code for this example.
Manually Creating the Hierarchy
Using this technique takes a little more work than using auto generation, but the advantage here is that you are not restricted to using DataSets. You can also more easily modify the layouts of the various ChildGridViewTemplates using the Visual Studio designer.
For this example, I've actually used the same exact database as in the first example, the MusicCollection database. I've once again created a DataSet based on this database (exactly like Figure 1 above). The major difference here is that I am not going to use the relationships contained within the DataSet to generate the hierarchy. I am going to instead use specific ID fields from the tables to define the relationships manually. Due to this, you actually don't have touse a DataSet to manually create a hierarchy, you simply need a set of classes that has a known relationship based on a particular ID/Key field.
In the Visual Studio designer, I have created several binding sources specific to each table contained within the MusicCollectionDataSet. They are, albumsBindingSource, artistsBindingSource, and songsBindingSource. Using the SmartTag on the RadGridView, I've set its DataSource to be the top level BindingSource, artistsBindingSource.
Figure 3. The Binding Sources
In the properties window of the designer for the RadGridView under MasterGridViewTemplate -> ChildGridViewTemplates I've added a new template with the albumsBindingSource set as its DataSource.
Figure 4. The Albums GridViewTemplate
This GridViewTemplate (gridViewTemplate1) also has a property for adding ChildGridViewTemplates. Since our hierarchy should expand to a third level past albums to display songs, we need to add a child GridViewTemplate here as well. This ChildGridViewTemplate's DataSource needs to be songsBindingSource.
Figure 5. The Songs GridViewTemplate
Back in the designer, the RadGridView also contains a property called Relations. This is where we need to define the relationships between all of the datasources. For the relationship between artists and albums, I've specified the following:
ChildColumnName: ArtistID
ChildTemplate: gridViewTemplate1
ParentColumnName: ArtistID
ParentTemplate: radGridView.MasterGridView
RelationName: ArtistsAlbums
I've also created a relationship between the albums and songs tables:
ChildColumnName: AlbumID
ChildTemplate: gridViewTemplate2
ParentColumnName: AlbumID
ParentTemplate: gridViewTemplate1
RelationName: AlbumsSongs
Running the application yields a hierarchy, three levels deep, that functions in exactly the same way as the auto-generated hierarchy from the first example.
Figure 6. The Manual Hierarchy Application
Click hereto download the source code for this example.
Hierarchy of Multiple One-to-Many Relations
The RadGridView also supports hierarchies that contain objects with multiple one-to-many relations. When it encounters this scenario it displays each ChildGridViewTemplate in its own separate tab. Setting up this type of hierarchy is very simple. For this example, I am using the following DataSet based on a Contacts database.
Figure 7. The Contacts DataSet
The Contacts table contains two separate one-to-many relationships. Getting theinformation from these tables to display in the hierarchy follows a very similar technique to what we did in example 2. In the Visual Studio properties window for the RadGridView under MasterGridViewTemplate -> ChildGridViewTemplates, I simply added two new GridViewTemplates. The first uses the emailAddressesBinding source as its DataSource. The seconds uses the phoneNumbersBindingSource as its DataSource. Having two ChildGridViewTemplates in this collection ensures that they will show up as tabbed child views under their parent GridViewTemplate.
The relationships are also defined in a similar way.
ContactsEmailAddresses Relationship:
ChildColumnName: ContactID
ChildTemplate: gridViewTemplate3
ParentColumnName: ContactID
ParentTemplate: radGridView.MasterGridView
RelationName: ContactsEmailAddresses
ContactsPhoneNumbers Relationship:
ChildColumnName: ContactID
ChildTemplate: gridViewTemplate2
ParentColumnName: ContactID
ParentTemplate: radGridView.MasterGridView
RelationName: ContactsEmailAddresses
Running the application yields a GridView containing contacts that can be expanded to show email addresses and phone numbers associated with a particular contact in tabbed child views.
Figure 8. The Tabbed Child Views Application
Click hereto download the source code for this example.
The feedback about our new version of CoverFlow for Silverlight has been great! Thank you guys for pointing out all these small issues and problems that had to be polished since we introduced a new beta CoverFlow for Silverlight 3 back in September. After the core functionality of the control is successfully integrated in our Silverlight 3 suite, we are now able to start developing new features that every grown-up CoverFlow control should possess :)
Vertical Orientation
Both in our forum and support system we have received numerous requests for vertical orientation of the CoverFlow control. That is why, with our 2009 Q3 SP2 release that is around the corner, CoverFlow will possess Orientation property that gives you an option for vertically arranging all CoverFlow items. However, the reflection functionality is not available while using vertical orientation, and is internally switched off when using Vertical orientation. All other properties concerning the child items that are orientation dependent such as OffsetX, OffsetY, RotationY and CameraViewPoint are rendered as if the control is horizontally oriented. This will change in future and will require some minor changes to the naming convention, but for now in order to prevent any breaking changes or ambiguities these properties won’t be renamed.
Reflection Properties
Another feature that we lacked in our CoverFlow API is capability to manipulate the reflection. Since Silverlight 3 introduced the power of shader effects, we have extensively leveraged on it to improve the presentation and performance of RadControls for Silverlight. With the upcoming release CoverFlow will also possess two new properties for tweaking up your reflection appearance. ReflectionHeight and ReflectionOpacity will be part of the CoverFlow API, and will internally tune a shader effect that is developed on High Level Shader Language (HLSL) that simulates the reflection. ReflectionHeight is a relative height of the reflection that accepts values in the range of 0 to 1. ReflectionOpacity defines the opacity of the reflection constrained by the ReflectionHeight and has a range of 0 to 1 as well.
There are many more cool features in our roadmap for the upcoming 2010 that will bring to us Silverlight 4 and Visual Studio 2010! The Silverlight team is eager to further enrich your most complete toolset that boosts your presentation and performance.
This is my last blog for the year, so I would like to congratulate all of you who have been using our products and wish you a happy and successful new year!
Sometimes when using a Docking control and implementing complex UI with it we need to add some custom rules about allowing some panes to be docked in some parts of the application and to disallow them to dock to other parts. As this behavior is quite complex itself, we’ve decided to enable some scenarios to be available in XAML in a declarative way (the more static scenarios) and some scenarios to be available only through the code-behind.
In this post I will guide you through some simple steps that will show you how you could use both approaches. First of all I will explain you some of the properties of the Compass class that will allow to control its options. After that I will show how to statically set the enabled compass directions. At the end I will show you how to implement some complex logic for enabling and disabling compass directions.
Compass directions
Both the Compass and RootCompass controls have some dependency properties that allow you to customize their docking directions. The RootCompass inherits from the Compass class, so it contains all the properties defined for the Compass class. Both classes have the following properties:
- IsLeftIndicatorVisible
- IsTopIndicatorVisible
- IsRightIndicatorVisible
- IsBottomIndicatorVisible
- IsCenterIndicatorVisible
These properties by default are controlling the visibility of the Compass and RootCompass parts. On Figure 1.1 and 1.2 you can see the parts of the Compass and the RootCompass controls.
Figure 1.1 Parts of the Compass Control
Figure 1.2 Parts of the RootCompass Control
In the RootCompass class the IsCenterIndicatorVisible property is not in use, because the RootCompass doesn’t have a center indicator. Figure 2.1 and 2.2 shows how each property affects both of the compasses:
Figure 2.1 Compass indicator visibility properties
Figure 2.2 RootCompass indicator visibility properties
Using compass indicators properties globally with Styles
One common scenario is to say that the user is not allowed to dock at one side of the Docking control (for example at the right one). Another common scenario is that our application doesn’t allow the user to have more than one pane in a group. Both of these scenarios are pretty static and we could achieve them using the previously mentioned configuration properties of the Compass and RootCompass controls without writing any code-behind. To achieve the first scenario we need to say to the RootCompass that its right indicator is always invisible. You could do that using the RootCompassStyle property of the Docking control. Listing 1.1 shows how we could use this property.
<telerikDocking:RadDocking. CompassStyle> <Style TargetType="dock:Compass"> <Setter Property="IsCenterIndicatorVisible" Value="false" /> </Style> </telerikDocking:RadDocking. CompassStyle> <telerikDocking:RadDocking. RootCompassStyle> <Style TargetType="dock:RootCompass"> <Setter Property="IsTopIndicatorVisible" Value="false" /> </Style> </telerikDocking:RadDocking. RootCompassStyle> Listing 1.1: Configure RootCompass using the RootCompassStyle property of the Docking control
Using compass indicators properties in code behind
When is needed for a group of the same type panes, or even for each pane, to be granted different permissions for docking, the code-behind is used for achieving this more complex scenario.
First, you must hook on the PreviewShowCompass event of the Docking control in the XAML and implement your logic in the event-handler in the code-behind. To divide the logic for the RootCompass and the other Compass you should use the TargetGroup property of the e argument. If its TargetGroup property is null, this means that the event is fired for the RootCompass, if not – for the other Compass. It is good to keep in mind that the programming overrides the styles in XAML, so if you are using both approaches the explicit settings of the properties are “stronger”.
So let’s create an example that will utilize the features we already mentioned.
First, we need to create a method called GetPaneType, which returns the type of the panes. This is achieved by comparing the resources of the panes, more specificly the color of the brush of the pane’s background, using simple if statements. We will need the type of the panes, so that we can decide which Compass indicators to show and which to hide depending on these types. Here is the code:
private PaneType GetPaneType(RadPane pane) { Panel c = pane.Content as Panel; if (c != null) { if (c.Background.Equals(this.Resources["OliveBrush"])) { return PaneType.Olive; } else if (c.Background.Equals(this.Resources["BlueBrush"])) { return PaneType.Blue; } else { return PaneType.Purple; } } return PaneType.Purple; }
Then, we will define a method called CanDockIn. The return type of this method is Boolean and its parameters are:
- paneToDock of type RadPane - the pane that will be docked in;
- paneInTargetGroup also of type RadPane - the pane that is targeted at the moment;
- position of type DockPosition, which is the direction the indicators point.
The return value will indicate whether the first pane (paneToDock) can be docked next to the second one(paneInTargetGroup). The third parameter indicates where we want to dock the first pane relatively to second one - to its left, right, top or bottom side or in the same group. We will use this value to set the visibility of the indicators of the Compass for each pane in the event PreviewShowCompass. For that we make 2 variables paneInTargetGroupType, of type PaneType, which is the pane that is the targeted one (the one that we are holding and moving at the moment), and paneToDockType, also of type PaneType, which is the one in which we are eventually going to dock. To the variable paneToDockType is assigned the value of GetPaneType(paneToDock) - this is the method that we have initially created with the first argument of the method CanDockIn. To the paneInTargetGroupType is assigned the GetPaneType(paneInTargetGr
After getting the type of the panes via the method GetPaneType, using switch statements we set the value (true or false) for each type of pane (in the example olive, purple and blue). The value of the outer switch expression, which is shown below, is the paneToDockType. If we take for example this code snippet:
case PaneType.Olive: switch (paneInTargetGroupType) { case PaneType.Olive: return true; case PaneType.Blue: return position != DockPosition.Left && position != DockPosition.Right; case PaneType.Purple: return false; } break; This code shows that one olive pane:
- can be docked in another olive pane
- in the blue pane, the left and right indicators are disabled
- in the purple the olive pane can’t be docked at all
In a similar way is defined the visibility of the indicators for the other remaining pane groups.
Similar logic is used for defining the visibility of the indicators of the RootCompass in the method CanDock. Again switch statements are used to define for each pane which indicators of the RootCompass are enabled.
switch (paneToDockType) { case PaneType.Olive: return position != DockPosition.Left; case PaneType.Blue: return false; case PaneType.Purple: return true; } return false;
Here we can see that for the olive pane the docking to the left is disabled, for the blue pane all 4 indicators in the RootCompass are disabled and for the purple pane all indicators are visible.
We are now able to set the visibility of all indicators of the two Compasses for every pane in the PreviewShowCompass event.
The values for the previously mentioned properties IsLeftIndicatorVisible, IsTopIndicatorVisible, IsRightIndicatorVisible, IsBottomIndicatorVisible, IsCenterIndicatorVisible are determined with the help of the methods CanDockIn and CanDock, which we have created.
private void RadDocking_PreviewShowComp ass(object sender, Telerik.Windows.Controls.D ocking.PreviewShowCompassE ventArgs e) { if (e.TargetGroup != null) { e.Compass.IsCenterIndicato rVisible = CanDockIn(e.DraggedSplitCo ntainer, e.TargetGroup, DockPosition.Center); e.Compass.IsLeftIndicatorV isible = CanDockIn(e.DraggedSplitCo ntainer, e.TargetGroup, DockPosition.Left); e.Compass.IsTopIndicatorVi sible = CanDockIn(e.DraggedSplitCo ntainer, e.TargetGroup, DockPosition.Top); e.Compass.IsRightIndicator Visible = CanDockIn(e.DraggedSplitCo ntainer, e.TargetGroup, DockPosition.Right); e.Compass.IsBottomIndicato rVisible = CanDockIn(e.DraggedSplitCo ntainer, e.TargetGroup, DockPosition.Bottom); } else { e.Compass.IsLeftIndicatorV isible = CanDock(e.DraggedSplitCont ainer, DockPosition.Left); e.Compass.IsTopIndicatorVi sible = CanDock(e.DraggedSplitCont ainer, DockPosition.Top); e.Compass.IsRightIndicator Visible = CanDock(e.DraggedSplitCont ainer, DockPosition.Right); e.Compass.IsBottomIndicato rVisible = CanDock(e.DraggedSplitCont ainer, DockPosition.Bottom); } e.Canceled = !(CompassNeedsToShow(e.Com pass)); }
As we can see in the Boolean value, which is returned by the methods CanDock and CanDockIn, is set to the corresponding properties IsCenterIndicatorVisible, IsLeftIndicatorVisible, IsTopIndicatorVisible, IsRightIndicatorVisible, IsBottomIndicatorVisible, which make the indicator visible or invisible.
The property Canceled of the e argument, if set to true, disables the whole Compass. The line
e.Canceled = !(CompassNeedsToShow(e.Com pass));refers to another method, called CompassNeedsToShow, which checks if all indicators are disabled, if so, disables the whole Compass, like so:
private static bool CompassNeedsToShow(Telerik .Windows.Controls.Docking. Compass compass) { return compass.IsLeftIndicatorVis ible || compass.IsTopIndicatorVisi ble || compass.IsRightIndicatorVi sible || compass.IsBottomIndicatorV isible || compass.IsCenterIndicatorV isible; }
Here you can find an example which illustrates the described implementation of the RadDocking Control. For more information please refer to Telerik’s online demos for Silverlight, the demos for WPF and help documentation for WPF and help documentation for Silverlight.
Using FixedDocument, DocumentViewer and PrintDialog you can easily create your own print and/or print preview for RadGridView for WPF.
I’ve made two extension methods Print() and PrintPreview() to illustrate how to turn the grid into a print friendly document in few lines of code:
…
public static void PrintPreview(this GridViewDataControl source) { var window = new Window() { Title = "Print Preview", Content = new DocumentViewer() { Document = ToFixedDocument(ToPrintFriendlyGrid(source), new PrintDialog()) } }; window.ShowDialog(); } public static void Print(this GridViewDataControl source, bool showDialog) { var dialog = new PrintDialog(); var dialogResult = showDialog ? dialog.ShowDialog() : true; if (dialogResult == true) { var viewer = new DocumentViewer(); viewer.Document = ToFixedDocument(ToPrintFri endlyGrid(source), dialog); dialog.PrintDocument(viewe r.Document.DocumentPaginat or, ""); } }
…
One of the less known features supported by Telerik’s RadChart for Silverlight/WPF is the ability to completely abandon the default control layout and build one of your own with no constraints for the number of elements used. The goal of this blog post is to shed some light on this functionality and to demonstrate the most common techniques that can be used to customize the legend.
First of all, to build your own custom chart layout you should set the UseDefaultLayout property of the RadChart object to false. Here is the custom layout I prepared:
<telerik:RadChart x:Name="
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="5
<ColumnDefinition Width="*
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"/
<RowDefinition Height="50"
</Grid.RowDefinitions>
<telerikCharting:ChartArea
<telerikCharting:ChartArea
<telerikCharting:DataSerie
</telerikCharting:DataSeri
<telerikCharting:DataSerie
</telerikCharting:DataSeri
</telerikCharting:ChartAre
</telerikCharting:ChartAre
<Canvas Grid.Column="1" >
<telerikCharting:ChartLege
</Canvas>
<Slider x:Name="Horizontal
<Slider x:Name="VerticalSl
</Grid>
</telerik:RadChart>
The code above declares a RadChart control with custom grid layout containing a ChartArea populated with two data series and a ChartLegend. There are also two sliders used to precisely position the legend. Following is the result:
By default the ChartLegend uses a vertical StackPanel to arrange its children, Being an ItemsControl, it is extremely easy to replace the Items panel of the legend with any panel fitting your needs. Here I have changed the default items panel with a horizontal one:
<Grid.Resources><ItemsPanelTemplate x:Name
<StackPanel Orientation="H
</ItemsPanelTemplate>
</Grid.Resources>
...
<telerikCharting:ChartLeg
And the result is:
There are much more scenarios when you could need to have more control over the visual appearance of the chart legend. For example, one could want to add a ScrollViewer control in order to be able to show large number of chart legend items in a limited space. Here is a legend style which you can use to do this:
<Style x:Name="legendStyl<Setter Property="Template
<Setter.Value>
<ControlTemplate TargetTyp
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
These are some of the most frequently requested customizations that can be applied to the chart legend and the chart control itself. We will be glad to hear your comments and recommendations about the ways we can go to make our product more friendly and easy to use.
Velin.
When you don't blog regularly, one of the biggest challenges is to find a good topic.With Twitter around, it becomes even more complicated for the people that are not regular bloggers.While I was waitingfor something interesting to pop-up as a topic, 2009 almost passed and it gave me the needed opportunity.It feels as if I blinked and it's Christmas Season again.
Before I move on with my overview, on behalf of everyone at Telerik, I would like to wish you and your families a better 2010 – stay healthy, happy and lucky. Thank you for being a part of the Telerik community and for bearing with us in good times and in bad
2009 was not an easy year – all of us, in differing severity, felt the hit of the economic slowdown that affected most of the world. It was the first time we as a business had to take into consideration macro factors and not just the things that are typically within our control. Yet, it was also an amazing time – in terms of new experiences and results achieved. Luckily, with the efforts of all the talented people at Telerik and with your incredible support, we overcame all challenges and emerged stronger – with more and better products and ready to “deliver more than expected” in 2010 and beyond.
Even though this year had a lot of economic uncertainty all around, we still accomplished almost everything on our roadmap plus a few extra things:
- Introduced the Telerik ASP.NET MVC Extensions. Contrary to popular belief, the MVC extensions were not a port of our ASP.NET AJAX products but a new development started from the ground up. It was also the first time we released a Telerik product under an open source license (using GPL 2.0).
- Telerik significantly extended theSilverlight andWPF product lines. Today, we have an amazing set of controls with which you can create pretty much any type of application. After the initial rush to provide features, we spent a lot of time to also deliver unmatched performance. It was a big engineering challenge but a good investment. I won’t go into controversy who’s grid is the fastest – you can test everything on the market and see which product performs fastest in your case.
- We were the first to provide support for Microsoft Silverlight 4.0. It shows how committed we are to closely following Microsoft releases and allowing you to leverage the latest and greatest products coming from Microsoft and not lose the productivity you get from our tools.
- We brought to market the firstSilverlight reporting engine by virtue of extending Telerik Reporting capabilities.
- Our mature product lines,RadControls for ASP.NET AJAX and WinForms, got many new controls and performance improvements, as well as much better looking skins. We also spent several months to ensure that all controls are much more easily styled and to provide tools for customers to make customizations to the skins visually – that’s how theVisual Style Builder was born. And we are in the final stages of revamping the WinForms Visual Style Builder.
- OpenAccess got many improvements and is getting closer to our vision for the product. In 2009 we focused on providing really broad LINQ support and the close to 200 tests (101 LINQ examples is just a small subset) is a true testament that we have one of the most feature-rich and LINQ capable solutions on the market.
- At PDC 2009 we released our first Visual Studio productivity plug-in “JustCode”. While JustCode is not as feature complete as the tools of our competitors, it shows our commitment to this space and it does deliver quite a few unique features such as solution-wide code analysis, JavaScript refactoring, and many others. Oh, and it’s much much lighter on your machine’s memory.
- This year we also shipped the Work Item Manager and Dashboard. Developed in partnership with Imaginet, these tools were intended mainly for internal purposes but everyone was so excited that we finally decided to offer them as a free download to our customers. It’s a great showcase of Telerik WPF technology put to heavy-duty use. And it’s useful as it makes working with VSTS more enjoyable.
- In 2009 we also managed to enter into a strategic partnership withArtOfTest and ourWebUI Test Studio product was born. Apart from selling it, we are also using it extensivelyacross our teams for ASP.NET AJAX, MVC and Silverlight test automation (in addition to our unit testing efforts of course:)
- We delivered the first truly accessible editor for SharePoint content editing. You can take a look at the RNIB case study on YouTube. It’s a great case how technology can help for something good.
We are extremely proud of every single item but the really important questions is not how we feel about our products, but instead how you feel about them? Did we get better? Did we deliver the value that you expected? Did we add the tools you wanted to see from us? Please share your feedback below and help us serve you better in the year to come.
Vassil Terziev
Co-founder/CEO
With the release of RadControls for ASP.NET Ajax Q3 2009 SP1 we introduced built-in CDN support. It was very logical that Telerik Extensions for ASP.NET MVC receive some CDN love as well. Now this is a fact! Go download the current release from here (open source) or here (licensed).
Enabling global CDN support from web.config
Add the following XML in your web.config:
<configSections>
<sectionGroup name="telerik">
<section name="webAssets" type="Telerik.Web.Mvc.Configuration.WebAssetConfigur ationSection, Telerik.Web.Mvc"/>
</sectionGroup>
</configSections>
<telerik>
<webAssets useTelerikContentDeliveryNetwork="true" />
</telerik>
Enable CDN support from code
Html.Telerik().ScriptRegistrar()
.DefaultGroup(group => group.UseTelerikContentDeliveryNetwork(true))
Questions and Answers
- Which files are served from the Telerik CDN?
Only telerik “native files” get served from the CDN – JavaScript, CSS and images. - Where is Telerik CDN hosted?
Amazon CloudFront - What is the URL that will be output?
- JavaScript: http://aspnet-scripts.tele
rikstatic.com/mvc|mvcz/assemblyVersion (mvc or mvcz depends whether the browser supports GZIP content encoding) - CSS and image files: http://aspnet-skins.teleri
kstatic.com/mvc|mvcz/assemblyVersion (mvc or mvcz depends whether the browser supports GZIP content encoding)
- JavaScript: http://aspnet-scripts.tele
- What about SSL support?
SSL is automatically detected and then the following will be output:- CSS and image files: https://telerik-aspnet-ski
ns.s3.amazonaws.com/mvc|mvcz/assemblyVersion - JavaScript files: https://telerik-aspnet-scr
ipts.s3.amazonaws.com/mvc|mvcz/assemblyVersion
- CSS and image files: https://telerik-aspnet-ski
Is there anything else in this release
Actually yes. We have implemented RTL support for the tabstrip, panelbar and menu.
The Astoria (aka ADO.NET Data Services) team released an updated .NET 3.5 SP1 version of Astoria last night. This version of Astoria is an inplace update and will overwrite your current version of Astoria (System.Data.Services.*.dl
- Windows 7 and Windows 2008 R2 http://www.microsoft.com/d
ownloads/details.aspx?fami lyid=4B710B89-8576-46CF-A4 BF-331A9306D555&displaylan g=en
- All Previous version of Windows http://www.microsoft.com/d
ownloads/details.aspx?fami lyid=79d7f6f8-d6e9-4b8c-86 40-17f89452148e&displaylan g=en
The new version of Astoria has some very useful and powerful features. They include projections, data binding, row count, feed customization, server based paging and better BLOB support. There is one small issue, in order to support these new features you have to tell the framework you are using the new version of Astoria. For backward compatibility reasons, by default Astoria will work in “1.0” mode and none of the new features will work out of the box. To take advantage of the 2.0 features, you have to make two minor changes to the InitializeService method:
1: //change the IDataServiceConfiguration to DataServiceConfiguration
2: public static void InitializeService(DataServiceConfiguration config)
3: { 4: config.SetEntitySetAccessRule("*", EntitySetRights.All);
5: //take advantage of the "2.0" features
6: config.DataServiceBehavior.MaxProtocolVersion =
7: System.Data.Services.Common.DataServiceProtocolVersi on.V2;
8: }
.csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }
The first thing that you need to change is on line 2, change the interface IDataServiceConfiguration to be just DataServiceConfiguration (I am sure that there is a better way to do this, I have not figured it out yet.). Next, set the MaxProtocolVersion property of DataServiceBehavior to V2. After that you can take advantage of all the new features!
I want to take advantage of my favorite new feature, the inline row count. (I have been asking over and over for this feature, so: Thanks Astoria team!!!) The inline row count will return the number rows in the data feed regardless of paging ($skip, $top etc) as an XML element: <m:count>. This new property makes our RAD Grid and other paging aware controls much easier to perform paging. To make this work, you just add the inlinecount to the querystring:
servicename/entityname?$inlinecount=allpages
.csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }
Let’s implement this with the example I did the other day using Telerik OpenAccess and the Data Service Wizard. If you remembered I built a simple Astoria 1.0 service exposing the Customers entity. We built this using “Astoria 1.0”, however, I upgraded my machine with the release of Astoria 2.0. When I use inlinecount, I get a 404 error. As with a brand new service, we have to tell the framework what version of Astoria we want to use before we can take advantage of inlinecount. I made the same changes as I did above (DataServiceConfiguration and MaxProtocolVersion ) and reran my application. Now when I type this URL: http://localhost:1191/WebD
I get only the top two records but the total count of records.
Awesome.
Enjoy Astoria 2.0!
PS:
I thought that this was called “WCF Data Services”? According to the Astoria team blog:
Since this release is an update to the .NET Framework 3.5 SP1 we kept the name consistent with what was used in the 3.5 SP1 timeframe so that printed documentation, etc is consistent. Going forward in .NET 4 and onwards you’ll see us use WCF Data Services.
Technorati Tags: Astoria

