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:
I have recreated the ChinookService to support editing.
I have encapsulated the details grid into a new user control called AlbumsControl.
I have added a “Submit Changes” button below the details grid.
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
< UserControl x : Class = "MasterDetailsWithRIAServices.AlbumsControl"
xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns : x = "http://schemas.microsoft.com/winfx/2006/xaml"
xmlns : my = "clr-namespace:MasterDetailsWithRIAServices"
xmlns : riaControls = "clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Ria"
xmlns : riaData = "clr-namespace:System.Windows.Data;assembly=System.Windows.Controls.Ria"
xmlns : services = "clr-namespace:MasterDetailsWithRIAServices.Web.Services"
xmlns : telerik = "clr-namespace:Telerik.Windows.Controls;assembly=Telerik.Windows.Controls.GridView"
xmlns : telerikGrid = "clr-namespace:Telerik.Windows.Controls.GridView;assembly=Telerik.Windows.Controls.GridView" >
< Grid Name = "LayoutRoot" >
< Grid.RowDefinitions >
< RowDefinition Height = "Auto" />
< RowDefinition Height = "Auto" />
< RowDefinition Height = "Auto" />
</ Grid.RowDefinitions >
< 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 >
< TextBlock Grid.Row = "0" Margin = "2" > Albums: </ TextBlock >
< telerik : RadGridView
Name = "albumsGrid"
MinHeight = "100"
MaxHeight = "400"
ItemsSource ="{ Binding ElementName = albumsDataSource , Path = Data} "
IsBusy ="{ Binding ElementName = albumsDataSource , Path = IsBusy} "
Grid.Row = "1"
Margin = "2"
AutoGenerateColumns = "False"
ColumnWidth = "*"
ShowGroupPanel = "False" >
< telerik : RadGridView.Columns >
< telerik : GridViewDataColumn Header = "Album Title"
DataMemberBinding ="{ Binding Title} " />
</ telerik : RadGridView.Columns >
</ telerik : RadGridView >
< Button Name = "submitButton"
Margin = "2"
Grid.Row = "2"
Content = "Submit Changes"
Click = "OnSubmitChanges"
Width = "100"
HorizontalAlignment = "Stretch" />
</ Grid >
</ 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
using System ;
using System . Collections . Generic ;
using System . Linq ;
using System . Net ;
using System . Windows ;
using System . Windows . Controls ;
using System . Windows . Documents ;
using System . Windows . Input ;
using System . Windows . Media ;
using System . Windows . Media . Animation ;
using System . Windows . Shapes ;
using MasterDetailsWithRIAServices . Web ;
using MasterDetailsWithRIAServices . Web . Services ;
using MasterDetailsWithRIAServices . Web . Models ;
using System . Windows . Controls . Ria ;
namespace MasterDetailsWithRIAServices
{
public partial class AlbumsControl : UserControl
{
public AlbumsControl ()
{
InitializeComponent ();
}
private void OnSubmitChanges ( object sender , RoutedEventArgs e )
{
this . albumsDataSource . SubmitChanges ();
}
}
}
Hiding the details grid and all of its logic into its own user control cleaned up the MainPage considerably:
MainPage
< UserControl
x : Class = "MasterDetailsWithRIAServices.MainPage"
xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns : d = "http://schemas.microsoft.com/expression/blend/2008"
xmlns : mc = "http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns : my = "clr-namespace:MasterDetailsWithRIAServices"
xmlns : riaControls = "clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Ria"
xmlns : riaData = "clr-namespace:System.Windows.Data;assembly=System.Windows.Controls.Ria"
xmlns : services = "clr-namespace:MasterDetailsWithRIAServices.Web.Services"
xmlns : telerik = "clr-namespace:Telerik.Windows.Controls;assembly=Telerik.Windows.Controls.GridView"
xmlns : telerikGrid = "clr-namespace:Telerik.Windows.Controls.GridView;assembly=Telerik.Windows.Controls.GridView"
xmlns : x = "http://schemas.microsoft.com/winfx/2006/xaml"
Width = "560"
d : DesignHeight = "480"
d : DesignWidth = "640"
mc : Ignorable = "d" >
< Grid x : Name = "LayoutRoot" >
< Grid.Resources >
<!-- RowDetailsTemplate containing the details (albums) grid. -->
< DataTemplate x : Key = "AlbumsTemplate" >
< my : AlbumsControl Width = "480"
HorizontalAlignment = "Left"
Margin = "24,2,2,2" />
</ DataTemplate >
</ Grid.Resources >
<!-- This is where the master (artists) grid gets its data from. -->
< riaControls : DomainDataSource x : Name = "artistsDataSource"
AutoLoad = "True"
QueryName = "GetArtistsQuery" >
< riaControls : DomainDataSource.DomainContext >
< services : ChinookContext />
</ riaControls : DomainDataSource.DomainContext >
</ riaControls : DomainDataSource >
< telerik : RadGridView
Name = "artistsGrid"
ItemsSource ="{ Binding ElementName = artistsDataSource , Path = Data} "
IsBusy ="{ Binding ElementName = artistsDataSource , Path = IsBusy} "
RowDetailsTemplate ="{ StaticResource AlbumsTemplate} "
ColumnWidth = "*"
AutoGenerateColumns = "False"
ShowGroupPanel = "False" >
< telerik : RadGridView.Columns >
< telerik : GridViewToggleRowDetailsColumn />
< telerik : GridViewDataColumn
DataMemberBinding ="{ Binding Name} "
Header = "Artist" />
</ telerik : RadGridView.Columns >
</ telerik : RadGridView >
</ Grid >
</ UserControl >
See the editing in action:
VIDEO
Download the source code of the updated demo project from here .