RadGridView for Silverlight and WCF RIA Services Part II: Basic Editing Support

Monday, January 11, 2010 by Rossen Hristov | Comments 9

In my previous blog post I have demonstrated how to display master-details data in an asynchronous manner with RadGridView for Silverlight and WCF RIA Services. I have decided to refactor the sample project a little bit and add some very basic editing support. Here is the changes I have made to the sample project:

  1. I have recreated the ChinookService to support editing.
  2. I have encapsulated the details grid into a new user control called AlbumsControl.
  3. I have added a “Submit Changes” button below the details grid.
  4. I got rid of the IValueConverter that used to create the albums DomainDataSource and defined everything in XAML.

Here is what the new AlbumsControl looks like:

MainPage
  1. <UserControl x:Class="MasterDetailsWithRIAServices.AlbumsControl"
  2.     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  3.     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  4.     xmlns:my="clr-namespace:MasterDetailsWithRIAServices"
  5.     xmlns:riaControls="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Ria"
  6.     xmlns:riaData="clr-namespace:System.Windows.Data;assembly=System.Windows.Controls.Ria"
  7.     xmlns:services="clr-namespace:MasterDetailsWithRIAServices.Web.Services"
  8.     xmlns:telerik="clr-namespace:Telerik.Windows.Controls;assembly=Telerik.Windows.Controls.GridView"
  9.     xmlns:telerikGrid="clr-namespace:Telerik.Windows.Controls.GridView;assembly=Telerik.Windows.Controls.GridView">
  10.     <Grid Name="LayoutRoot">
  11.         
  12.         <Grid.RowDefinitions>
  13.             <RowDefinition Height="Auto"/>
  14.             <RowDefinition Height="Auto"/>
  15.             <RowDefinition Height="Auto"/>
  16.         </Grid.RowDefinitions>
  17.  
  18.         <riaControls:DomainDataSource x:Name="albumsDataSource"
  19.                                       AutoLoad="True"
  20.                                       QueryName="GetAlbumsForArtistIdQuery">
  21.             <riaControls:DomainDataSource.QueryParameters>
  22.                 <riaControls:ControlParameter ControlName="albumsGrid"
  23.                                               ParameterName="artistId"
  24.                                               PropertyName="DataContext.ArtistId"/>
  25.             </riaControls:DomainDataSource.QueryParameters>
  26.             <riaControls:DomainDataSource.DomainContext>
  27.                 <services:ChinookContext/>
  28.             </riaControls:DomainDataSource.DomainContext>
  29.         </riaControls:DomainDataSource>
  30.  
  31.         <TextBlock Grid.Row="0" Margin="2">Albums:</TextBlock>
  32.         <telerik:RadGridView
  33.                         Name="albumsGrid"
  34.                         MinHeight="100"
  35.                         MaxHeight="400"
  36.                         ItemsSource="{Binding ElementName=albumsDataSource, Path=Data}"
  37.                         IsBusy="{Binding ElementName=albumsDataSource, Path=IsBusy}"
  38.                         Grid.Row="1"
  39.                         Margin="2"
  40.                         AutoGenerateColumns="False"
  41.                         ColumnWidth="*"
  42.                         ShowGroupPanel="False">
  43.             <telerik:RadGridView.Columns>
  44.                 <telerik:GridViewDataColumn Header="Album Title"
  45.                                             DataMemberBinding="{Binding Title}"/>
  46.             </telerik:RadGridView.Columns>
  47.         </telerik:RadGridView>
  48.         <Button Name="submitButton"
  49.                 Margin="2"
  50.                 Grid.Row="2"
  51.                 Content="Submit Changes"
  52.                 Click="OnSubmitChanges"
  53.                 Width="100"
  54.                 HorizontalAlignment="Stretch"/>
  55.     </Grid>
  56. </UserControl>

 

Instead of creating the DomainDataSource in the converter like in the previous version, now the AlbumsControl hosts its own little albums DomainDataSource. Notice how the ControlParameter tells the DomainDataSource what is the artistId it should use when executing the “GetAlbumsForArtistId” query. Since the AlbumsControl is inside row details, the DataContext of the albumsGrid automatically becomes the master data item, in our case the Artist. And since DataContext is an instance of the Artist entity, I have assigned “DataContext.ArtistId” as the PropertyName of the ControlParameter.

Finally, here is what it takes to commit your changes:

MainPage
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Net;
  5. using System.Windows;
  6. using System.Windows.Controls;
  7. using System.Windows.Documents;
  8. using System.Windows.Input;
  9. using System.Windows.Media;
  10. using System.Windows.Media.Animation;
  11. using System.Windows.Shapes;
  12. using MasterDetailsWithRIAServices.Web;
  13. using MasterDetailsWithRIAServices.Web.Services;
  14. using MasterDetailsWithRIAServices.Web.Models;
  15. using System.Windows.Controls.Ria;
  16.  
  17. namespace MasterDetailsWithRIAServices
  18. {
  19.     public partial class AlbumsControl : UserControl
  20.     {
  21.         public AlbumsControl()
  22.         {
  23.             InitializeComponent();
  24.         }
  25.  
  26.         private void OnSubmitChanges(object sender, RoutedEventArgs e)
  27.         {
  28.             this.albumsDataSource.SubmitChanges();
  29.         }
  30.     }
  31. }

 

Hiding the details grid and all of its logic into its own user control cleaned up the MainPage considerably:

MainPage
  1. <UserControl
  2.     x:Class="MasterDetailsWithRIAServices.MainPage"
  3.     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  4.     xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
  5.     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
  6.     xmlns:my="clr-namespace:MasterDetailsWithRIAServices"
  7.     xmlns:riaControls="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Ria"
  8.     xmlns:riaData="clr-namespace:System.Windows.Data;assembly=System.Windows.Controls.Ria"
  9.     xmlns:services="clr-namespace:MasterDetailsWithRIAServices.Web.Services"
  10.     xmlns:telerik="clr-namespace:Telerik.Windows.Controls;assembly=Telerik.Windows.Controls.GridView"
  11.     xmlns:telerikGrid="clr-namespace:Telerik.Windows.Controls.GridView;assembly=Telerik.Windows.Controls.GridView"
  12.     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  13.     Width="560"
  14.     d:DesignHeight="480"
  15.     d:DesignWidth="640"
  16.     mc:Ignorable="d">
  17.     <Grid x:Name="LayoutRoot">
  18.         <Grid.Resources>
  19.             <!-- RowDetailsTemplate containing the details (albums) grid. -->
  20.             <DataTemplate x:Key="AlbumsTemplate">
  21.                 <my:AlbumsControl Width="480"
  22.                                   HorizontalAlignment="Left"
  23.                                   Margin="24,2,2,2"/>
  24.             </DataTemplate>
  25.         </Grid.Resources>
  26.  
  27.         <!-- This is where the master (artists) grid gets its data from. -->
  28.         <riaControls:DomainDataSource x:Name="artistsDataSource"
  29.                                       AutoLoad="True"
  30.                                       QueryName="GetArtistsQuery">
  31.             <riaControls:DomainDataSource.DomainContext>
  32.                 <services:ChinookContext/>
  33.             </riaControls:DomainDataSource.DomainContext>
  34.         </riaControls:DomainDataSource>
  35.  
  36.         <telerik:RadGridView
  37.             Name="artistsGrid"
  38.             ItemsSource="{Binding ElementName=artistsDataSource, Path=Data}"
  39.             IsBusy="{Binding ElementName=artistsDataSource, Path=IsBusy}"
  40.             RowDetailsTemplate="{StaticResource AlbumsTemplate}"
  41.             ColumnWidth="*"
  42.             AutoGenerateColumns="False"
  43.             ShowGroupPanel="False">
  44.             <telerik:RadGridView.Columns>
  45.                 <telerik:GridViewToggleRowDetailsColumn/>
  46.                 <telerik:GridViewDataColumn
  47.                     DataMemberBinding="{Binding Name}"
  48.                     Header="Artist"/>
  49.             </telerik:RadGridView.Columns>
  50.         </telerik:RadGridView>
  51.     </Grid>
  52. </UserControl>

 

Below you can see the updated sample application in action:

Download the source code of the updated demo project from here.

9 Comments

  • Matjaz Bravc 18 Jan 2010
    Hi,

    thanks a lot for this great sample, but with AlbumsControl I have bad luck. Simply don't work. After displaying AlbumsControl everything turns into white and dissaper from screen! I have discovered that passing QueryParameters to RIA must be something wrong! I'm using latest RIA build 12/2009 and latest Telerik controls. Can you give me hint/tip how to override this problem???
    ...
    <riaControls:DomainDataSource x:Name="albumsDataSource"
                                          AutoLoad="True"
                                          QueryName="GetAlbumsForArtistIdQuery">
                <riaControls:DomainDataSource.QueryParameters>
                    <riaControls:ControlParameter ControlName="albumsGrid"
                                                  ParameterName="artistId"
                                                  PropertyName="DataContext.ArtistId"/>
                </riaControls:DomainDataSource.QueryParameters>
                <riaControls:DomainDataSource.DomainContext>
                    <services:ChinookContext/>
                </riaControls:DomainDataSource.DomainContext>
    </riaControls:DomainDataSource>
    ...

    Thank you very much!
  • Rossen Hristov 18 Jan 2010
    Can you please open a new support ticket and send me your sample project. I will take a look at it to see what's going wrong.
  • hamit 04 Mar 2010
    I know that is not interesting all the subject but I googled some and I came here, I will ask that;

    I have a RadGridView and  I will give it a DataSource evrything is good but now I want to manipulate for its RowHeight's Auto Resize according to the data. I want provide a current with like 300 px and id the data for the current cell is large than the actual with than it will be expand to the height automatically.

    Is it possible?


    Thanks for all regards
  • Rossen Hristov 05 Mar 2010
    Hello Hamit,

    Can you please open a new support ticket, since this is not the best place for this discussion.
  • GEB 12 Mar 2010
    Great post.  I have a follow up question.  Suppose that you place a button below the grid in the DataTemplate for the Albums.  If the user clicks the button (i.e., to add a new album for the artist), is it possible to determine the associated artist?  That is, given an event within the album control, how to determine the artist associated with the DataTemplate?
  • Rossen Hristov 20 Mar 2010
    Of course it is.

    The DataContext of the control that you have placed in the RowDetailsTemplate is automatically set to the respective parent Artist.

    In my example I have only used the Albums property to bind the child grid, but you can place a TextBlock with Text={Binding Name} and it will display the Artist's name.

    The thing to remember is that the DataContext of each Row Detail is the parent row's DataContext, which is, the entity that is displayed in this parent row. Think of the Row Details as an additional place/space to display what you already have in the row's cells.

    I hope this helps.
  • Ron Frick 06 Jul 2010
    Man this is great. Thanks for the post.  Are you going to keep going with this? Maybe a Master Detail with all CRUD operations.  Keep up the good work!!!

  • Rossen Hristov 06 Jul 2010
    Hello Ron,

    I might continue when I have the spare time. Implementing CRUD should not be so hard. You simply need two DomainDataSources -- one for the master records and one for the details records. Both of them should support editing, deleting, inserting, etc. You can add various buttons inside the row details template that will communicate with the "details" DomainDataSource and perform the CRUD operations.
  • fred 11 Nov 2010
    Hi
    Where I could find a sample using SL4 with visualStudio2010 ?
    Thanks
    Fred

Add comment

  1. Formatting options
       
     
     
     
     
       
  2. (optional, emails won't be shown on public pages)
  3. (optional)