views:

1046

answers:

2

Hi, I'm building a Silverlight app using RIA Services. I want to implement a master/detail behaviour. The trick here is that the "detail" grid can not be filled directly with the "SelectedItem" property of the master grid, and what I have to do is get one of the fields from the master grid and use it as a parameter to the DataService. How would the binding be?

This is the code of the parametrized query:

public Usuarios GetUserFromId(int id)
    {
        return this.ObjectContext.Usuarios.Where(u => u.ID == id).First();
    }

And these are the sources on the XAML:

<riaControls:DomainDataSource x:Name="DomainDataSourceRaceTrackGetUsersWithRole" AutoLoad="True" QueryName="GetUsersWithRoleQuery" LoadSize="20">
            <riaControls:DomainDataSource.DomainContext>
            <App:DomainServiceRaceTrack></App:DomainServiceRaceTrack>
        </riaControls:DomainDataSource.DomainContext>
        </riaControls:DomainDataSource>
    <riaControls:DomainDataSource x:Name="DomainDataSourceRaceTrackGetUserById" AutoLoad="True" QueryName="GetUserFromId">
        <riaControls:DomainDataSource.DomainContext>
            <App:DomainServiceRaceTrack></App:DomainServiceRaceTrack>
        </riaControls:DomainDataSource.DomainContext>
    </riaControls:DomainDataSource>

Here's how I bind the master grid:

<data:DataGrid x:Name="DataGridUsers" AutoGenerateColumns="False" ItemsSource="{Binding Data, ElementName=DomainDataSourceRaceTrackGetUsersWithRole}">

And then on SelectedItemChanged I need to populate the Detail grid, but the binding I use doesn't work:

<dataControls:DataForm x:Name="dataForm1" Height="393" Width="331"
                           VerticalAlignment="Top"       
                           Header="User Details"
                           CurrentItem="{Binding DataGridUsers.SelectedItem.Id, ElementName=DomainDataSourceRaceTrackGetUserById}" 
                            HorizontalAlignment="Left" >
                <dataControls:DataForm.EditTemplate>

Anyone knows what I'm doing wrong? I'd like to use XAML instead of codebehind.

Thanks!

A: 

Well! You have to pass the parameter 'id' to 'DomainDataSourceRaceTrackGetUserById' without which RIA services has no idea where to get the 'id' value.

<riaControls:DomainDataSource x:Name="DomainDataSourceRaceTrackGetUserById" AutoLoad="True" QueryName="GetUserFromId">
        <riaControls:DomainDataSource.DomainContext>
            <App:DomainServiceRaceTrack></App:DomainServiceRaceTrack>
        </riaControls:DomainDataSource.DomainContext>

<riaControls:DomainDataSource.QueryParameters> <riaData:ControlParameter
                    ParameterName="id"
                    ControlName="DataGridUsers"
                    PropertyName="SelectedItem.Id"
                    RefreshEventName="SelectedItemChanged" /> </riaControls:DomainDataSource.QueryParameters>
    </riaControls:DomainDataSource>

and bind your dataForm1 ItemsSource to member 'Data' of 'DomainDataSourceRaceTrackGetUserById'. Test it and let me know If I am missing something.

Hope this helps!

funwithcoding
I'm getting an error: QueryParameters cannot be changed when AutLoad is set to True and CanLoad is set to False. Any ideas? Also, on the first load I get the error Load operation failed for query 'GetUserFromId'. Sequence contains no elements.Any ideas?
brafales
I think you're hitting a limitation in our PDC release that caused some headaches for people. We were blocking loads when an existing load was pending, and this was getting hit very frequently.That behavior will be fixed in our next release so that a pending load will be canceled when a new load is invoked.In the meantime, you may have to turn auto load off for the child data DomainDataSource, listen to the SelectionChange events on the master grid, cancel any pending loads on the child data, and invoke the new load.
Jeff Handley
Ok, I'll give it a try.Thanks to both for the answers!
brafales
note: controlparameter is now gone in SL4 - https://forums.silverlight.net/forums/t/167989.aspx
Simon_Weaver
+1  A: 

Here is the complete XAML. It is implemented very quickly,so pls let me know if it can be done even better. Click Here for complete project source code

 <UserControl xmlns:my1="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data.DataForm.Toolkit"  x:Class="Silverlight4LobHol.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    d:DesignHeight="600" d:DesignWidth="800" xmlns:data="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data" xmlns:controlsToolkit="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Toolkit" xmlns:riaControls="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Ria" xmlns:my="clr-namespace:Silverlight4LobHol.Web" xmlns:controls="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls" xmlns:my2="clr-namespace:System.Windows.Data;assembly=System.Windows.Controls.Ria" xmlns:dataInput="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data.Input">

    <Grid x:Name="LayoutRoot" Background="White">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*" />
            <ColumnDefinition Width="300" />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="50" />
            <RowDefinition Height="*" />
            <RowDefinition Height="50" />
        </Grid.RowDefinitions>
        <riaControls:DomainDataSource AutoLoad="True" LoadedData="orderDomainDataSource_LoadedData" Name="orderDomainDataSource" QueryName="GetOrdersQuery">
                <riaControls:DomainDataSource.DomainContext>
                <my:NorthWindDomainContext />
            </riaControls:DomainDataSource.DomainContext>
        </riaControls:DomainDataSource>
        <data:DataGrid AutoGenerateColumns="False" Grid.Row="1" Grid.Column="0" ItemsSource="{Binding ElementName=orderDomainDataSource, Path=Data}" Name="orderDataGrid" RowDetailsVisibilityMode="VisibleWhenSelected">
            <data:DataGrid.Columns>
                <data:DataGridTextColumn x:Name="customerIdColumn" Binding="{Binding Path=CustomerID}" Header="CustomerID" Width="SizeToHeader"  />
                <data:DataGridTextColumn x:Name="freightColumn" Binding="{Binding Path=Freight}" Header="Freight" Width="SizeToHeader" />
                <data:DataGridTemplateColumn x:Name="orderDateColumn" Header="Order Date" Width="SizeToHeader">
                    <data:DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <controls:DatePicker SelectedDate="{Binding Path=OrderDate, Mode=TwoWay, ValidatesOnExceptions=true, NotifyOnValidationError=true}" />
                        </DataTemplate>
                    </data:DataGridTemplateColumn.CellTemplate>
                </data:DataGridTemplateColumn>
                <data:DataGridTextColumn x:Name="orderIDColumn" Binding="{Binding Path=OrderID}" Header="Order ID" Width="SizeToHeader" />
                <data:DataGridTemplateColumn x:Name="requiredDateColumn" Header="Required Date" Width="SizeToHeader">
                    <data:DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <controls:DatePicker SelectedDate="{Binding Path=RequiredDate, Mode=TwoWay, ValidatesOnExceptions=true, NotifyOnValidationError=true}" />
                        </DataTemplate>
                    </data:DataGridTemplateColumn.CellTemplate>
                </data:DataGridTemplateColumn>
                <data:DataGridTextColumn x:Name="shipAddressColumn" Binding="{Binding Path=ShipAddress}" Header="Ship Address" Width="SizeToHeader" />
                <data:DataGridTextColumn x:Name="shipCityColumn" Binding="{Binding Path=ShipCity}" Header="Ship City" Width="SizeToHeader" />
                <data:DataGridTextColumn x:Name="shipCountryColumn" Binding="{Binding Path=ShipCountry}" Header="Ship Country" Width="SizeToHeader" />
                <data:DataGridTextColumn x:Name="shipNameColumn" Binding="{Binding Path=ShipName}" Header="Ship Name" Width="SizeToHeader" />
                <data:DataGridTemplateColumn x:Name="shippedDateColumn" Header="Shipped Date" Width="SizeToHeader">
                    <data:DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <controls:DatePicker SelectedDate="{Binding Path=ShippedDate, Mode=TwoWay, ValidatesOnExceptions=true, NotifyOnValidationError=true}" />
                        </DataTemplate>
                    </data:DataGridTemplateColumn.CellTemplate>
                </data:DataGridTemplateColumn>
                <data:DataGridTextColumn x:Name="shipPostalCodeColumn" Binding="{Binding Path=ShipPostalCode}" Header="Ship Postal Code" Width="SizeToHeader" />
                <data:DataGridTextColumn x:Name="shipRegionColumn" Binding="{Binding Path=ShipRegion}" Header="Ship Region" Width="SizeToHeader" />
                <data:DataGridTextColumn x:Name="shipViaColumn" Binding="{Binding Path=ShipVia}" Header="Ship Via" Width="SizeToHeader" />
            </data:DataGrid.Columns>
        </data:DataGrid>
        <controlsToolkit:BusyIndicator Grid.Row="1" Grid.Column="0" IsBusy="{Binding ElementName=orderDomainDataSource,Path=IsBusy}"></controlsToolkit:BusyIndicator>
        <riaControls:DomainDataSource AutoLoad="True" Height="0" LoadedData="customerDomainDataSource_LoadedData" Name="customerDomainDataSource" QueryName="GetCustomersByCustomerIdQuery" Width="0" Visibility="Visible">
            <riaControls:DomainDataSource.DomainContext>
                <my:NorthWindDomainContext />
            </riaControls:DomainDataSource.DomainContext>
            <riaControls:DomainDataSource.QueryParameters>
                <riaControls:ControlParameter ControlName="orderDataGrid" ParameterName="customerId" PropertyName="SelectedItem.CustomerID" RefreshEventName="SelectionChanged" />
            </riaControls:DomainDataSource.QueryParameters>
        </riaControls:DomainDataSource>
                <my1:DataForm Grid.Row="1" Grid.Column="1"  ItemsSource="{Binding ElementName=customerDomainDataSource, Path=Data}" HeaderVisibility="Collapsed"></my1:DataForm> 

    </Grid>
</UserControl>
funwithcoding
Did this resolve this issue? or still you have some issues?
funwithcoding