Developpez.com - Microsoft DotNET
X

Choisissez d'abord la catégorieensuite la rubrique :


Exemple d'applications métier avec Silverlight 3 RTM et .NET RIA Services mise à jour de juillet

Partie 14 : Support de Visual Basic (VB) et de WPF

Date de publication : 08 janvier 2011.

Par Brad Adams
 Jérôme Lambert (Traduction) (Espace perso) (Blog)
 

Cet article est une traduction d'un des articles de la série "en Business Apps Example for Silverlight 3 RTM and .NET RIA Services July Update" de Brad Adams.

       Version PDF (Miroir)   Version hors-ligne (Miroir)
Viadeo Twitter Facebook Share on Google+        



I. Support de Visual Basic (VB) et de WPF


I. Support de Visual Basic (VB) et de WPF

Certains ont dit qu'ils aimeraient voir quelque chose dans ma série mettant à jour ma session en Mix09 de "en building business applications with Silverlight 3" en Visual Basic. VB est "super" important dans le champ des applications métier, je n'ai donc aucun problème à satisfaire cette demande. Pendant que j'étais occupé à cela, j'ai pensé que je montrerais également un client WPF pour RIA Services au travers du très sympa support de ADO.NET Data Services que nous avons. Ca ressemble plus au support WinForms que j'ai montré plutôt.

Cette démo nécessite (tout est 100% gratuit et pour toujours) :

  1. VS2008 SP1
  2. Silverlight 3 RTM
  3. .NET RIA Services July '09 Preview <--- N'est en réalité pas nécessaire pour cette démo ! Mais c'est néanmoins bien de le savoir ;-)
Téléchargez ensuite l'ensemble des fichiers des démos (lien sur le site original - lien sur developpez.com).

Vous pouvez voir en la série complète ici.

Dans en la partie 1 : Les bases de la navigation, il n'y a abosulement aucun code, donc la version VB ressemble exactement à ce que j'ai posté.

Dans la partie 2 : Righ Data Query, il y a quelques brides de code supplémentaires intéressantes. Premièrement, regardons au DomainService.
<EnableClientAccess()> _
2: Public Class SuperEmployeeDomainService
3:     Inherits LinqToEntitiesDomainService(Of NORTHWNDEntities)
4:  
5:     Public Function GetSuperEmployees() As IQueryable(Of SuperEmployee)
6:         Dim q = From emp In Me.Context.SuperEmployeeSet _
7:                 Where emp.Issues > 100 _
8:                 Order By emp.EmployeeID
9:         Return q
10:     End Function
11:  
12:  
13:     Public Sub UpdateSuperEmployee(ByVal currentSuperEmployee As SuperEmployee)
14:         Me.Context.AttachAsModified(currentSuperEmployee, Me.ChangeSet.GetOriginal(currentSuperEmployee))
15:     End Sub
16:     Public Sub InsertSuperEmployee(ByVal superEmployee As SuperEmployee)
17:         Me.Context.AddToSuperEmployeeSet(superEmployee)
18:     End Sub
Ici, nous définissons les méthodes de requêtes, mise à jour et insertion.

Après pour mettre en valeur certains de nos supports POCO, j'ai créé une méthode qui retourne les comptes originaux
Public Function GetOrigins() As IQueryable(Of Origin)
 
     Dim q = (From emp In Context.SuperEmployeeSet _
              Select emp.Origin).Distinct().Select(Function(name) New Origin With {.Name = name, .Count = Context.SuperEmployeeSet.Count(Function(emp) emp.Origin.Trim() = name.Trim())})
     q = q.Where(Function(emp) emp.Name IsNot Nothing)
     Return q
 End Function
Et j'ai défini une classe POCO pour retourner ces données au client dans ma fenêtre AutoComplete
Public Class Origin
    Public Sub New()
    End Sub
    Private _Name As String
    <Key()> _
    Public Property Name() As String
        Get
            Return _Name
        End Get
        Set(ByVal value As String)
            _Name = value
        End Set
    End Property
    Private _Count As Integer
    Public Property Count() As Integer
        Get
            Return _Count
        End Get
        Set(ByVal value As Integer)
            _Count = value
        End Set
    End Property
End Class
Du côté client dans le projet Silverlight, je finis par faire la plupart des choses au travers de liaisons dans Xaml, donc celles-ci sont exactement les mêmes en VB. Mais j'ai créé un AddNewEmployee ChildWindow.
Partial Public Class AddNewWindow
    Inherits ChildWindow
    Private _NewEmployee As SuperEmployee
    Public Property NewEmployee() As SuperEmployee
        Get
            Return _NewEmployee
        End Get
        Set(ByVal value As SuperEmployee)
            _NewEmployee = value
        End Set
    End Property
 
    Public Sub New()
        InitializeComponent()
 
        NewEmployee = New SuperEmployee()
        NewEmployee.LastEdit = DateTime.Now.[Date]
        Me.newEmployeeForm.CurrentItem = NewEmployee
    End Sub
 
    Private Sub OKButton_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
        newEmployeeForm.CommitEdit()
        Me.DialogResult = True
    End Sub
 
    Private Sub CancelButton_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
        Me.DialogResult = False
    End Sub
 
End Class
Et ensuite nous lançons juste cet évènement
Private Sub AddNew_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs)
    Dim w = New AddNewWindow()
 
    AddHandler w.Closed, AddressOf addNewWindow_Closed
 
    w.Show()
 
End Sub
Private Sub addNewWindow_Closed(ByVal sender As Object, ByVal e As EventArgs)
    Dim win = TryCast(sender, AddNewWindow)
    Dim context = TryCast(dds.DomainContext, SuperEmployeeDomainContext)
    If win.DialogResult = True Then
        context.SuperEmployees.Add(win.NewEmployee)
    End If
End Sub
en Partie 3 : Authentification - abosulement aucun code ici... C'est exactement pareil entre VB et C#.


Pour SEO, nous avons activé un lien en profondeur en maintenant plusieurs évènements...
'Executes when the user navigates to this page.
Protected Overrides Sub OnNavigatedTo(ByVal e As System.Windows.Navigation.NavigationEventArgs)
    Dim qs = NavigationContext.QueryString
 
    If qs.ContainsKey("EmpId") Then
        dds.FilterDescriptors.Add(New FilterDescriptor("EmployeeID", FilterOperator.IsEqualTo, qs("EmpId")))
    End If
 
End Sub
Et
Private Sub dataGrid1_SelectionChanged(ByVal sender As System.Object, ByVal e As System.Windows.Controls.SelectionChangedEventArgs)
    Dim emp = TryCast(dataGrid1.SelectedItem, SuperEmployee)
    If emp IsNot Nothing Then
        PermalinkTextBox.Text = (Application.Current.Host.Source.ToString().Replace("ClientBin/MyApp.xap", "") & "#/Home?EmpId=") & emp.EmployeeID
    End If
End Sub
Le code côté serveur pour Sitemap.aspx et le contenu alternatif dans default.aspx est identique.. Exepcté pour une petite partie du code de réécriture d'URL dans default.aspx to s'assurer que le serveur et le client ont tous les deux accès au lien.
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
 
    Dim empId As String = Request.QueryString("EmpId")
    Dim deepLink = "/Home?EmpId=" & empId
 
    If empId IsNot Nothing Then
        Response.Write("<script type=text/javascript>window.location.hash='#" & deepLink & "';</script>")
    End If
 
End Sub
La partie sur l'export vers Excel est super facile également..
Private Sub ExportToExcel_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs)
    Dim context = TryCast(dds.DomainContext, SuperEmployeeDomainContext)
    Dim s = Application.GetResourceStream(New Uri("excelTemplate.txt", UriKind.Relative))
    Dim dialog = New SaveFileDialog()
 
    dialog.DefaultExt = "*.xml"
    dialog.Filter = "Excel Xml (*.xml)|*.xml|All files (*.*)|*.*"
 
    If dialog.ShowDialog() = False Then
        Exit Sub
    End If
 
    Using sw = New StreamWriter(dialog.OpenFile())
        Dim sr = New StreamReader(s.Stream)
        While Not sr.EndOfStream
            Dim line = sr.ReadLine()
            If line = "***" Then
                Exit While
            End If
            sw.WriteLine(line)
        End While
 
        For Each emp In context.SuperEmployees
            sw.WriteLine("<Row>")
            sw.WriteLine("<Cell><Data ss:Type=""String"">{0}</Data></Cell>", emp.Name)
            sw.WriteLine("<Cell><Data ss:Type=""String"">{0}</Data></Cell>", emp.Origin)
            sw.WriteLine("<Cell><Data ss:Type=""String"">{0}</Data></Cell>", emp.Publishers)
            sw.WriteLine("<Cell><Data ss:Type=""Number"">{0}</Data></Cell>", emp.Issues)
            sw.WriteLine("</Row>")
        Next
        While Not sr.EndOfStream
            sw.WriteLine(sr.ReadLine())
        End While
    End Using
End Sub
Après un petit peu de formattage... nous obtenons :

Pour finir, dans en la partie 5 : Astoria, Ajouter une référence Service et WinForms... Définir l'ADO.NET Data Services dans le projet web ressemble à :
Public Class SuperEmployeeWebDataService
 
    Inherits DataService(Of [SuperEmployeeDomainService])
    Implements IServiceProvider
 
    ' This method is called only once to initialize service-wide policies.
    Public Shared Sub InitializeService(ByVal config As IDataServiceConfiguration)
        ' TODO: set rules to indicate which entity sets and service operations are visible, updatable, etc.
        ' Examples:
        config.SetEntitySetAccessRule("*", EntitySetRights.All)
        config.SetServiceOperationAccessRule("*", ServiceOperationRights.All)
    End Sub
Après pour d'autres cas, j'ai créé un client WPF pour ce service. J'ai également utilisé le contrôle DataGrid du très chouette en WPF Control Toolkit.

Tout d'abord, je charge les données...
Private Sub LoadButton_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles LoadButton.Click
    Context = New SuperEmployeeDomainService( _
        New Uri("http://localhost:4558/SuperEmployeeWebDataService.svc/"))
    Context.MergeOption = MergeOption.AppendOnly
 
    Dim q = From emp In Context.SuperEmployee _
    Where emp.Issues > 10 _
    Order By emp.Name _
    Select emp
 
    Dim savedCursor = Cursor
    Cursor = Cursors.Wait
    Me.DataGrid1.ItemsSource = q.ToList()
    Cursor = savedCursor
End Sub
Ensuite, je mets à jour à chaque fois qu'il y a un changement.
Private Sub DataGrid1_CurrentCellChanged(ByVal sender As System.Object, ByVal e As System.EventArgs)
    Dim selectedItem As SuperEmployee = Me.DataGrid1.CurrentItem
 
    If selectedItem Is Nothing Then
        Return
    End If
 
    Dim q = From emp In Context.SuperEmployee _
                Where emp.EmployeeID = selectedItem.EmployeeID _
                Select emp
    Dim employee = q.FirstOrDefault()
 
    employee.Gender = selectedItem.Gender
    employee.Issues = selectedItem.Issues
    employee.LastEdit = selectedItem.LastEdit
    employee.Name = selectedItem.Name
    employee.Origin = selectedItem.Origin
    employee.Publishers = selectedItem.Publishers
    employee.Sites = selectedItem.Sites
 
    Context.UpdateObject(employee)
 
    Dim savedCursor = Cursor
    Cursor = Cursors.Wait
 
    Context.SaveChanges()
 
    Cursor = savedCursor
	 
End Sub


               Version PDF (Miroir)   Version hors-ligne (Miroir)

Valid XHTML 1.0 TransitionalValid CSS!

Copyright © 2011 Brad Abrams. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts. Droits de diffusion permanents accordés à Developpez LLC.

Responsable bénévole de la rubrique Microsoft DotNET : Hinault Romaric -