brafales
brafales

Reputation: 590

Silverlight Databind to a parametrized DataService

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!

Upvotes: 0

Views: 2458

Answers (2)

funwithcoding
funwithcoding

Reputation: 2412

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>

Upvotes: 1

funwithcoding
funwithcoding

Reputation: 2412

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!

Upvotes: 1

Related Questions