Social Icons

twitterfacebookgoogle pluslinkedinrss feedemail

Monday, November 29, 2010

Silverlight Tips, Tricks, Tutorials and Links Page

Getting Started Tutorials

  • Silverlight 2 End to End Tutorial: Digg Sample: I recommend reading this post first if you are looking to get started with Silverlight 2 development for the first time.  It not only describes the high-level of what Silverlight 2 provides, but also links to a series of 8 blog posts that walkthrough building a Digg client sample application.  These tutorial posts provide a good introduction to Silverlight 2 and WPF development concepts. 
  • First Look at Using Expression Blend with Silverlight 2: I recommend downloading the Expression Blend 2.5 March preview and following along with this tutorial post.  I think it does a good job of showing off some of the common features of Expression Blend, and uses it to build an IM chat client sample.
  • Jesse Liberty Silverlight Tutorials: Jesse Liberty is writing an in-depth series of articles that cover Silverlight programming concepts in more depth.  Bookmark this page and check back frequently to read them as they get published (he also has PDF versions of each article that you can download and read offline).

Getting Started Presentations

  • My Getting Started with Silverlight Talk: You can download the slides + samples from my "Getting Started with Silverlight 2" talk that I recently gave in Arizona.  Feel free to re-use the slides however you want for your own presentations.

Documentation Links

Tutorials and Samples

  • Using Deep Zoom with Silverlight 2: Jacek Ciereszko has a nice blog post that describes how to use the "Deep Zoom" feature of Silverlight 2 to implement image zoom functionality like with the Hard Rock sample.

Deployment

User Controls

ListBox and ScrollViewer

DataGrid

  • Using Silverlight 2's DataGrid with WCF + LINQ to SQL: This 15 minute video blog demonstrates how to build a LINQ to SQL object model on the server and publish it using WCF.  It then demonstrates how to build a Silverlight client that uses the new Silverlight DataGrid control, and which calls the WCF service to retrieve the LINQ to SQL data to populate it with.
  • Simple Editing of Web Service Data in a DataGrid: Mike Taulty has a nice blog post that shows how to create a WCF service on the server, and then use it from a Silverlight 2 client to retrieve data, bind it to a DataGrid, allow users to update rows, add/delete rows, and then save it back to the server using Silverlight 2 Beta1.
  • Sorting with Silverlight 2's DataGrid Control: The DataGrid control in Silverlight 2 Beta1 doesn't yet have built-in column sorting support (it is coming in Beta2).  That hasn't stopped Matt Berseth though!  In this post he shows how to implement sorting using a custom header column approach.  Also check out Matt's post here, which provides a DataGrid test page that shows off a number of the current DataGrid features.

Control Templates

Web Services and Networking

  • Web Services and Silverlight: This helpful post discusses how to use web-services with Silverlight and links to relevant quickstart samples and documentation.

HTML Integration

  • Silverlight Interop with HTML: Wilco Bauwer has a great post on the HTML and JavaScript integration features enabled by Silverlight 2 (he should know all about them - since he was the developer who built them!).

Unit Testing

  • Unit Testing with Silverlight 2: This post of mine talks about how to unit-test Silverlight 2 applications using the unit test framework in the Silverlight SDK.

Video Scenarios

Accessibility and 508 Compliance

  • Accessibility in Silverlight 2: Mark Rideout from the Silverlight team talks about accessibility support with Silverlight 2, and talks about how you'll be able to build section 508 and accessible solutions using Silverlight.

Sunday, November 28, 2010

Silverlight Tutorial Sites

Silverlight tutorial sites in alphabetical order:

Author/SiteLink
Andy Beauliuehttp://www.andybeaulieu.com/Home/tabid/67/Default.aspx
Brad Adamshttp://blogs.msdn.com/brada/default.aspx
Chris Hayhttp://www.screencast.com/users/chrishayuk
DotNet Curryhttp://www.dotnetcurry.com/
Jesse Libertyhttp://silverlight.net/blogs/jesseliberty/
Joe Stegmanhttp://blogs.msdn.com/jstegman/default.aspx
Nikola Mihaylovhttp://blogs.msdn.com/nikola/default.aspx
Page Brookshttp://pagebrooks.com/
Pete Brownhttp://community.irritatedvowel.com/blogs/pete_browns_blog/default.aspx
Shawn Wildermuthhttp://wildermuth.com/
Silverlight Learning Resourceshttp://silverlight.net/learn/
SilverlightShowhttp://www.silverlightshow.net/
Terence Tsanghttp://www.shinedraw.com/
Tim Heuerhttp://timheuer.com/blog/
Timmy Kokkehttp://geekswithblogs.net/tkokke/Default.aspx

Also, here is a great Silverlight Blog summary page: http://www.netvibes.com/rboarman#Silverlight

Silverlight : How to Declare a Custom User Control from a XAML Page

How to Declare a Custom User Control from a XAML Page.

UserControls are a great way to separate objects into smaller, more manageable chunks of logic. These controls can reused by different applications and are independent from other controls. Each UserControl can contain any amount of content and logic and can be directly added to your Canvas tree (I.e. MyCanvas.Children.Add(myControl)).
Once you have a UserControl created, how do you reference or declare it from another XAML file (such as Page.xaml)? Doing this is relatively straight forward and we will demonstrate how to do this in this tutorial.
Run this application here to preview: http://silverlight.services.live.com/invoke/66033/Custom%20UserControl/iframe.html
To start, let’s create a custom UserControl called “Card”. In Visual Studio 2008, Right click on your Silverlight Application and choose “Add->New Item…”.
image
In the Add New Item dialog, choose “Silverlight User Control” and change the name to “Card.xaml”.
image
Add the following two images to your Silverlight application project:
CardDiamond3.png                           CardHeartAce.png
image          image
Now, open up Card.xaml and:
  1. Add an Image in the UserContol.
  2. Set the “x:Name” of the Image to “CardImg”.
  3. Set the source default value to”CardHeartAce.png”
  4. Remove the controls Width, Height and Grid tags as they are not needed. Your Card.xaml should now look like this:
"UserCtrl.Card"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
"CardImg" Source="CardHeartAce.png">
Next we want to give users the ability to change the image of the card. Open Card.xaml.cs and add the following code which will allow the user to change the image:
namespace UserCtrl
{
public partial class Card : UserControl
{
public Card()
{
InitializeComponent();
}
 
public ImageSource CardImage
{
get { return CardImg.Source; }
set
{
this.CardImg.Source = value;
}
}
}
}
Our final step is to show you how to reference this UserControl from a xaml file such as Page.xaml.
In Page.xaml:
  1. Add a local reference to your Page.xaml UserControl which will allow you to reference objects in your assembly: 

    <
    UserControl x:Class="UserCtrl.Page"     xmlns=http://schemas.microsoft.com/winfx/2006/xaml/presentation      xmlns:x=http://schemas.microsoft.com/winfx/2006/xaml      xmlns:local="clr-namespace:UserCtrl;assembly=UserCtrl"      Width="480" Height="300" > 
  2. Declare a couple references to your Card control like this: 

    "UserCtrl.Page"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:local="clr-namespace:UserCtrl;assembly=UserCtrl" 
    Width="480" Height="300" >
    "MyCanvas" Background="Gray">
     
    "50" Canvas.Top="20" x:Name="MyCard" CardImage="CardDiamond3.png" >
     
    "250" Canvas.Top="20" x:Name="MyCard2" CardImage="CardHeartAce.png" >
     
  3. Run the application and you will see two cards are shown! 

    image  
Thank you,

Parsing XML Files

Introduction
NSXMLParser is a forward only reader or an event driven parser. What it means is, an event is raised whenever the parser comes across a start of an element, value, CDATA and so on. The delegate of NSXMLParser can then implement these events to capture XML data. Some of the events are raised multiple times like the start of an element, value of an element and so on. Since NSXMLParser is known as an event driven parser, we can only read data at the present node and cannot go back. The iPhone only supportsNSXMLParser and not NSXMLDocument, which loads the whole XML tree in memory.

Books Application
To understand how to use an instance of NSXMLParser, let's create a simple navigation based application where we will list the title of the book in the table view and upon selecting a title, display the detail information in a detail view. Click here to see the sample XML file, used in this application.

Create a new application in XCode by selecting Navigation-Based Application, I have named my app XML. Since the NSXMLParser is a forward only parser or an event driven parser, we need to store the data locally, which can be used later. To store this data, we will create a class which replicates the elements and attributes in the XML file. An instance of this class represents one single Book element in the XML file. I have named this class "Book" and its source code is listed below

//Book.h
#import

@interface Book : NSObject {

NSInteger bookID;
NSString *title; //Same name as the Entity Name.
NSString *author; //Same name as the Entity Name.
NSString *summary; //Same name as the Entity Name.

}

@property (nonatomic, readwrite) NSInteger bookID;
@property (nonatomic, retain) NSString *title;
@property (nonatomic, retain) NSString *author;
@property (nonatomic, retain) NSString *summary;

@end

//Book.m
#import "Book.h"

@implementation Book

@synthesize title, author, summary, bookID;

- (void) dealloc {

[summary release];
[author release];
[title release];
[super dealloc];
}

@end


Notice that the name of the property is the same as the element name in the XML file. Since the XML file has n number of Book elements, we need an array to hold all the books we read, so we declare an array in the application delegate and this is how the source code changes


//XMLAppDelegate.h
#import

@interface XMLAppDelegate : NSObject {

UIWindow *window;
UINavigationController *navigationController;

NSMutableArray *books;
}

@property (nonatomic, retain) IBOutlet UIWindow *window;
@property (nonatomic, retain) IBOutlet UINavigationController *navigationController;

@property (nonatomic, retain) NSMutableArray *books;

@end


The Delegate
To keep the source code clean, we will also declare a delegate, which will be used by the instance ofNSXMLParser and this how its source code looks like


//XMLParser.h
#import

@class XMLAppDelegate, Book;

@interface XMLParser : NSObject {

NSMutableString *currentElementValue;

XMLAppDelegate *appDelegate;
Book *aBook;
}

- (XMLParser *) initXMLParser;

@end


Let's look at how the variables will be used. currentElementValue holds the current element value, appDelegate so we can access the array which holds the list of books and finally a reference to the Book class itself. Notice that we do not keep track of the current element name being processed, because the event will tell us that. Finally, we have a constructor called initXMLParser and let's see what it does


//XMLParser.m
- (XMLParser *) initXMLParser {

[super init];

appDelegate = (XMLAppDelegate *)[[UIApplication sharedApplication] delegate];

return self;
}


Very simple, gets a reference to the application delegate and returns itself.


Parsing the XML File
Now that we have everything set up, let's look at the code to read the XML file


//XMLAppDelegate.m
- (void)applicationDidFinishLaunching:(UIApplication *)application {


NSURL *url = [[NSURL alloc] initWithString:@"http://sites.google.com/site/iphonesdktutorials/xml/Books.xml"];
NSXMLParser *xmlParser = [[NSXMLParser alloc] initWithContentsOfURL:url];

//Initialize the delegate.
XMLParser *parser = [[XMLParser alloc] initXMLParser];

//Set delegate
[xmlParser setDelegate:parser];

//Start parsing the XML file.
BOOL success = [xmlParser parse];

if(success)
NSLog(@"No Errors");
else
NSLog(@"Error Error Error!!!");

// Configure and show the window
[window addSubview:[navigationController view]];
[window makeKeyAndVisible];
}


The code is very simple, we create an instance of NSURL, create an instance of NSXMLParser, initialize the delegate, assign the delegate and start parsing by passing the parse message. It returns YES, if the parsing is successful, NO if there is an error or if the operation is aborted.

Parsing the start of an element

The delegate of the parser does not have to implement all the methods that it raises, so we can pick and choose which events we care about. If we do not want to handle the event when the parser starts reading the document, we can choose to ignore it by not implementing it. We will only implement three methods which is called when the parser encounters the start of an element, end of an element or value of an element.


Let's look at parser:didStartElement:namespaceURI:qualifiedName:attributes method which is called when the parser encounters the start of an element.


//XMLParser.m
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName
attributes:(NSDictionary *)attributeDict {

if([elementName isEqualToString:@"Books"]) {
//Initialize the array.
appDelegate.books = [[NSMutableArray alloc] init];
}
else if([elementName isEqualToString:@"Book"]) {

//Initialize the book.
aBook = [[Book alloc] init];

//Extract the attribute here.
aBook.bookID = [[attributeDict objectForKey:@"id"] integerValue];

NSLog(@"Reading id value :%i", aBook.bookID);
}

NSLog(@"Processing Element: %@", elementName);
}


From the above code we first initialize the array when it encounters the "Books" element, which can also be done in parserDidStartDocument method. If the element is "Book" then we initialize the local book object and read the attribute of the present XML book element from the attribute dictionary object.


Parsing an element's value
Now that we have a local book object representing the current book element in the XML tree, the next thing to do is to populate the local object with the XML data. The parser now moves to the title element and the same method is called again, but this time we do not do anything. Parser then moves to the element value and it sends parser:foundCharacters event to the delegate, let's see how the code look like


//XMLParser.m
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {

if(!currentElementValue)
currentElementValue = [[NSMutableString alloc] initWithString:string];
else
[currentElementValue appendString:string];

NSLog(@"Processing Value: %@", currentElementValue);

}


The code is very easy to read, if the mutable string is nil then we initialize it with the string parameter. If the currentElementValue is not nil then we simply append the data to the existing string value.


Parsing the end of an element
The parser now moves to the end of the element and henceparser:didEndElement:namespaceURI:qualifiedName is sent to the delegate. This is where we set the currentElementValue to the correct property of the local book object and set the currentElementValue to nil. This is how the code looks like


//XMLParser.m
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {

if([elementName isEqualToString:@"Books"])
return;

//There is nothing to do if we encounter the Books element here.
//If we encounter the Book element howevere, we want to add the book object to the array
// and release the object.
if([elementName isEqualToString:@"Book"]) {
[appDelegate.books addObject:aBook];

[aBook release];
aBook = nil;
}
else
[aBook setValue:currentElementValue forKey:elementName];

[currentElementValue release];
currentElementValue = nil;
}


If the element it encounters is "Books" then there is nothing to do as we are almost done reading the file. If the element name is "Book" then we add the book object to the array and set the local book object to nil and release its memory, so it can be used again. If the end element is not "Books" or "Book" then it must be one of the sub element of "book" and we set the currentElementValue to the current book property usingsetValue:forKey. We can do this, because the properties declared in the book is the same as the XML element names.


The cycle starts again by initializing the book object and reading the attribute, reading the children elements and setting its value to the local object and finally adding the object to the array. The parser calls the three functions again and again as long as it does not encounters eof.


Complete listing of XMLParser.m file


//XMLParser.m
#import "XMLParser.h"
#import "XMLAppDelegate.h"
#import "Book.h"

@implementation XMLParser

- (XMLParser *) initXMLParser {

[super init];

appDelegate = (XMLAppDelegate *)[[UIApplication sharedApplication] delegate];

return self;
}

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName
attributes:(NSDictionary *)attributeDict {

if([elementName isEqualToString:@"Books"]) {
//Initialize the array.
appDelegate.books = [[NSMutableArray alloc] init];
}
else if([elementName isEqualToString:@"Book"]) {

//Initialize the book.
aBook = [[Book alloc] init];

//Extract the attribute here.
aBook.bookID = [[attributeDict objectForKey:@"id"] integerValue];

NSLog(@"Reading id value :%i", aBook.bookID);
}

NSLog(@"Processing Element: %@", elementName);
}

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {

if(!currentElementValue)
currentElementValue = [[NSMutableString alloc] initWithString:string];
else
[currentElementValue appendString:string];

NSLog(@"Processing Value: %@", currentElementValue);

}

- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {

if([elementName isEqualToString:@"Books"])
return;

//There is nothing to do if we encounter the Books element here.
//If we encounter the Book element howevere, we want to add the book object to the array
// and release the object.
if([elementName isEqualToString:@"Book"]) {
[appDelegate.books addObject:aBook];

[aBook release];
aBook = nil;
}
else
[aBook setValue:currentElementValue forKey:elementName];

[currentElementValue release];
currentElementValue = nil;
}

- (void) dealloc {

[aBook release];
[currentElementValue release];
[super dealloc];
}

@end


This is how the data looks like in the table view and the detail view controller.



The data is then shown in a UITableView with a detail view, the complete code is not shown here but you can download the source code and to get a better understanding UITableView, you can follow my suggested readings below.

Summary
Reading XML files is very easy and it can be done with only three methods as seen above. I hope this tutorial has got you started in reading XML files. 

New In iPhone 3.0 Tutorial Series, Part 2: In App Email, MessageUI


This time, we’ll add in-app email to a simple iPhone application using the new-in-3.0 MessageUI framework.
Technically neither mail from an app nor MessageUI are new. MessageUI was a private framework prior to 3.0, and apps could send mail using mailto:// URLs, though in a limited way.
In any case, with 3.0 and MessageUI, sending messages is straightforward and full featured.
We’ll start with working code for a simple app with a UI containing a single button. We’ll add code that shows the compose-an-email message UI and pre-fills the subject and content when the button is pressed.
Source/GitHub
The code for this tutorial is available on GitHub. To download a copy for yourself, close the repository:
  1. Open a terminal and change to the directory where you want the code
  2. Clone the repo by typing git clone git://github.com/dcgrigsby/InAppEmail.git
I’ve made two separate commits to the repository — an initial commit without in-app email, and a second one with those capabilities added. If you’re following along step-by-step, you’ll want to revert to the earlier commit. From the source directory:
  1. Type git checkout 0019071d855e6d3a9f263b8a02d9c7d93dc5dcd2
Orientation
InAppEmail is about as simple an application as it’s possible to construct. The single “Send Email” button — which is disabled, for now — triggers the buttonPressed message when pressed.
Adding The MessageUI Framework
As part of the MessageUI Framework, Apple provides a ready-made compose-a-message UI called MFMailComposeViewController for our use. In order to use it, we need to add the MessageUI Framework to our project:
  1. In the Groups & Files panel of the project, expand the InAppEmail project branch
  2. Control-click or right-click the Frameworks folder
  3. Choose Add > Existing Frameworks…
  4. Expand the Frameworks folder
  5. Choose MessageUI.framework and click Add
  6. Click Add once more
Next, import the framework in the header:
  1. Add #import  to InAppEmailViewController.h
Showing The MFMailComposeViewController UI
MFMailComposeViewController is just like any other view controller; we can usepresentModalViewController from our InAppEmailViewController class to slide it onto the screen modally.
Replace the puttonPressed method in InAppEmailController.m with this:
- (IBAction)buttonPressed {
MFMailComposeViewController *controller = [[MFMailComposeViewController alloc] init];
[controller setSubject:@"In app email..."];
[controller setMessageBody:@"...a tutorial from mobileorchard.com" isHTML:NO];
[self presentModalViewController:controller animated:YES];
[controller release];
}
Running the app in its current form would be disappointing. The “Send Email” message button is disabled. It’s a simple matter to enable it but, but we should do so only if the iPhone or iPod touch the app is running on has been configured to send mail. To do so, add code for aviewDidLoad method to InAppEmailViewController.m:
- (void)viewDidLoad {
if ([MFMailComposeViewController canSendMail])
button.enabled = YES;
}
Dismissing the MFMailComposeViewController UI
We’re most of the way there. Run the app at this juncture and it mostly works: clicking the button brings up the compose UI pre-filled with our sample message. Add an email address in the “To” field and away you go — mostly:
We’re missing one piece: we need to know when to dismiss the mail composer UI. TheMFMailComposeViewControllerDelegate protocol provides a callback mechanism to accomplish this.
To receive the callback, we’ll need:
  1. Adopt the protocol in our InAppEmailViewController
  2. Set ourselves up as the delegate to receive the callbacks
  3. Implement the callback method
To adopt the protocol update InAppEmailViewController.h. Changes are bold:
#import 

@interface InAppEmailViewController : UIViewController {
IBOutlet UIButton *button;
}

- (IBAction)buttonPressed;

@end
To set ourselves up as the delegate to receive the callbacks update buttonPressed in InAppEmailViewController.m. Changes are bold:
- (IBAction)buttonPressed {
MFMailComposeViewController *controller = [[MFMailComposeViewController alloc] init];
controller.mailComposeDelegate = self;
[controller setSubject:@"In app email..."];
[controller setMessageBody:@"...a tutorial from mobileorchard.com" isHTML:NO];
[self presentModalViewController:controller animated:YES];
[controller release];
}
Finally, we implement the callback method. Add this code for amailComposeController:didFinishWithResult:error: method to InAppEmailViewController.m:
- (void)mailComposeController:(MFMailComposeViewController*)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError*)error {
[self becomeFirstResponder];
[self dismissModalViewControllerAnimated:YES];
}
Conclusion
That covers the basics. This tutorial doesn’t demonstrate setting recipients, adding attachments, or composing HTML email — all of which are straightforward once you’ve got the basics down.
Finally, one limitation that’s worth noting: you can’t force a user to send mail; they can always click the cancel button.
There was an error in this gadget
 
Get Twitter Fan Box Widget

Like Us On Facebook and Receive All Updates!

You can also receive Free Email Updates:

Powered By Tutorails

Followers