AspAlliance.com LogoASPAlliance: Articles, reviews, and samples for .NET Developers
URL:
http://aspalliance.com/articleViewer.aspx?aId=2074&pId=-1
Observable Collections
page
by frans eilering
Feedback
Average Rating: 
Views (Total / Last 10 Days): 40999/ 47

Introduction

There are many items on the Internet about Silverlight, retrieving information from a SQL database, WCF RIA Services and datagrid connection. Implementing them in a complete project still remains time consuming. In this article Frans will start from the beginning with a new Silverlight 4 project, trying to explain the use and behavior of the datagrid observable collection and the connection with the database through the WCF RIA Services.

Create a new project

From the menu, create a new Silverlight application

Make sure WCF RIA Services is enabled.

The result is a new project divided into two parts as can be seen in the Solution Explorer.

A first part called ObservableCollection and a second with the same name but with the extension .Web.

The first part can be seen as the Silverlight part running on your computer. The second one runs on the Internet. Communication between these two parts is done using WCF RIA Services.

 

Classes

In this project we need several Classes. They must be included in the Internet part. To create a new Class, select the ObservableCollection.Web with a right mouse click and select "New Item".

 

Select "Class", give it a name and click "OK".

Below a new Class Contact.vb is created.

We need four Classes.

·       Contact.vb

·       Functions.vb

·       SQLHelper.vb

·       Config.vb

You need to create the Classes this way. Just adding a Class to the ObservableCollection.Web directory on your computer will show it but will not be recognized.

The SQLhelper.vb Class can be copied from the attached project. Copy this code and paste in into the SQLHelper.vb Class just created.

In the Contact.vb Class I will use just the name, address and City of a Contact. Further, each contact will have an ID named IDContact. The ID will be a GUI, an automatically created ID of 38 characters.

Code of Class Contact.vb

Imports System.Data.SqlClient
Imports System.Data
Imports System
Imports System.Web
Namespace demo
    Public Class Contact 
        Private _City As String 
        Private _Address As String 
        Private _Name As String 
        Private _IDContact As String 
        Public Sub New()  
            MyBase.New()
        End Sub
        Public Property City() As String 
            Get
                Return _City
            End Get
            Set(ByVal Value As String)
                If Value = "" Then
                    _City = Nothing
                Else
                    _City = Value
                End If
            End Set
        End Property
        Public Property Address() As String 
            Get
                Return _Address
            End Get
            Set(ByVal Value As String)
                If Value = "" Then
                    _Address = Nothing
                Else
                    _Address = Value
                End If
            End Set
        End Property
        Public Property Name() As String 
            Get
                Return _Name
            End Get
            Set(ByVal Value As String)
                If Value = "" Then
                    _Name = Nothing
                Else
                    _Name = Value
                End If
            End Set
        End Property
        Public Property IDContact() As String 
            Get
                Return _IDContact
            End Get
            Set(ByVal Value As String)
                If Value = "" Then
                    _IDContact = Nothing
                Else
                    _IDContact = Value
                End If
            End Set
        End Property
         Public Overloads Function GetsContactAll() As SqlDataReader 
            Dim arParms() As SqlParameter = New SqlParameter(0) {}
             Return SqlHelper.ExecuteReader(demo.Config.Connectionstring, 
Data.CommandType.StoredProcedure, "O_GetS_ContactMaster", arParms)
        End Function 
    End Class 
End Namespace

The code in the Functions.vb Class will not be used as a Class but as a module. It is easier to implement.

Suppose I need IDContact. What happens if IDContact is empty or Nothing? I need an empty string.

           Contact.IDContact = demo.Functions.NullSafeString(key)

will give it.

 

Code Class Funcions.vb

Namespace demo
    Public Module Functions
        Public Function NullSafeString(ByVal arg As ObjectOptional ByVal 
returnIfEmpty As String = ""As String
            Dim returnValue As String
            If (arg Is DBNull.Value) OrElse (arg Is NothingOrElse (arg Is 
String.Empty) Then
                returnValue = returnIfEmpty
            Else
                Try
                    returnValue = CStr(arg).Trim
                Catch
                    returnValue = returnIfEmpty
                End Try
            End If
            Return returnValue
        End Function
    End Module
End Namespace

Then the Config.vb Class. This is also a module. In the Contact Class I want to get data from the SQL database through a connection string.

demo.Config.Connectionstring

will give it.

Code Class Config.vb

Imports System.Web
Imports System.Configuration
Namespace demo
    Public Module Config
        Dim result As String
        Public Function Connectionstring() As String
            result = (ConfigurationManager.AppSettings("ConnectionItalie"))
            Return result
        End Function
    End Module
End Namespace

The connection information itself is stored in the config.web part.

Code for the Config.web.

<?xml version="1.0"?>
 
 
<configuration>
    <system.web>
        <compilation debug="true" strict="false" explicit="true" targetFramework="4.0" />
    </system.web>
    <appSettings>
        <add key="ConnectionItalie" 
value="Data Source='URL'; user ID='username';Password='Password';Initial 
Catalog='DatabaseName';" />
    </appSettings>
 
    <system.serviceModel>
        <behaviors>
            <serviceBehaviors>
                <behavior name="">
                    <serviceMetadata httpGetEnabled="true" />
                    <serviceDebug includeExceptionDetailInFaults="false" />
                </behavior>
            </serviceBehaviors>
        </behaviors>
        <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
    </system.serviceModel>
</configuration>

 

The database

Create the table

In the SQL database, create the contact table

Go to your database and insert a new stored procedure.

Copy the code below in this procedure and click the "Execute" button.

Code for creating table Contact

USE [yentel]
GO
/****** Object:  Table [dbo].[Contact]    Script Date: 08/10/2011 18:52:03 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[Contact](
      [City] [varchar](100) NULL,
      [Address] [varchar](100) NULL,
      [Name] [varchar](100) NULL,
      [IDContact] [varchar](38) NOT NULLON [PRIMARY]
 
GO
 
ALTER TABLE [dbo].[Contact] ADD  CONSTRAINT [UK_ContactIDContact]  
DEFAULT (newid()) FOR [IDContact]
GO

The last instruction will automatically create a new IDContact for you for new contacts.

 

Insert some data in this table

Pressing the exclamation symbol will refresh the table and the new ID's will be shown..

 

Adding data to your table can also be done using Access.

Open Access

From the File menu, select new.

On the right side, select "Project using existing data"

Give it a name

And click the create button.

In the next window, insert the database URL and your credentials.

And click OK.

Click Save Password is the easiest way.

Another way for creating the table is using TSQL in a bat file.

Open Notepad.

Insert the code below

Code for TSQL batch file

Print 'START(A)'
GO 1
If not EXISTS
    (
        SELECT *
        FROM INFORMATION_SCHEMA.TABLES
        WHERE TABLE_NAME = 'Contact'
    )
    BEGIN
CREATE TABLE [dbo].[Contact] (
      [City] [varchar] (100)  NULL ,
      [Address] [varchar] (100)  NULL ,
      [Name] [varchar] (100)  NULL ,
      [IDContact] [varchar] (38)   NOT NULL
      ) ON [PRIMARY]
 
            ALTER TABLE [dbo].[Contact] WITH NOCHECK ADD
                  CONSTRAINT [PK_Contact] PRIMARY KEY  CLUSTERED
                  (
                  [IDContact]
                  )  ON [PRIMARY]
END
 
            ALTER TABLE [dbo].[Contact] ADD
                  CONSTRAINT [UK_ContactIDContact] DEFAULT (newid()) FOR 
[IDContact]
            CREATE  INDEX [IX_Contact] ON [dbo].[Contact]([IDContact]) ON 
[PRIMARY]
            SET QUOTED_IDENTIFIER ON
            SET ANSI_NULLS ON
 
PRINT ''
GO
 

Save this file on disk as "O_Contact.txt".

Create a new text file containing the code below

Code for TSQL batch file

OSQL.EXE  -U UserName -P Password -S sql1.vaisulweb.it 
-i C:\Frans\O_Contact.txt -o C:\Frans\O_Contact.out -d Yentel

And save it to disk as contact.bat.

It contains

OSQL.EXE  -U USERNAME -P Password -S yourURL -i SOURCE -o DESTINATION -d DATABASE

Now when you double click the bat file, your txt file will be executed. The "O_Contact.out" will contain the result. You can open it in Notepad.

You can use this structure for all kinds of database commands; create tables, create or delete stored procedures etc.

 

Now that the table is created, we need a stored procedure to get the information from the contact table in our project.

Stored procedures

Create the Contact stored procedure

CREATE PROCEDURE O_GetS_ContactMaster
 
      AS
      SET CONCAT_NULL_YIELDS_NULL  OFF
      SET NOCOUNT ON SELECT     
            Contact.IDContact AS IDContact,
            Contact.City AS City,
            Contact.Address AS Address,
            Contact.Name AS Name
FROM Contact
 
ORDER BY Name
 
GO

(You can insert this text into the O_Contact.txt file and click the same bat file)

This was the preparation. Now we need to add our datagrid and our Servicereference.

 

ServiceReference

A ServiceReference will be used as link between the Silverlight part and the web part. It can be seen as a webservice. You ask a question and the result comes back. Asynchronously. This means "Don't wait for the answer. If it is there you should handle it".

First Build the project. It's a good practice to regularly build it.

First, create the Service reference.

Right click the web part.

Select "New item"

 

Select WCF Service and click Add.

A new WCF Service reference will be created with the name Service1.

Two files have been added to the web project.

Service1.svc.vb and IService1.vb.

The are closely linked. A function inserted in Service1.svc.vb  must be inserted as an OperationContract in IService1.vb

New code for IService1.vb

Imports System.ServiceModel
 
' NOTE: You can use the "Rename" command on the context menu to change the 
' interface name "IService1" in both code and config file together.
<ServiceContract()>
Public Interface IService1
 
    <OperationContract()>
    Sub DoWork()
 
    <OperationContract()> _
    Function FindContactList() As List(Of demo.Contact)
 
End Interface

You may remove the sub DoWork. The IService1.vb can contain more OperationContracts.

In Service1.svc.vb insert the code below.

New code for Service1.svc.vb

Imports System.Data.SqlClient
 
' NOTE: You can use the "Rename" command on the context menu to change the class 
' name "Service1" in code, svc and config file together.
Public Class Service1
    Implements IService1
 
    Public Sub DoWork() Implements IService1.DoWork
    End Sub
 
    Public Function FindContactList() As List(Of demo.Contact) Implements 
IService1.FindContactList
        Return New ContactManager().FindContactList()
    End Function
 
 
    Public Class ContactManager
        Public Function FindContactList() As List(Of demo.Contact)
            Dim OContact As demo.Contact
            OContact = New demo.Contact
 
            Dim Bdr As System.Data.SqlClient.SqlDataReader  ' IS CLOSED BELOW F
            Bdr = OContact.GetsContactAll
 
            Dim ContactList = New List(Of demo.Contact)()
            If Bdr IsNot Nothing Then
                Do While Bdr.Read()
                    Dim NewContact = CreateNewContact(Bdr)
                    ContactList.Add(NewContact)
                Loop
            End If
            Bdr = Nothing
 
            Return ContactList
        End Function
 
        Private Function CreateNewContact(ByVal rdr As SqlDataReader) As 
demo.Contact
            Dim NewContact = New demo.Contact With {
                .IDContact = rdr("IDContact").ToString(),
                .Name = rdr("Name").ToString(),
                .Address = rdr("Address").ToString(),
                .City = rdr("City").ToString()
            }
            Return NewContact
        End Function
    End Class
End Class
 

If you call the function FindContactList then a new object OContact is created. Then through our SQLHelper a SQLDataReader is filled with the information coming from the GetsContactAll function in our Contact Class. Then iterate through our SQLDataReader to create a list.

 

Again, build the solution.

Add the service reference

Right click your silverlight part of the project and select "Add Service reference"

Click the "Discover" button to look for Services in your project.

And click OK.

It will take some time but then you will see a new Servicereference1.

This will be the file to communicate with from your Silverlight part.

Mainpage.aspx

In your mainpage.aspx, drag a datagrid to your grid.

Code for mainpage.aspx

<UserControl x:Class="ObservableCollection.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="300" d:DesignWidth="732" 
xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk">
 
    <Grid x:Name="LayoutRoot" Background="White">
        <sdk:DataGrid 
            AutoGenerateColumns="True" 
            Height="153" 
            HorizontalAlignment="Left" 
            Margin="9,14,0,0" 
            Name="DataGrid1" 
            VerticalAlignment="Top" 
            Width="711" />
    </Grid>
</UserControl>

Change the AutoGenerateColumns to true.

Build your solution again otherwise your servicereference will not be implemented correctly.

The the code behind for your mainpage.aspx. Press F7 to open this code page.

Insert the code below.

Code for Mainpage.aspx.vb

Partial Public Class MainPage
    Inherits UserControl
 
    Public Sub New()
        InitializeComponent()
        Dim proxy As ServiceReference1.Service1Client = New 
ServiceReference1.Service1Client
        AddHandler proxy.FindContactListCompleted, AddressOf GetContactcompleted
        proxy.FindContactListAsync()
  
    End Sub
 
    Sub GetContactcompleted(ByVal sender As Object, ByVal e As 
ServiceReference1.FindContactListCompletedEventArgs)
        DataGrid1.ItemsSource = e.Result
    End Sub
End Class

The config.web may be changed when implementing the service. Make sure the connectionstring is properly inserted in this file.

    <appSettings>
        <add key="ConnectionItalie" value="Data Source='URL'; user 
ID='username';Password='Password';Initial Catalog='DatabaseName';" />
    </appSettings>

This code first creates a proxy variable, a link to our servicereference1.

When you type AddHandler proxy. with a dot, all possibilities will be shown for this proxy.

One of them is FindContactListCompleted. So, as soon as our service got all the information from the database we need to do something with it. What we do is in our GetContactcompleted subroutine. So we add a handler to this FindContactListCompleted.

Then we have to call the service using proxy.FindContactListAsync()

In the subroutine GetContactcompleted we bind the result to our datagrid.

Now run your application. This is the result.

ObservableCollection

Insert a break point in the mainpage.aspx.vb code

And put e.result in your watch window by dragging or by right clicking the text and selecting "Add watch".

e.result is of type ObservableCollection. The way I interpret this type is that Silverlight keeps a link to this collection. When we change this collection, it will be visible in the datagrid without having to bind it again.

New code for Mainpage.aspx.vb

Imports System.Collections.ObjectModel
Partial Public Class MainPage
    Inherits UserControl
 
    Public WithEvents MyList As ObservableCollection(Of ServiceReference1.Contact)
    Public Sub New()
        InitializeComponent()
        Dim proxy As ServiceReference1.Service1Client = New 
ServiceReference1.Service1Client
        AddHandler proxy.FindContactListCompleted, AddressOf GetContactcompleted
        proxy.FindContactListAsync()
 
    End Sub
 
    Sub GetContactcompleted(ByVal sender As Object, ByVal e As 
ServiceReference1.FindContactListCompletedEventArgs)
        MyList = e.Result
        DataGrid1.ItemsSource = MyList
    End Sub
End Class

Here a public variable MyList of type ObservableCollection is inserted. It is part of the System.Collections.ObjectModel which is imported.

When running your application, the result will be the same. But changing the content of the datagrid will automatically change the content of MyList. And this can be handled in code.

New code for Mainpage.aspx.vb

Imports System.Collections.ObjectModel
Partial Public Class MainPage
    Inherits UserControl
 
    Public WithEvents MyList As ObservableCollection(Of ServiceReference1.Contact)
    Public Sub New()
        InitializeComponent()
        Dim proxy As ServiceReference1.Service1Client = New 
ServiceReference1.Service1Client
        
        AddHandler proxy.FindContactListCompleted, AddressOf GetContactcompleted
        proxy.FindContactListAsync()
    End Sub
 
    Sub GetContactcompleted(ByVal sender As Object, ByVal e As 
ServiceReference1.FindContactListCompletedEventArgs)
        MyList = e.Result
        DataGrid1.ItemsSource = MyList
 
        MyList.Add(New ServiceReference1.Contact() With { _
        .IDContact = 101, _
        .Name = "new", _
        .Address = "", _
        .City = "" _
       })
 
    End Sub
End Class
 

In this code a new record is inserted into MyList. Although Datagrid1 has been connected before to MyList, changes in MyList still will be visible in the datagrid.

I would like to hide the third column in the datagrid. It should not be visible. I would expect hiding the column in

   Sub GetContactcompleted(ByVal sender As Object, ByVal e As 
ServiceReference1.FindContactListCompletedEventArgs)
        MyList = e.Result
        DataGrid1.ItemsSource = MyList
 
        MyList.Add(New ServiceReference1.Contact() With { _
        .IDContact = 101, _
        .Name = "new", _
        .Address = "", _
        .City = "" _
       })
 
        DataGrid1.Columns(3).Visibility = Windows.Visibility.Collapsed
 
    End Sub

Would hide this column.

But this will result in an error.

Datagrid columns are created after the entire code is finished and can not be handled in this subroutine. A solution may be to manually create the columns in the datagrid. This will be shown later.

What you can do is change the result from the service using ILinq

Using ILinq in the result

  Sub GetContactcompleted(ByVal sender As Object, ByVal e As 
ServiceReference1.FindContactListCompletedEventArgs)
        MyList = e.Result
 
        MyList.Add(New ServiceReference1.Contact() With { _
        .IDContact = 101, _
        .Name = "new", _
        .Address = "", _
        .City = "" _
       })
 
        Dim TopData = From NewData In MyList
              Order By NewData.Name Descending
              Take (2)
        DataGrid1.ItemsSource = TopData
 
    End Sub

Gives this

Update changed information from datagrid.

You may click in a cell in the datagrid and change its contents. But when you refresh your page all changes will be ignored. So, after changing the info you should store it in the database.

First, insert the code below into your Contact.vb Class

Update code in contact class

Public Sub UpdateContact()
      Dim arParms() As SqlParameter = New SqlParameter(3) {}
      arParms(0) = New SqlParameter("@IDContact", Data.SqlDbType.VarChar, 38)
      arParms(0).Value = _IDContact
      arParms(1) = New SqlParameter("@City", Data.SqlDbType.VarChar, 100)
      arParms(1).Value = demo.Functions.NullSafeString(_City, 
DBNull.Value.ToString)
      arParms(2) = New SqlParameter("@Address", Data.SqlDbType.VarChar, 100)
      arParms(2).Value = demo.Functions.NullSafeString(_Address, 
DBNull.Value.ToString)
      arParms(3) = New SqlParameter("@Name", Data.SqlDbType.VarChar, 100)
      arParms(3).Value = demo.Functions.NullSafeString(_Name, 
DBNull.Value.ToString)
      SqlHelper.ExecuteNonQuery(demo.Config.Connectionstring, 
Data.CommandType.StoredProcedure, "O_Upd_Contact", arParms)
End Sub

This will call stored procedure O_Upd_Contact.

So, implement this stored procedure.

Stored procedure for O_Upd_Contact

USE [yentel]
GO
/****** Object:  StoredProcedure [eilering].[O_Upd_Contact]    Script Date: 
08/17/2011 13:10:11 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE [eilering].[O_Upd_Contact]
      (
      
            @IDContact varchar (38),
            @Name varchar (100),
            @Address varchar (100),
            @City varchar (100)
      )
      AS
      SET NOCOUNT ON
 
Update Contact
      SET           
 
            Name = @Name,
            Address = @Address,
            City = @City
      WHERE IDContact  = @IDContact
Then you should modify the servicereference

Modify IService.vb

Code for IService.vb for updating

Imports System.ServiceModel
 
' NOTE: You can use the "Rename" command on the context menu to change the 
' interface name "IService1" in both code and config file together.
<ServiceContract()>
Public Interface IService1
 
    <OperationContract()>
    Sub DoWork()
 
    <OperationContract()> _
    Function FindContactList() As List(Of demo.Contact)
 
    <OperationContract()> _
    Function UpdateContactList(ByVal ModifiedRow As demo.Contact)
 
End Interface

Code for Service1.svc.vb for updating

Imports System.Data.SqlClient
 
' NOTE: You can use the "Rename" command on the context menu to change the class 
' name "Service1" in code, svc and config file together.
Public Class Service1
    Implements IService1
 
    Public Sub DoWork() Implements IService1.DoWork
    End Sub
 
    Public Function FindContactList() As List(Of demo.Contact) Implements 
IService1.FindContactList
        Return New ContactManager().FindContactList()
    End Function
 
    Public Function UpdateContactList(ByVal ModifiedRow As demo.Contact) 
Implements IService1.UpdateContactList
        ModifiedRow.UpdateContact()
    End Function
 
 
    Public Class ContactManager
        Public Function FindContactList() As List(Of demo.Contact)
            Dim OContact As demo.Contact
            OContact = New demo.Contact
 
            Dim Bdr As System.Data.SqlClient.SqlDataReader  ' IS CLOSED BELOW F
            Bdr = OContact.GetsContactAll
 
            Dim ContactList = New List(Of demo.Contact)()
            If Bdr IsNot Nothing Then
                Do While Bdr.Read()
                    Dim NewContact = CreateNewContact(Bdr)
                    ContactList.Add(NewContact)
                Loop
            End If
            Bdr = Nothing
 
            Return ContactList
        End Function
 
        Private Function CreateNewContact(ByVal rdr As SqlDataReader) As 
demo.Contact
            Dim NewContact = New demo.Contact With {
                .IDContact = rdr("IDContact").ToString(),
                .Name = rdr("Name").ToString(),
                .Address = rdr("Address").ToString(),
                .City = rdr("City").ToString()
            }
            Return NewContact
        End Function
    End Class
End Class

Here a new function UpdateContactList is inserted for updating. It expects a row from the datagrid after modifying it. Before going on, build your solution.

Then you should update your servicereference by right clicking your ServisReference1 and selecting Update Service reference.

This MUST be done before you can use the update function in your MainPage.aspx.vb code.

If you insert the update code in your MainPage.aspx.vb code before updating your reference, you get an error.

Then you should include the code which handles the modification in your mainPage.aspx.vb

Code for handling updates from datagrid.

  Private Sub DataGrid1_RowEditEnded(ByVal sender As ObjectByVal e As 
System.Windows.Controls.DataGridRowEditEndedEventArgs) Handles 
DataGrid1.RowEditEnded
<span lang=NL>        </span>'TAKE THE MODIFIED ROW
        Dim ModifiedRow As ServiceReference1.Contact = New 
ServiceReference1.Contact
        ModifiedRow = CType(sender, DataGrid).SelectedItem
 
        'UPDATE THE DATABASE
        Dim proxy As ServiceReference1.Service1Client = New 
ServiceReference1.Service1Client
        AddHandler proxy.UpdateContactListCompleted, AddressOf 
GetUpdateContactcompleted
        proxy.UpdateContactListAsync(ModifiedRow)
    End Sub
 
    Sub GetUpdateContactcompleted(ByVal sender As ObjectByVal e As 
ServiceReference1.UpdateContactListCompletedEventArgs)
        Dim proxy As ServiceReference1.Service1Client = New 
ServiceReference1.Service1Client
        AddHandler proxy.FindContactListCompleted, AddressOf GetContactcompleted
        proxy.FindContactListAsync()
    End Sub
 

When you have finished editing, DataGrid1_RowEditEnded is called. As seen before, first the proxy is created and a handler is added to the servicereference1 UpdateContactListCompleted routine. If this routine is finished GetUpdateContactcompleted is called.

 

If you have changed the information in the database you have to refresh the data in your datagrid because there may be others who have modified other records. So after updating call FindContactListAsync again.

Hide the ID column

To hide the IDContact column insert a second datagrid.

<UserControl x:Class="ObservableCollection.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="300" d:DesignWidth="732" 
xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk">
 
    <Grid x:Name="LayoutRoot" Background="White">
        <sdk:DataGrid x:Name="Datagrid2" AutoGenerateColumns="False">
            <sdk:DataGrid.Columns>
                <sdk:DataGridTextColumn Header="Name" 
                Binding="{Binding Name}" />
                <sdk:DataGridTextColumn Header="Address" 
                Binding="{Binding Address}" />
                <sdk:DataGridTextColumn Header="City" 
                Binding="{Binding City}" />
                <sdk:DataGridTextColumn Header="IDContact" 
                Binding="{Binding IDContact}"  Visibility="Collapsed"/>
            </sdk:DataGrid.Columns>
        </sdk:DataGrid>
        <sdk:DataGrid 
            AutoGenerateColumns="True" 
            Height="121" 
            HorizontalAlignment="Left" 
            Margin="9,167,0,0" 
            Name="DataGrid1" 
            VerticalAlignment="Top" 
            Width="711" />
    </Grid>
</UserControl>
And set Visibility="Collapsed" for this column.
It the Mainpage.aspx.vb code insert the next code

Code for extra datagrid

  Sub GetContactcompleted(ByVal sender As Object, ByVal e As 
ServiceReference1.FindContactListCompletedEventArgs)
        MyList = e.Result
 
        MyList.Add(New ServiceReference1.Contact() With { _
        .IDContact = 101, _
        .Name = "new", _
        .Address = "", _
        .City = "" _
       })
 
        Dim TopData = From NewData In MyList
              Order By NewData.Name Descending
              Take (2)
        DataGrid1.ItemsSource = TopData
        Datagrid2.ItemsSource = MyList
 
    End Sub

Download sample project.


Product Spotlight
Product Spotlight 

©Copyright 1998-2024 ASPAlliance.com  |  Page Processed at 2024-03-28 4:25:17 AM  AspAlliance Recent Articles RSS Feed
About ASPAlliance | Newsgroups | Advertise | Authors | Email Lists | Feedback | Link To Us | Privacy | Search