in
Forums
Blogs
DevExpress.com
Client Center
Support Center
DevExpress Channel

The One With

Silverlight Line of Business Applications: Part 1 - Getting Started

By now, those of you who know me personally or through the forums and blogs know that I love Silverlight. It had me at hello. A rich client side user experience, cross platform*, tiny runtime. What's not to love? In this set of posts, I want to show you some of the things that you would need, to develop a client side applet for your next big product.

For this, we are going to develop and deploy a bug tracking app. "Bugger" and we'll use XPO for Silverlight to connect to our data. If you have not read the Silverlight and Data Access using XPO I suggest you do so as it covers the basics. The article is written for DXperience v8.2, and in v8.3, a few things have been changed. For now, the only thing we need to worry about is the name change of the data acess assemblies.

·    DevExpress.Data.v8.2.SL was renamed to DevExpress.AgData.v8.3

·    DevExpress.Xpo.v8.2.SL was renamed to  DevExpress.AgXpo.v8.3 

Getting Started

We'll start by creating a new ASP.NET project and add a Silverlight-enabled WCF Service to it. The web service will expose the XPO DataStore that our client will use.

      [ServiceContract(Namespace = ""), AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]

      [XmlSerializerFormat]

      public class Gateway {

            static DevExpress.Xpo.DB.IDataStore s_dataStore;

 

            static Gateway() {

                  try {                  

                        string connectionString = DevExpress.Xpo.DB.AccessConnectionProviderMultiUserThreadSafe.GetConnectionString(

                              "C:\\Bugger.mdb", "Admin", string.Empty);

                        s_dataStore = DevExpress.Xpo.XpoDefault.GetConnectionProvider(

                              connectionString,

                              DevExpress.Xpo.DB.AutoCreateOption.DatabaseAndSchema);

                  }

                  catch (Exception e) {

                        System.Diagnostics.Debug.WriteLine(e.Message);

                  }

            }

 

            [OperationContract]

            public DevExpress.Xpo.DB.AutoCreateOption GetAutoCreateOption() {

                  return s_dataStore.AutoCreateOption;

            }

 

            [OperationContract]

            public DevExpress.Xpo.DB.SelectedData SelectData(DevExpress.Xpo.DB.SelectStatement[] selects) {

                  if (selects != null && selects.Length > 0 && selects[0].TableName == "XPObjectType") {

                        return new DevExpress.Xpo.DB.SelectedData(new DevExpress.Xpo.DB.SelectStatementResult());

                  }

                  return s_dataStore.SelectData(selects);

            }

 

            [OperationContract]

            public DevExpress.Xpo.DB.UpdateSchemaResult UpdateSchema(bool dontCreateIfFirstTableNotExist,

                  DevExpress.Xpo.DB.DBTable[] tables) {

                  try {

                        return s_dataStore.UpdateSchema(dontCreateIfFirstTableNotExist, tables);

                  }

                  catch (Exception e) {

                        System.Diagnostics.Debug.WriteLine(e.Message);

                        return DevExpress.Xpo.DB.UpdateSchemaResult.FirstTableNotExists;

                  }

            }

 

            [OperationContract]

            public DevExpress.Xpo.DB.ModificationResult ModifyData(DevExpress.Xpo.DB.ModificationStatement[] statements) {

                  try {

                        return s_dataStore.ModifyData(statements);

                  }

                  catch (Exception e) {

                        System.Diagnostics.Debug.WriteLine(e.Message);

                        return null;

                  }

            }

      }

We will need to add references to DevExpress.Data.v8.3 and DevExpress.Xpo.v8.3 assemblies.

Client Side

On the client side, we will need to add a service reference to this Gateway web service. Instead of using the wizard however, we'll do this manually by adding a generic client proxy implementation (Gateway.cs) to our Silverlight project, downloadable here http://tv.devexpress.com/content/XPO/Gateway/Gateway.zip. We'll update the ServiceReferences.ClientConfig so that our IGateway contract is registered properly.

 <configuration>

  <system.serviceModel>

    <bindings>

      <basicHttpBinding>

        <binding name="BasicHttpBinding_Gateway" maxBufferSize="65536"

          maxReceivedMessageSize="65536">

          <security mode="None" />

        </binding>

      </basicHttpBinding>

    </bindings>

    <client>

      <endpoint address="http://localhost:50344/Gateway.svc" binding="basicHttpBinding"

        bindingConfiguration="BasicHttpBinding_Gateway" contract="DevExpress.Xpo.Xtras.IGateway"

        name="BasicHttpBinding_Gateway" />

    </client>

  </system.serviceModel>

</configuration>

 

Now we are ready to design our data model and start running some queries. Our data model is rather simple here. We have only one table Issues that we want to query, add to and display on the screen.

      public enum Status {

            Active,

            Closed,

      }

 

      public enum Importance {

            Normal,

            High,

            Low,

      }

 

      [OptimisticLocking(false)]

      public class Issue : PersistentBase {

            public Issue(Session session)

                  : base(session) {

            }

            Guid _id;

            [Key(AutoGenerate = true)]

            public Guid ID {

                  get { return _id; }

                  set { SetPropertyValue("ID", ref _id, value); }

            }

            string _subject;

            public string Subject {

                  get { return _subject; }

                  set { SetPropertyValue("Subject", ref _subject, value); }

            }

            string _owner;

            public string Owner {

                  get { return _owner; }

                  set { SetPropertyValue("Owner", ref _owner, value); }

            }

            Status _status;

            public Status Status {

                  get { return _status; }

                  set { SetPropertyValue("Status", ref _status, value); }

            }

            Importance _importance;

            public Importance Importance {

                  get { return _importance; }

                  set { SetPropertyValue("Importance", ref _importance, value); }

            }

            [NonPersistent]

            public Visibility HighImportance {

                  get {

                        if (Importance == Importance.High) {

                              return Visibility.Visible;

                        }

                        else {

                              return Visibility.Collapsed;

                        }

                  }

            }

            [NonPersistent]

            public Visibility LowImportance {

                  get {

                        if (Importance == Importance.Low) {

                              return Visibility.Visible;

                        }

                        else {

                              return Visibility.Collapsed;

                        }

                  }

            }

      }

Notice the additional NonPersistent helper properties. They will come in handy when displaying data inside the AgDataGrid.

Since we dont have any data entry forms yet and we need some mock data. Let's add some fake issues. Remember any work done againt XPO must be done asynchronously.

                         DevExpress.Xpo.Xtras.Gateway _dataStore;

             ..

             this._dataStore = new DevExpress.Xpo.Xtras.Gateway(this.Dispatcher);         

             .. 

            ThreadPool.QueueUserWorkItem((state) => {

                        try {

                              using (UnitOfWork unitOfWork = new UnitOfWork(new SimpleDataLayer(this._dataStore))) {

 

                                    var issue = new Issue(unitOfWork);

                                    issue.Owner = "Joe Smith";

                                    issue.Status = Status.Active;

                                    issue.Subject = "New Issue";

 

                                    unitOfWork.Save(issue);

                                    unitOfWork.CommitChanges();

                              };

                        }

                        catch (Exception e) {

                              System.Diagnostics.Debug.WriteLine(e.Message);

                        }

                  });

Displaying the Data

Download the free AgDataGrid and AgMenu suites here http://devexpress.com/Products/NET/Controls/Silverlight/Menu/ we'll use them a lot. Add a reference to the AgDataGrid assembly to your project and add a name space alias to it inside your page.xaml. In this case AgDataGridEx is a derived class from the standard AgDataGrid and the namespace alias is our project itself. 

      public class AgDataGridEx : AgDataGrid {

            public AgDataGridEx() {

                  this.DefaultStyleKey = typeof(AgDataGridEx);

            }

      } 

 

      <bugger:AgDataGridEx Grid.Row="1" x:Name="issuesDataGrid" ColumnsAutoWidth="True" ShowGroupPanel="Visible" SelectionMode="None">

            <bugger:AgDataGridEx.Resources>

                <DataTemplate x:Key="ImportanceCellTemplateEx">

                    <Grid HorizontalAlignment="Center" Margin="0,0,2,0">

                        <Image Source="ImportanceRed.png" Stretch="None" Visibility="{Binding CellValue}"></Image>

                    </Grid>                   

                </DataTemplate>

            </bugger:AgDataGridEx.Resources>

            <bugger:AgDataGridEx.Columns>

                <bugger:AgDataGridColumnEx x:Name="issuesColumnImportance" FieldName="HighImportance" FixedWidth="True" Width="22"

                        MinColumnWidth="22" MaxColumnWidth="22" AllowResizing="False" AllowGrouping="False"

                        CellDisplayTemplate="{StaticResource ImportanceCellTemplateEx}">

                    <bugger:AgDataGridColumnEx.HeaderContent>

                        <Image Source="ImportanceBlack.png" Width="3" Height="11" Stretch="Uniform"></Image>

                    </bugger:AgDataGridColumnEx.HeaderContent>

                </bugger:AgDataGridColumnEx>

                <bugger:AgDataGridColumnEx FieldName="Subject" Width="250" />

                <bugger:AgDataGridColumnEx FieldName="Owner" />

                <bugger:AgDataGridColumnEx FieldName="Status" />

            </bugger:AgDataGridEx.Columns>

      </bugger:AgDataGridEx>

 

Notice how the HighImportance property is used in our DataTemplate. We'll cover more of this in the next parts where we'll explore the AgDataGrid customization.

To fetch the data from the server, simply run a query against the issues table.

      private void AsyncGetData() {

                  ThreadPool.QueueUserWorkItem(delegate(object state) {

                        UnitOfWork unitOfWork = new UnitOfWork(new SimpleDataLayer(_dataStore));

 

                        XPQuery<Issue> issues = new XPQuery<Issue>(unitOfWork);

                        var query = from t in issues

                                          select t;

 

                        var list = query.ToList<Issue>();

 

                        Dispatcher.BeginInvoke(() => {

                              issuesDataGrid.DataSource = list;

                        });

 

                  });

      }

 

And that's it. Well not yet, we still need to make our UI pretty, we still need to add a data entry form etc... Stay tuned for Parts 2 and 3.

Eventually, we want to get to something like this:

 

or rather this Stick out tongue (A free t-shirt to the first person who tells me what this is. The mock data records should give it away pretty quickly.)

Cheers,

Azret

 

Published Dec 01 2008, 04:11 PM by Azret Botash (Developer Express)
Technorati tags: Silverlight, AgDataGrid, XPO, AgMenu

Comments

 

Chris W Walsh said:

Love the work!!!! :D

December 2, 2008 1:16 AM
 

Stefan Heim said:

Nice to see, that you're sill using XPO ;-)

Good Work!

December 2, 2008 5:41 AM
 

Christoph Brändle said:

great sample,

yes we want silverlight

yes we want wpf

December 2, 2008 6:31 AM
 

proxy server | Digg hot tags said:

Pingback from  proxy server | Digg hot tags

December 2, 2008 11:40 AM
 

Matthew K said:

Are you referring to an application shortcut, which opens a special Google Chrome "application window"?

It's cool to see silverlight in there. I've been on some silverlight multimedia sites that didn't work with Chrome.

December 2, 2008 1:56 PM
 

Azret Botash (Developer Express) said:

Hi Matthew,

There are some gotchas in the WebKit and NPAPI.

But to answer your question, no it is not an application shortcut :)

December 2, 2008 2:16 PM
 

free counter strike download | Digg hot tags said:

Pingback from  free counter strike download | Digg hot tags

December 3, 2008 3:21 AM
 

2008 December 03 - Links for today « My (almost) Daily Links said:

Pingback from  2008 December 03 - Links for today « My (almost) Daily Links

December 3, 2008 6:11 AM
 

Ben Hayat said:

>>(A free t-shirt to the first person who tells me what this is. The mock data records should give it away pretty quickly.)<<

Azret, would that be an "off-line" usage of XPO and SL? :-)

..Ben

December 3, 2008 7:53 AM
 

Azret Botash (Developer Express) said:

Hi Ben,

No. but offline XPO is an interesting thought.

December 3, 2008 1:38 PM
 

Matthew K said:

Azret,

Perhaps you are going to describe how to get rid of the scrollbar!

December 3, 2008 4:35 PM
 

Karl Greenwood said:

Smells like Mac

December 4, 2008 8:25 AM
 

Mohsen Benkhellat said:

Just wondering if it has to do with supporting from agDataGrid a hyperlink editor based column and be able to navigate to another web page from there.

Or may be about asynchronous calls to web services

Just guessing

Mohsen

December 4, 2008 3:41 PM
 

Azret Botash (Developer Express) said:

Karl,

It does smell like Mac doesn't it?

December 4, 2008 8:04 PM
 

Community Blogs said:

In this issue: Jobi, Russell Greenspan(5), Mike Ormond, Tim Heuer, Matthias Shapiro(2), Terence Tsang

December 4, 2008 9:41 PM
 

Liu Benxi said:

Fiji?

December 5, 2008 1:02 AM
 

Zinovate said:

Can the IGateway/technic be used in WPF? I'd like to use XPO but lack on an NTier model is a No-go for me but this would solve that.

I love to see the Silverlight support. It WILL be big for DevExpress. You guys should start talking about it.

I feel like a slueth, trying to find out about Silverlight support in XPO.

April 5, 2009 10:44 AM

Leave a Comment

(required)  
(optional)
(required)  
Verification code: Required
   
Add
Copyright © 1998-2009 Developer Express Inc.
ALL RIGHTS RESERVED