I discovered this amazing feature almost by accident and it has made this one part of my design so much easier that I had to share it.
A new feature in Silverlight 4 is the ability to using the StringFormat feature when binding. Previously, if I wanted to have a piece of text that said “Your name is [username]” I could either use the old Horizontal-Stack-Panel-And-2-TextBlocks trick (as seen below)… <StackPanel Orientation=”Horizontal”> <TextBlock Text=”Your name is” Margin=”0,0,4,0″/> <TextBlock Text=”{Binding username}“/> </StackPanel>
…or write a value converter (not going to be seen below because there’s a great example of it over here. Incidentally, that example is totally irrelevant if you’re going to use StringFormat, but more on that in a second).
The StringFormat option in Silverlight 4 allows you put all that information into a single field, which is extremely useful not only for TextBlocks, but for Content fields in a Button. In fact, let’s use that as an example.
Let’s say you want to create a Button to log out, so you want it to say “Log Out of <Username> Account”. (A bit clumsy, but the technique is the important part.) All you would have to do is the following:
<Button Content=”{Binding username, StringFormat=’Log Out of \{0\} Account’}“/>
This gets even better for things like number formatting. Let’s say we want the user to enter an amount of money (for example, $1,593.29) into a TextBox (maybe in a PayPal application). If we have bound that value to a numeric format, we can express that format through binding and when the TextBox loses focus, the StringFormat will take the number entered and format in a currency format.
The only issue with numerical and date formats is they the MUST be bound to a number or date.
With that in mind, here is a sampling of StringFormat options, stolen mostly from Kathy Kam. For more complete options, check out the MSDN articles on String.Format and trial-and-error your way through things. If you want to play around with this, download my StringFormat project or look at the Silverlight sample app at the bottom of this page.
Strings
For a string with the value “Silverlight”
Using \{0\,#\} effectively forces the string to be at least # characters long, using spaces to pad it to the requested length.
StringFormat=\{0\,20\} : “ Silverlight” StringFormat=\{0\,-20\} : “Silverlight ” StringFormat=’I just typed "\{0\}".’ : “I just typed “Silverlight”.”
StringFormat=c : “$38,293.53” – Use ‘c’ for currency StringFormat=e : “3.829353e+004” – Use ‘e’ for exponential (scientific) StringFormat=n : “38,293.53” – Use n for number
You can also use these in the following format:
\{0:(letter)(number)\}
where (number) indicates how many decimal places there should be. The format will use standard rounding rules to determine the last digit. For example:
StringFormat=\{0:c0\} : “$38,294” StringFormat=\{0:n4\} : “38,293.5300” StringFormat=You have \{0:c1\} : “You have $38,293.5”
You can either use a set of standard formats (standard formats)… StringFormat=f : “Saturday, April 17, 2004 1:52 PM” StringFormat=g : “4/17/2004 1:52 PM” StringFormat=m : “April 17” StringFormat=y : “April, 2004” StringFormat=t : “1:52 PM” StringFormat=u : “2004-04-17 13:52:45Z” StringFormat=o : “2004-04-17T13:52:45.0000000”
… or you can create your own date formatting using letters (custom formats)
Information visualization is a powerful medium for the communication of data, but one of the things that makes it so powerful is the fact that it plays a part in the larger story of reality. Information visualizations can tell the part of the story that is data heavy in a way that is gripping and memorable. The first half of my chapter walks through the process of creating a visualization and the importance of anchoring that visualization in the context of a larger story (including some thought-experiment examples).
The second half of the chapter walks through the entire process of creating an information visualization, from data gathering to munging (sorting, filtering, re-aligning) a large data set, to visual representation. This visualization is done using Microsoft Excel (you could use Google Docs, which is free) and Adobe Photoshop (you could use GIMP, which is free).
Finally, if you’re one of those people who is constantly thinking “I really wish I could financially support someone who is soooooo awesome that they put their professional work online for free”, today is your lucky day. You can donate whatever you would like directly to me as a thank you via PayPal.
But, most of all, read my chapter! Comment on it, tear it to shreds, pick out the good parts, pick out the bad parts, print it out and light it on fire. I hope it will be helpful in whatever you’re doing.
This is meant to be the one-stop-shop blog post for creating a very simple web service in PHP that pulls from a MySQL database and displaying the data in Silverlight. Emphasis on the “simple”. Here is an example of the finished product (I reserve the right to clean up the data on a regular basis):
In Part 1, we created the MySQL tables necessary to store data for a simple to-do list. In Part 2, we wrote a PHP service to deliver the items in our to-do list in JSON format. In Part 3, we’ll create a Silverlight application that can utilize this web service to retrieve, display, and edit the to-do list.
Part 3: Connecting Silverlight To Our PHP Web Service
First, let’s start a new Silverlight project. (You can download the full project here.) In the interest of time, I’m not going to go into the details of the “ideal” implementation for this. I’m just going to show the parts necessary to retrieve, display and interact with the to-do data.
Before we start with the UI, let’s build a model so that we can appropriately bind our data. Add a new folder to the Silverlight project and name it “Models”. Add a new class to it and name the class “ToDoItem.cs”. In this instance, we’re just going to make the model look just like our MySQL table.
Now, we’ll add to our MainPage.xaml a ListBox named “ToDoList” that will hold the to-do items and a Grid to house the UI to add a new to-do. We’ll work on gathering and displaying our items first.
Right-click on the ListBox and go to “Edit Additional Templates –> Edit Generated Items (ItemTemplate) –> Create Empty…”
You’ll love this part… Just add a checkbox to it. That’s all we’ll need, so that’s all we’ll add. Then, go into the XAML and make the checkbox look like this:
This binding is all we’ll need once we gather our to-dos from the web service and attach it to the ListBox. Let’s go ahead and get that data into this ListBox.
Open MainPage.xaml.cs and, at the top of the class, add:
You may have to add “using System.Net;” and “using System.Collections.ObjectModel;” to the top of the file. While we’re adding references, right-click on the “References” folder and find the “System.Json” component and add it to the project. Then add “using System.Json;” to the references section in the top. It’ll come in handy in a minute.
In the MainPage() method under InitializeComponent(), type “wc.DownloadStringCompleted += “ and hit TAB twice. This will add an event handler for when the WebClient has finished connecting to the web service we wrote.
The resulting event handler (which should be named “wc_DownloadStringCompleted”), is the code that our application will go to whenever it makes a call to our web service and gets a result. In it, we will do the following things:
Check to make sure we got a result without error
Check to see what kind of result we got (did we get all to-do items? or add a new to-do item?)
Walk through the result, extracting the data we need
Apply that data to the UI
Let’s add the code to do that for getting all the items. Make your event handler look like this:
int isDoneInt = Convert.ToInt32(todoItemJson["IsDone"].ToString().Replace(‘”‘, ‘ ‘).Trim());
if(isDoneInt == 0){
thisTodo.isDone = false;
} elseif (isDoneInt == 1){
thisTodo.isDone = true;
}
}
myToDoList.Add(thisTodo);
}
ToDoList.ItemsSource = myToDoList;
}
}
}
With this in place, all we need to do is make a call to the get_todo_items.php, which we can do by adding this code just below the wc.DownloadStringCompleted line in the MainPage() method.
When we run the project, we should get all objects from our database and the results should show up just the way we want in our Silverlight application. We will follow the exact same model to add new to-do items and update the to-do items we already have.
I’m in the process of separating out the final part of this tutorial (adding and updating the items) into a supplemental post so that I can wrap this post up. I encourage anyone walking through this to try to complete those parts by yourself and refer to the last bit only if you get stuck.
Finally, a little bit of warning. I structured this project to get it working in as straightforward a manner as possible. It is not in any way the ideal architectural example for a data-driven Silverlight application. It’s just a good way to get started using Silverlight in an environment that isn’t 100% Microsoft technologies.
This is meant to be the one-stop-shop blog post for creating a very simple web service in PHP that pulls from a MySQL database and displaying the data in Silverlight. Emphasis on the “simple”.
Here is an example of the finished product (I reserve the right to clean up the data on a regular basis):
In Part 1, we created the MySQL tables necessary to store data for a simple to-do list. In Part 2, we’ll write some PHP code that will give us the ability to grab the data out of the database and send it, in JSON format, to our Silverlight application.
We’ve added the to-do table and column names so that, if we decide to change anything later, we can just go to this file and update the table or column once.
Just for good measure, we’ve added a function we’ll want to use across our php files. The function “formatInput” will be used to make sure all our data is decoded from the URL that calls our web service (the urldecode method) and then try to block any SQL injections (the mysql_real_escape_string method).
Now, let’s write the basic “Get the data” file. What we’re going to do is write it so that the we can choose to get:
all the to-do items
all the to-do items that are “done”
all the to-do items that are “not done”
This range of functionality isn’t even close to ideal. In a perfect world, we would want a wider range of options in gathering items (for example, items that contain a certain word or one item in particular or limit the number of items we call by a date range). However, for our very simple purposes, this will do.
The way our web service will work is that we have a URL that we’ll call from Silverlight when we want to get some data. When we calls this web service, we may want only the “not done” items or only the “done” items. We’ll handle that option by adding “?itemStatus=done” or “?itemStatus=notDone” to the end of the URL.
will get all the to do items that are complete. So we need to make sure that our web service responds appropriately to both calls.
There are comments in the code, but I’ll just explain the basic concept in picture form:
We take in a URL, extract the variables from it, create the MySQL query based on the variables, execute the MySQL query, extract the results, and then send back the php object encoded as a Json object. Each one of our files will follow this same pattern.
get_todo_items.php
<? include‘mysql_vars.php’;
// set up the “itemStatus” URL option and build a query addition
// to account for the itemStatus variable $itemStatus = $_GET['itemStatus'];
$itemQueryAddition = “”;
// … then encode the results as JSON Text…
// we’re using a “returnType” field so that our Silverlight application can differentiate between
// the kind of return values it recieves and parse the Json object appropriately
// … and print the results so that our app can read them echo $JSONResult; ?>
The other two files, add_todo_item.php and change_status.php use exactly the same structure to add a new item and change the status of an existing item (respectively). I won’t put all the code here in this post that is already too long, but you can download all the files here.
Update the mysql_vars.php file to fit your needs and you should be able to just upload these files and have your running to-do web service all ready for Silverlight to call it for data, which is something we’ll deal with in Part 3.
This is meant to be the one-stop-shop blog post for creating a very simple web service in PHP that pulls from a MySQL database and displaying the data in Silverlight. Emphasis on the “simple”. This tutorial is geared toward someone who has never done databases or web services.
Here is an example of the finished product (I reserve the right to clean up the data on a regular basis):
This tutorial will walk through the steps to create a simple to-do list. Our to-do list will hold text of what it is we need to do and a value indicating if the task has been done. In this tutorial, we will create a MySQL table to hold our data, a PHP service to call the data and a Silverlight application to display and interact with the data.
First, let’s create the table we need for our data.
If you don’t have or don’t like phpMyAdmin, the MySQL query to create the table described below is:
CREATE TABLE `[your_database_name]`.`to_do_data` (
`index_key` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`is_done` TINYINT( 4 ) NOT NULL DEFAULT ’0′,
`to_do_text` TEXT NOT NULL ,
FULLTEXT ( `to_do_text` )
) ENGINE = MYISAM
If you have phpMyAdmin, I highly suggest using it if you’re a MySQL novice. In phpMyAdmin, go to your database and enter the name of the table you want to create in the “Create new table on database [your_db_name]” section.
We’ll call our table “to_do_data” and give it 3 fields.
index_key – identifies the to-do item uniquely
is_done – true/false value indicates the status of the to-do item
to_do_text – a short text to describe what needs to be done
In phpMyAdmin, it will look like this:
A couple of notes about the fields:
index_key
This is the primary key of the table and is used to uniquely identify the given row. As such, it cannot be null and it auto-increments as rows are added to the table.
is_done
We use “TINYINT” type for this value because using BOOLEAN is basically the same thing. It is not null because every item must either be “done” or “not done”. “Done” = true = 1 and “not done” = false = 0. We are going to default to “0” (false) because we’re assuming that users aren’t going to make a to do list of stuff that is already complete.
to_do_text
We have artificially limited the text size to 1024 because we assume that this will be a set of short to-dos to, not a set of journal entries. We’ve also turned on “Fulltext” which lets the MySQL database index our entries for quick searching.
Now we just click the “Save” button at the bottom and we have our table.
Now our database system is in place and we’re ready to write a PHP webservice to implement all the CRUD (create, read, update, delete) capabilities our system will need.
If you want to learn more about MySQL, I highly recommend “A Visual Introduction to SQL“. This is the book I have, a left-over of my grad school years and it is an exceptional book for picking your way through various database scenarios.
If you’re looking for something a bit less costly, “MySQL Crash Course” is a fine book on the subject as well.
If you’re interested in government transparency, there is not better organization to watch than the Sunlight Foundation, a non-profit organization that is leading the charge to more government transparency through the release, organization and visualization of government data and processes.
Every once in a while, Sunlight Foundation runs contests to either visualize or interact with government data. I submitted a Silverlight project called “Recovery Review” for the latest contest, “Design for America”. With Recovery Review, users can search and visualize stimulus projects. If they find information that they think is inaccurate, they can flag that project for inaccurate information.
The idea behind the visualization is that users can search through the data using a couple of key points (how much money was awarded to a project, where the project is, how many jobs were reported as “saved or created” due to the project, etc) and the system will deliver in a visual format a set of results that match that search. It will also visualize (as seen above) the total of all awards that match that search in the context of the stimulus awarded as a whole.
If the user clicks on the on one of the projects in the list, the visualization resizes so the user can see how much money and how many jobs that individual project represents, both in relation to the search total and in relation to the total stimulus.
Here’s a video overview of the project (runs about 8 mins).
Looking at the competition, I find it unlikely that I will win, but building the project was a pretty exciting learning experience. I’ll be posting my lessons here in the next couple weeks.