So I got a little deeper into Silverlight this morning as I was initially discouraged with my initial introduction with Silverlight. Things seemed somewhat more difficult then I thought they would be and I was assuming that it was me more then the toolset.
My Goals
My goal was to create a simple search function that would work against a SalesLogix database through the provider. To make this happen I would need the Silverlight control, and a web service to provide the search data.
Starting off with the UI and moving backward I created the basic XAML to display a filter text box, button and a results grid.
All looked pretty good with the display and the resulting XAML is;
<Grid x:Name="LayoutRoot" ShowGridLines="False" Background="LightSteelBlue" Margin="2"> <StackPanel> <StackPanel Orientation="Horizontal" Margin="2">
<TextBox Width=”400″ x:Name=”searchValue”></TextBox>
<Button x:Name=”Button1″ Click=”Button1_Click” Content=”Search” Width=”95″ Height=”30″ />
</StackPanel>
<my:DataGrid AutoGenerateColumns=”True” x:Name=”myGrid” Width=”500″ Height=”180″></my:DataGrid> </StackPanel> </Grid>
Now that my layout was good. I ran the application to make sure that it displayed in the browser. All is good.
Web Service
Creating the Web service was not too bad. Standard ASP.net web service that was stubbed out as usual with the HelloWorld default method.
I created a basic Account class to be a property bag to return up to my Client as follows;
/// <summary>
/// Summary description for Account
/// </summary>
public class Account
{ public string Name { get; set; }
public string Phone { get; set; }
public Account()
{
}
}
The next thing I did was a new web method to get the accounts based on a value provided by the Client. Deciding to return a list of Accounts as I wanted to avoid any XML parsing on the client and it seemed the most natural way to access the data. The final code is
[WebMethod]
public List<Account> GetAccounts(string lookupValue)
{ SlxConnection conn = new SlxConnection("Dev64", "SalesLogix_Eval", "Admin", "Admin");
List<Account> accounts = new List<Account>();
using (OleDbConnection connection = new OleDbConnection(conn.ToString()))
{
connection.Open();
string query = string.Format("select Account, IsNull(MainPhone,'') from Account where Account Like '{0}' order by Account", lookupValue);
OleDbDataAdapter adapter = new OleDbDataAdapter(query, connection);
DataTable table = new DataTable();
adapter.Fill(table);
if (table.Rows.Count > 0)
{
foreach (DataRow row in table.Rows)
{
Account account = new Account() { Name = (string)row[0], Phone = (string)row[1] };
accounts.Add(account);
}
}
}
return accounts;
}
Note that the SlxConnection class is nothing more then a specialized connection builder ensuring a proper provider based connection. You can use the actual connection string in the constructor of the OleDbConnection as well.
Adding the Service Reference
To access the web service I needed to add a service reference in the Silverlight project. I selected to add a ‘Solution based’ reference and when completed all of the proxy objects were created.
This step was the most confusing for me initially as I tried different ways to add a reference and most for me did not work. I finally was able to add the reference and use the Soap method to get the results I was expecting. Not that this is a problem with the implementation but with my current understanding on how everything works.
Wiring up the Search Button
Finally I was ready to wire up the search button. Every service call now seems to be ASYNC by default which is a good thing. So basically I new’d up instance of the AccountLookupSoapClient proxy that was created for me when I added a Service Reference.
ServiceReference1.AccountLookupSoapClient client = new ServiceReference1.AccountLookupSoapClient();
Next was to wire up the Async handler. Pretty simple type
client.GetAccountCompleted +=
And the ‘Add Event Handler’ auto complete starts, after hitting Tab, Tab and empty stub was available for me to add the code.
Then the code for actually making the WS call was added
client.GetAccountAsync(searchValue.Text);
Result Handler
When the Async call comes back the handler is called and on the UI thread so to populate the data in the grid all that was required was a check for an error and to set the grids ItemSource to the result.
The final code for the Silverlight page is;
private void Button1_Click(object sender, RoutedEventArgs e)
{ ServiceReference1.AccountLookupSoapClient client = new ServiceReference1.AccountLookupSoapClient();
client.GetAccountsCompleted +=
new EventHandler<TestingSilverlight.ServiceReference1.GetAccountsCompletedEventArgs>(client_GetAccountsCompleted);
client.GetAccountsAsync(searchValue.Text);
}
void client_GetAccountsCompleted(object sender, TestingSilverlight.ServiceReference1.GetAccountsCompletedEventArgs e)
{
if (e.Error == null)
{
Account[] accounts = e.Result;
myGrid.ItemsSource = accounts;
}
}
Run the application and Presto …
– Mark