JSON (JavaScript Object Notation) is a lightweight data-interchange format. It is easy for humans to read and write. It is easy for machines to parse and generate. It is based on a subset of the JavaScript Programming Language, Standard ECMA-262 3rd Edition - December 1999. JSON is a text format that is completely language independent but uses conventions that are familiar to programmers of the C-family of languages, including C, C++, C#, Java, JavaScript, Perl, Python, and many others. These properties make JSON an ideal data-interchange language.
JSON is built on two structures:
A collection of name/value pairs. In various languages, this is realized as an object, record, struct, dictionary, hash table, keyed list, or associative array.
An ordered list of values. In most languages, this is realized as an array, vector, list, or sequence.
These are universal data structures. Virtually all modern programming languages support them in one form or another. It makes sense that a data format that is interchangeable with programming languages also be based on these structures.
In JSON, they take on these forms:
An object is an unordered set of name/value pairs. An object begins with { (left brace) and ends with } (right brace). Each name is followed by : (colon) and the name/value pairs are separated by , (comma).
An array is an ordered collection of values. An array begins with [ (left bracket) and ends with ] (right bracket). Values are separated by , (comma).
A value can be a string in double quotes, or a number, or true or false or null, or an object or an array. These structures can be nested.
A string is a sequence of zero or more Unicode characters, wrapped in double quotes, using backslash escapes. A character is represented as a single character string. A string is very much like a C or Java string.
A number is very much like a C or Java number, except that the octal and hexadecimal formats are not used.
Whitespace can be inserted between any pair of tokens. Excepting a few encoding details, that completely describes the language.
Eg:=
object
{}
{ members }
members
pair
pair , members
pair
string : value
array
[]
[ elements ]
elements
value
value , elements
value
string
number
object
array
true
false
null
string
""
" chars "
chars
char
char chars
char
any-Unicode-character-
except-"-or-\-or-
control-character
\"
\\
\/
\b
\f
\n
\r
\t
\u four-hex-digits
number
int
int frac
int exp
int frac exp
int
digit
digit1-9 digits
- digit
- digit1-9 digits
frac
. digits
exp
e digits
digits
digit
digit digits
e
e
e+
e-
E
E+
E-
How to convert XML to JSON in ASP.NET C#
Last modified: 18 July 2006. Any comments or suggestions - please fill in form below. Chris Cant.
No download provided - cut and paste to try out. The following code is provided as-is without any warranty of any kind.
Code to convert XML to JSON in ASP.NET C#
Example of how to insert JSON code into a page when the page is generated
Please acknowledge PHD Computer Consultants Ltd (PHDCC) if you use this code
Please read the comments for suggestions on improvements to the code.
Introduction
JSON is a lightweight data-interchange format. It is particularly useful because it can be 'decoded' easily by web page JavaScript into object form.
AJAX-based web pages use XmlHttpRequest to receive data from a server in response to a user action. While the returned data is normally in XML format, it can also be returned in JSON string format and processed more easily in JavaScript.
Many applications may store information in XML format. However they may want to send data to a client using JSON. To achieve this, they must convert their XML data into JSON format. The ASP.NET C# code below does this job.
Code Description
The code provides a method private static string XmlToJSON(XmlDocument xmlDoc) that converts an XmlDocument into a JSON string. The code iterates through each XML element, its attributes and children, creating the corresponding JSON objects.
The code never generates number or boolean values.
The XML documentElement is always reported as member:object even if it could be shortened by the following rules.
Element attributes are converted into member "attr_name":"attr_value".
XML
JSON
<xx yy='nn'></xx>
{ "xx": {"yy":"nn"} }
<xx yy=''></xx>
{ "xx": {"yy":""} }
Element children with no attributes, children or text are converted into member "child_name":null
XML
JSON
<xx/>
{ "xx":null }
Element children with no attributes or children but contain text are converted into "child_name":"child_text"
XML
JSON
<xx>yyy</xx>
{ "xx":"yyy" }
Other element attributes and children are converted into "child_name":object or an array "child_name":[elements] as appropriate, with element text converted into a member with name "value"
XML
JSON
<xx yy='nn'><mm>zzz</mm></xx>
{ "xx": {"yy":"nn", "mm":"zzz"} }
<xx yy='nn'><mm>zzz</mm><mm>aaa</mm></xx>
{ "xx": {"yy":"nn", "mm": [ "zzz", "aaa" ] } }
<xx><mm>zzz</mm>some text</xx>
{ "xx": {"mm":"zzz", "value":"some text"} }
<xx value='yyy'>some text<mm>zzz</mm>more text</xx>
{ "xx": {"mm":"zzz", "value": [ "yyy", "some text", "more text" ] } }
Characters are made safe for conversion into JSON. Note that this does not protect your JavaScript from attack if any of the source XML comes from an unsafe source, eg user input.
XML
JSON
<aa>/z'z"z\yyy<aa><
{"aa": "\/z\u0027z\"z\\yyy" }
In some special circumstances, such as in the example below, you may need to escape the backslash characters again, eg:
string JSON = XmlToJSON(doc);
JSON = JSON.Replace(@"\", @"\\");
Note that there may be security implications for web pages using unchecked XML contents.
Example
The examples on this page come from my Space Browse site.
XML Input:
<space name="Cake Collage">
<frame>
<photo img="cakecollage1.jpg" />
<text string="Browse my cake space" />
<rule type="F" img="cakecollage9.jpg" x="150" y="0" w="300" h="250" />
<rule type="F" img="cakecollage2.jpg" x="0" y="0" w="150" h="220" />
</frame>
<frame>
<photo img="cakecollage2.jpg" />
<rule type="B" img="cakecollage1.jpg" />
<rule type="L" img="cakecollage3.jpg" />
</frame>
</space>
JSON Output (re-formatted):
{ "space":
{ "name": "Cake Collage",
"frame": [ {"photo": { "img": "cakecollage1.jpg" },
"rule": [ { "type": "F",
"img": "cakecollage9.jpg",
"x": "150",
"y": "0",
"w": "300",
"h": "250"
},
{ "type": "F",
"img": "cakecollage2.jpg",
"x": "0",
"y": "0",
"w": "150",
"h": "220"
}
],
"text": { "string": "Browse my cake space" }
},
{"photo": { "img": "cakecollage2.jpg" },
"rule": [ { "type": "B", "img": "cakecollage1.jpg" },
{ "type": "L", "img": "cakecollage3.jpg" }
]
}
]
}
}
Once the JSON has been converted into a JavaScript object, eg called space_DOM, the following objects are available:
space_DOM.space.name
space_DOM.space.frame.length
space_DOM.space.frame[0].text.string
space_DOM.space.frame[0].rule[0].type
Your JavaScript code should be flexible to cope with members not existing, members existing as a single value, or members existing as an array. I find it useful to have a JavaScript function ObjectToArray which converts all these cases into an Array of length 0, 1 or greater.
function ObjectToArray( obj)
{
if( !obj) return new Array();
if( !obj.length) return new Array(obj);
return obj;
}
space_DOM.space.frame = ObjectToArray(space_DOM.space.frame);
XmlToJSON C# code
You may wish to use some of the updates suggsted in the comments below.
private static string XmlToJSON(XmlDocument xmlDoc)
{
StringBuilder sbJSON = new StringBuilder();
sbJSON.Append("{ ");
XmlToJSONnode(sbJSON, xmlDoc.DocumentElement, true);
sbJSON.Append("}");
return sbJSON.ToString();
}
// XmlToJSONnode: Output an XmlElement, possibly as part of a higher array
private static void XmlToJSONnode(StringBuilder sbJSON, XmlElement node, bool showNodeName)
{
if (showNodeName)
sbJSON.Append("\"" + SafeJSON(node.Name) + "\": ");
sbJSON.Append("{");
// Build a sorted list of key-value pairs
// where key is case-sensitive nodeName
// value is an ArrayList of string or XmlElement
// so that we know whether the nodeName is an array or not.
SortedList childNodeNames = new SortedList();
// Add in all node attributes
if( node.Attributes!=null)
foreach (XmlAttribute attr in node.Attributes)
StoreChildNode(childNodeNames,attr.Name,attr.InnerText);
// Add in all nodes
foreach (XmlNode cnode in node.ChildNodes)
{
if (cnode is XmlText)
StoreChildNode(childNodeNames, "value", cnode.InnerText);
else if (cnode is XmlElement)
StoreChildNode(childNodeNames, cnode.Name, cnode);
}
// Now output all stored info
foreach (string childname in childNodeNames.Keys)
{
ArrayList alChild = (ArrayList)childNodeNames[childname];
if (alChild.Count == 1)
OutputNode(childname, alChild[0], sbJSON, true);
else
{
sbJSON.Append(" \"" + SafeJSON(childname) + "\": [ ");
foreach (object Child in alChild)
OutputNode(childname, Child, sbJSON, false);
sbJSON.Remove(sbJSON.Length - 2, 2);
sbJSON.Append(" ], ");
}
}
sbJSON.Remove(sbJSON.Length - 2, 2);
sbJSON.Append(" }");
}
// StoreChildNode: Store data associated with each nodeName
// so that we know whether the nodeName is an array or not.
private static void StoreChildNode(SortedList childNodeNames, string nodeName, object nodeValue)
{
// Pre-process contraction of XmlElement-s
if (nodeValue is XmlElement)
{
// Convert <aa></aa> into "aa":null
// <aa>xx</aa> into "aa":"xx"
XmlNode cnode = (XmlNode)nodeValue;
if( cnode.Attributes.Count == 0)
{
XmlNodeList children = cnode.ChildNodes;
if( children.Count==0)
nodeValue = null;
else if (children.Count == 1 && (children[0] is XmlText))
nodeValue = ((XmlText)(children[0])).InnerText;
}
}
// Add nodeValue to ArrayList associated with each nodeName
// If nodeName doesn't exist then add it
object oValuesAL = childNodeNames[nodeName];
ArrayList ValuesAL;
if (oValuesAL == null)
{
ValuesAL = new ArrayList();
childNodeNames[nodeName] = ValuesAL;
}
else
ValuesAL = (ArrayList)oValuesAL;
ValuesAL.Add(nodeValue);
}
private static void OutputNode(string childname, object alChild, StringBuilder sbJSON, bool showNodeName)
{
if (alChild == null)
{
if (showNodeName)
sbJSON.Append("\"" + SafeJSON(childname) + "\": ");
sbJSON.Append("null");
}
else if (alChild is string)
{
if (showNodeName)
sbJSON.Append("\"" + SafeJSON(childname) + "\": ");
string sChild = (string)alChild;
sChild = sChild.Trim();
sbJSON.Append("\"" + SafeJSON(sChild) + "\"");
}
else
XmlToJSONnode(sbJSON, (XmlElement)alChild, showNodeName);
sbJSON.Append(", ");
}
// Make a string safe for JSON
private static string SafeJSON(string sIn)
{
StringBuilder sbOut = new StringBuilder(sIn.Length);
foreach (char ch in sIn)
{
if (Char.IsControl(ch) || ch == '\'')
{
int ich = (int)ch;
sbOut.Append(@"\u" + ich.ToString("x4"));
continue;
}
else if (ch == '\"' || ch == '\\' || ch == '/')
{
sbOut.Append('\\');
}
sbOut.Append(ch);
}
return sbOut.ToString();
}
Using XmlToJSON
The following code shows how to use XmlToJSON() when an ASP.NET 2 page loads. It then uses the ASP.NET2 ClientScriptManager to insert code containing the JSON string into the web page. See the following section for an example of JavaScript space_processJSON().
protected void Page_Load(object sender, EventArgs e)
{
XmlDocument doc = new XmlDocument();
try
{
string path = Server.MapPath(".");
doc.Load(path+"whatever.xml");
}
catch (Exception ex)
{
lblError.Text = ex.ToString();
return;
}
// Convert XML to a JSON string
string JSON = XmlToJSON(doc);
// Replace \ with \\ because string is being decoded twice
JSON = JSON.Replace(@"\", @"\\");
// Insert code to process JSON at end of page
ClientScriptManager cs = Page.ClientScript;
cs.RegisterStartupScript(GetType(), "SpaceJSON", "space_processJSON('" + JSON + "');", true);
}
Client-side code
<script src="space/json.js" type="text/javascript"></script>
<script type="text/javascript">
function space_processJSON( JSON)
{
space_DOM = JSON.parseJSON();
if( !space_DOM)
{
alert("JSON decode error");
return;
}
space_DOM.space.frame = ObjectToArray(space_DOM.space.frame);
space_frameCount = space_DOM.space.frame.length;
.. or whatever
}
</script>
Comments:
Michael, Mon, 19 Jun 2006 16:46:05 (GMT)
See this implementation: http://groups.google.de/group/ajaxpro/browse_thread/thread/219f830011e5ca6f/9e72c85fcf802a84#9e72c85fcf802a84
Damon Carr, Thu, 07 Sep 2006 12:24:31 (GMT)
Excellent work.
Alex Egg, Sun, 31 Dec 2006 06:31:43 (GMT)
Question: Why is XmlToJSON private? Wouldn't it be more appropriate for this method to be declared as public? Also, I think you should change the XmlDocument parameter of XmlToJSON to an XmlNode, it would be much more versatile.
Also, I have discovered you code does not produce correct JSON when the xml contains cdata blocks
Eric Walker, Mon, 8 Oct 2007 08:01:45 -0700
I found that an empty xml node was not being decoded properly (an extra } was being added). So for example <foo /> would be translated as {"foo" : }}
By tracking whether or not a child was added, I was able to work arround this issue:
// XmlToJSONnode: Output an XmlElement, possibly as part of a higher array
public static void XmlToJSONnode(StringBuilder sbJSON, XmlElement node, bool showNodeName)
{
bool childAdded = false;
if (showNodeName)
sbJSON.Append("\"" + SafeJSON(node.Name) + "\": ");
sbJSON.Append("{");
// Build a sorted list of key-value pairs
// where key is case-sensitive nodeName
// value is an ArrayList of string or XmlElement
// so that we know whether the nodeName is an array or not.
SortedList childNodeNames = new SortedList();
// Add in all node attributes
if (node.Attributes != null)
foreach (XmlAttribute attr in node.Attributes)
StoreChildNode(childNodeNames, attr.Name, attr.InnerText);
// Add in all nodes
foreach (XmlNode cnode in node.ChildNodes)
{
childAdded = true;
if (cnode is XmlText)
StoreChildNode(childNodeNames, "value", cnode.InnerText);
else if (cnode is XmlElement)
StoreChildNode(childNodeNames, cnode.Name, cnode);
}
// Now output all stored info
foreach (string childname in childNodeNames.Keys)
{
childAdded = true;
ArrayList alChild = (ArrayList)childNodeNames[childname];
if (alChild.Count == 1)
OutputNode(childname, alChild[0], sbJSON, true);
else
{
sbJSON.Append(" \"" + SafeJSON(childname) + "\": [ ");
foreach (object Child in alChild)
OutputNode(childname, Child, sbJSON, false);
sbJSON.Remove(sbJSON.Length - 2, 2);
sbJSON.Append(" ], ");
}
}
sbJSON.Remove(sbJSON.Length - 2, 2);
if (childAdded)
{
sbJSON.Append(" }");
}
else
{
sbJSON.Append(" null");
}
}
I hope this is helpful.
Leon, Mon, 22 Oct 2007 09:20:55 -0700
Another way to do it (DataContractJsonSerializer):
http://blogs.msdn.com/kaevans/archive/2007/09/04/use-linq-and-net-3-5-to-convert-rss-to-json.aspx
Mark Brito, Tue, 19 Feb 2008 21:16:32 GMT
In spirit of helping .. I found a bug where there is only one element in the xml, it would make it a single element instead of an array.. simply change the following line of code..
if (alChild.Count == 1)
to
if (alChild.Count == 1 && (alChild[0] is string))
Below is the entire function.
public static void XmlToJSONnode(StringBuilder sbJSON, XmlElement node, bool showNodeName)
{
bool childAdded = false;
if (showNodeName)
sbJSON.Append("\"" + SafeJSON(node.Name) + "\": ");
sbJSON.Append("{");
// Build a sorted list of key-value pairs
// where key is case-sensitive nodeName
// value is an ArrayList of string or XmlElement
// so that we know whether the nodeName is an array or not.
SortedList childNodeNames = new SortedList();
// Add in all node attributes
if (node.Attributes != null)
foreach (XmlAttribute attr in node.Attributes)
StoreChildNode(childNodeNames, attr.Name, attr.InnerText);
// Add in all nodes
foreach (XmlNode cnode in node.ChildNodes)
{
childAdded = true;
if (cnode is XmlText)
StoreChildNode(childNodeNames, "value", cnode.InnerText);
else if (cnode is XmlElement)
StoreChildNode(childNodeNames, cnode.Name, cnode);
}
// Now output all stored info
foreach (string childname in childNodeNames.Keys)
{
childAdded = true;
ArrayList alChild = (ArrayList)childNodeNames[childname];
bool bFlag = false;
foreach (object oChild in alChild) bFlag = true;
if (alChild.Count == 1 && (alChild[0] is string))
OutputNode(childname, alChild[0], sbJSON, true);
else
{
sbJSON.Append(" \"" + SafeJSON(childname) + "\": [ ");
foreach (object Child in alChild)
OutputNode(childname, Child, sbJSON, false);
sbJSON.Remove(sbJSON.Length - 2, 2);
sbJSON.Append(" ], ");
}
}
sbJSON.Remove(sbJSON.Length - 2, 2);
if (childAdded)
{
sbJSON.Append(" }");
}
else
{
sbJSON.Append(" null");
}
}
Milind Amin, Fri, 25 Jul 2008 06:52:56 GMT
Thanks. Very Good Article.
Paul Chu, Thu, 16 Oct 2008 01:52:44 GMT
Thank you and all the other contributors for this excellent article.
Does the last post contain all the suggested enhancements ?
Answer: I haven't tested the suggestions but they look good!
Chris, Thu, 13 Nov 2008 04:47:25 GMT
I could see where this would come in handy. Hats off to you for that. Overall, I would prefer to build JSON from real objects which gives me the ability to serialize to XML, JSON, or whatever.
noone, Mon, 06 Apr 2009 12:55:55 GMT
Use the .NET 3.5 JavaScript Serializer: System.Web.Script.Serialization.JavaScriptSerializer
Michele Costabile, Wed, 20 May 2009 13:33:31 GMT
I had a problem with an extra brace at the end of the file. I solved it checking that I really had to remove two characters from the end of the string buffer in XmlToJSONnode. The following is my version of the function. Maybe further inspection of the code would be in order for finding a more elegant solution, but this is what I managed to do in a short time.
// XmlToJSONnode: Output an XmlElement, possibly as part of a higher array
private static void XmlToJSONnode(StringBuilder sbJSON, XmlElement node, bool showNodeName)
{
if (showNodeName)
sbJSON.Append("\"" + SafeJSON(node.Name) + "\": ");
sbJSON.Append("{");
// Build a sorted list of key-value pairs
// where key is case-sensitive nodeName
// value is an ArrayList of string or XmlElement
// so that we know whether the nodeName is an array or not.
SortedList childNodeNames = new SortedList();
// Add in all node attributes
if (node.Attributes != null)
foreach (XmlAttribute attr in node.Attributes)
StoreChildNode(childNodeNames, attr.Name, attr.InnerText);
// Add in all nodes
foreach (XmlNode cnode in node.ChildNodes)
{
if (cnode is XmlText)
StoreChildNode(childNodeNames, "value", cnode.InnerText);
else if (cnode is XmlElement)
StoreChildNode(childNodeNames, cnode.Name, cnode);
}
// Now output all stored info
bool hasAddedChild = false;
foreach (string childname in childNodeNames.Keys)
{
ArrayList alChild = (ArrayList)childNodeNames[childname];
if (alChild.Count == 1 && (alChild[0] is string))
{
hasAddedChild = true;
OutputNode(childname, alChild[0], sbJSON, true);
}
else
{
sbJSON.Append(" \"" + SafeJSON(childname) + "\": [ ");
foreach (object Child in alChild)
{
hasAddedChild = true;
OutputNode(childname, Child, sbJSON, false);
}
if (hasAddedChild)
sbJSON.Remove(sbJSON.Length - 2, 2);
sbJSON.Append(" ], ");
}
}
if (hasAddedChild)
sbJSON.Remove(sbJSON.Length - 2, 2);
sbJSON.Append(" }");
}
Overide, Thu, 09 Jul 2009 11:09:49 GMT
ObjectToArray(obj): function is incorrect if obj is String. Maybe better:
function ObjectToArray( obj)
{
if (!obj) return new Array();
if (!(obj instanceof Array)) return new Array(obj);
return obj;
}
Override, Fri, 10 Jul 2009 08:39:11 GMT
and also it conflicts with JQuery. Line: v = f(v); - not enough memory
lucky, Fri, 21 Aug 2009 01:29:39 GMT
Thank
Karl, Thu, 15 Oct 2009 23:46:49 GMT
I added a check for numeric values, to optionally display the quotes.
In OutputNode() change the one line with the quotes to:
Double temp;
if (Double.TryParse(sChild, out temp))
sbJSON.Append(SafeJSON(sChild));
else
sbJSON.Append("\"" + SafeJSON(sChild) + "\"");
Richard, Mon, 02 Aug 2010 16:59:07 GMT
I've got an bug with the code - It doesn't handle unicode characters! An Ampersand would be return as an '&' rather than '&'. This is presumably due to the use of InnerXml rather than InnerText. However using InnerXml causes my JSON to be incorrectly rendered.
Any thoughts?
leonwoo, Thu, 14 Oct 2010 01:01:25 GMT
Nice code but has a bug with the comma in certain scenario. The workaround I put is this at the end of the OutputNode function.
string temp2 = sbJSON.ToString().Trim();
if(temp2.Substring(temp2.Length - 1) != ",")
sbJSON.Append(", ");
Gregory, Thu, 03 Mar 2011 16:03:27 GMT
Have not tested validity of the output for my needs, but comparing this methodology to the other libraries out there, I am quite impressed. I was getting logarithmic times with other JSON to XML libraries out there. As I have a huge file to deal with, the results with the others were unacceptable.
Saturday, July 30, 2011
Jquery Intorductions
What is jQuery?
jQuery is a library of JavaScript Functions.
jQuery is a lightweight "write less, do more" JavaScript library.
The jQuery library contains the following features:
HTML element selections
HTML element manipulation
CSS manipulation
HTML event functions
JavaScript Effects and animations
HTML DOM traversal and modification
AJAX
Utilities
jQuery Syntax
With jQuery you select (query) HTML elements and perform "actions" on them.
jQuery Syntax Examples
$(this).hide()
Demonstrates the jQuery hide() method, hiding the current HTML element.
$("#test").hide()
Demonstrates the jQuery hide() method, hiding the element with id="test".
$("p").hide()
Demonstrates the jQuery hide() method, hiding all <p> elements.
$(".test").hide()
Demonstrates the jQuery hide() method, hiding all elements with class="test".
jQuery Syntax
The jQuery syntax is tailor made for selecting HTML elements and perform some action on the element(s).
Basic syntax is: $(selector).action()
A dollar sign to define jQuery
A (selector) to "query (or find)" HTML elements
A jQuery action() to be performed on the element(s)
Examples:
$(this).hide() - hides current element
$("p").hide() - hides all paragraphs
$("p.test").hide() - hides all paragraphs with class="test"
$("#test").hide() - hides the element with id="test"
jQuery uses a combination of XPath and CSS selector syntax.
You will learn more about the selector syntax in the next chapter of this tutorial.
The Document Ready Function
You might have noticed that all jQuery methods, in our examples, are inside a document.ready() function:
$(document).ready(function(){
// jQuery functions go here...
});
This is to prevent any jQuery code from running before the document is finished loading (is ready).
Here are some examples of actions that can fail if functions are run before the document is fully loaded:
Trying to hide an element that doesn't exist
Trying to get the size of an image that is not loaded
jQuery Selectors
jQuery selectors allow you to select and manipulate HTML elements as a group or as a single element.
jQuery AJAX
jQuery Examples
jQuery Quiz
jQuery Quiz
jQuery Reference
jQuery Selectors
jQuery Events
jQuery Effects
jQuery HTML
jQuery CSS
jQuery AJAX
jQuery Misc
jQuery Selectors
« Previous
Next Chapter »
jQuery selectors allow you to select and manipulate HTML elements as a group or as a single element.
jQuery Selectors
In the previous chapter we looked at some examples of how to select different HTML elements.
It is a key point to learn how jQuery selects exactly the elements you want to apply an effect to.
jQuery selectors allow you to select HTML elements (or groups of elements) by element name, attribute name or by content.
In HTML DOM terms:
Selectors allow you to manipulate DOM elements as a group or as a single node.
jQuery Element Selectors
jQuery uses CSS selectors to select HTML elements.
$("p") selects all <p> elements.
$("p.intro") selects all <p> elements with class="intro".
$("p#demo") selects all <p> elements with id="demo".
jQuery Attribute Selectors
jQuery uses XPath expressions to select elements with given attributes.
$("[href]") select all elements with an href attribute.
$("[href='#']") select all elements with an href value equal to "#".
$("[href!='#']") select all elements with an href attribute NOT equal to "#".
$("[href$='.jpg']") select all elements with an href attribute that ends with ".jpg".
jQuery CSS Selectors
jQuery CSS selectors can be used to change CSS properties for HTML elements.
The following example changes the background-color of all p elements to yellow:
Example
$("p").css("background-color","yellow");
Try it yourself »
Some More Examples
Syntax
Description
$(this)
Current HTML element
$("p")
All <p> elements
$("p.intro")
All <p> elements with class="intro"
$("p#intro")
All <p> elements with id="intro"
$("p#intro:first")
The first <p> element with id="intro"
$(".intro")
All elements with class="intro"
$("#intro")
The first element with id="intro"
$("ul li:first")
The first <li> element of each <ul>
$("[href$='.jpg']")
All elements with an href attribute that ends with ".jpg"
$("div#intro .head")
All elements with class="head" inside a <div> element with id="intro"
Use our excellent jQuery Selector Tester to experiment with the different selectors.
For a full reference please go to our jQuery Selectors Reference
jQuery Events
jQuery is tailor made to handle events.
jQuery Event Functions
The jQuery event handling methods are core functions in jQuery.
Event handlers are method that are called when "something happens" in HTML. The term "triggered (or "fired") by an event" is often used.
It is common to put jQuery code into event handler methods in the <head> section:
Example
<html>
<head>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript">
$(document).ready(function(){
$("button").click(function(){
$("p").hide();
});
});
</script>
</head>
<body>
<h2>This is a heading</h2>
<p>This is a paragraph.</p>
<p>This is another paragraph.</p>
<button>Click me</button>
</body>
</html>
Try it yourself »
In the example above, a function is called when the click event for the button is triggered:
$("button").click(function() {..some code... } )
The method hides all <p> elements:
$("p").hide();
Functions In a Separate File
If your website contains a lot of pages, and you want your jQuery functions to be easy to maintain, put your jQuery functions in a separate .js file.
When we demonstrate jQuery here, the functions are added directly into the <head> section, However, sometimes it is preferable to place them in a separate file, like this (refer to the file with the src attribute):
Example
<head>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="my_jquery_functions.js"></script>
</head>
jQuery Name Conflicts
jQuery uses the $ sign as a shortcut for jQuery.
Some other JavaScript libraries also use the dollar sign for their functions.
The jQuery noConflict() method specifies a custom name (like jq), instead of using the dollar sign.
<html>
<head>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript">
var jq=jQuery.noConflict();
jq(document).ready(function(){
jq("button").click(function(){
jq("p").hide();
});
});
</script>
</head>
<body>
<h2>This is a heading</h2>
<p>This is a paragraph.</p>
<p>This is another paragraph.</p>
<button>Click me</button>
</body>
</html>
jQuery Events
Here are some examples of event methods in jQuery:
Event Method
Description
$(document).ready(function)
Binds a function to the ready event of a document
(when the document is finished loading)
$(selector).click(function)
Triggers, or binds a function to the click event of selected elements
$(selector).dblclick(function)
Triggers, or binds a function to the double click event of selected elements
$(selector).focus(function)
Triggers, or binds a function to the focus event of selected elements
$(selector).mouseover(function)
Triggers, or binds a function to the mouseover event of selected elements
For a full jQuery event reference, please go to our jQuery Events Reference.
jQuery Effects
Hide, Show, Toggle, Slide, Fade, and Animate. WOW!
Examples
jQuery hide()
Demonstrates a simple jQuery hide() method.
jQuery hide()
Another hide() demonstration. How to hide parts of text.
jQuery slideToggle()
Demonstrates a simple slide panel effect.
jQuery fadeTo()
Demonstrates a simple jQuery fadeTo() method.
jQuery animate()
Demonstrates a simple jQuery animate() method.
jQuery Hide and Show
With jQuery, you can hide and show HTML elements with the hide() and show() methods:
Example
$("#hide").click(function(){
$("p").hide();
});
$("#show").click(function(){
$("p").show();
});
Try it yourself »
Both hide() and show() can take the two optional parameters: speed and callback.
Syntax:
$(selector).hide(speed,callback)
$(selector).show(speed,callback)
The speed parameter specifies the speed of the hiding/showing, and can take the following values: "slow", "fast", "normal", or milliseconds:
Example
$("button").click(function(){
$("p").hide(1000);
});
Try it yourself »
The callback parameter is the name of a function to be executed after the hide (or show) function completes. You will learn more about the callback parameter in the next chapter of this tutorial.
jQuery Toggle
The jQuery toggle() method toggles the visibility of HTML elements using the show() or hide() methods.
Shown elements are hidden and hidden elements are shown.
Syntax:
$(selector).toggle(speed,callback)
The speed parameter can take the following values: "slow", "fast", "normal", or milliseconds.
Example
$("button").click(function(){
$("p").toggle();
});
Try it yourself »
The callback parameter is the name of a function to be executed after the hide (or show) method completes.
jQuery Slide - slideDown, slideUp, slideToggle
The jQuery slide methods gradually change the height for selected elements.
jQuery has the following slide methods:
$(selector).slideDown(speed,callback)
$(selector).slideUp(speed,callback)
$(selector).slideToggle(speed,callback)
The speed parameter can take the following values: "slow", "fast", "normal", or milliseconds.
The callback parameter is the name of a function to be executed after the function completes.
slideDown() Example
$(".flip").click(function(){
$(".panel").slideDown();
});
Try it yourself »
slideUp() Example
$(".flip").click(function(){
$(".panel").slideUp()
})
Try it yourself »
slideToggle() Example
$(".flip").click(function(){
$(".panel").slideToggle();
});
Try it yourself »
jQuery Fade - fadeIn, fadeOut, fadeTo
The jQuery fade methods gradually change the opacity for selected elements.
jQuery has the following fade methods:
$(selector).fadeIn(speed,callback)
$(selector).fadeOut(speed,callback)
$(selector).fadeTo(speed,opacity,callback)
The speed parameter can take the following values: "slow", "fast", "normal", or milliseconds.
The opacity parameter in the fadeTo() method allows fading to a given opacity.
The callback parameter is the name of a function to be executed after the function completes.
fadeTo() Example
$("button").click(function(){
$("div").fadeTo("slow",0.25);
});
Try it yourself »
fadeOut() Example
$("button").click(function(){
$("div").fadeOut(4000);
});
Try it yourself »
jQuery Custom Animations
The syntax of jQuery's method for making custom animations is:
$(selector).animate({params},[duration],[easing],[callback])
The key parameter is params. It defines the CSS properties that will be animated. Many properties can be animated at the same time:
animate({width:"70%",opacity:0.4,marginLeft:"0.6in",fontSize:"3em"});
The second parameter is duration. It specifies the speed of the animation. Possible values are "fast", "slow", "normal", or milliseconds.
Example 1
<script type="text/javascript">
$(document).ready(function(){
$("button").click(function(){
$("div").animate({height:300},"slow");
$("div").animate({width:300},"slow");
$("div").animate({height:100},"slow");
$("div").animate({width:100},"slow");
});
});
</script>
Try it yourself »
Example 2
<script type="text/javascript">
$(document).ready(function(){
$("button").click(function(){
$("div").animate({left:"100px"},"slow");
$("div").animate({fontSize:"3em"},"slow");
});
});
</script>
Try it yourself »
HTML elements are positioned static by default and cannot be moved.
To make elements moveable, set the CSS position property to fixed, relative or absolute.
jQuery Effects
Here are some examples of effect functions in jQuery:
Function
Description
$(selector).hide()
Hide selected elements
$(selector).show()
Show selected elements
$(selector).toggle()
Toggle (between hide and show) selected elements
$(selector).slideDown()
Slide-down (show) selected elements
$(selector).slideUp()
Slide-up (hide) selected elements
$(selector).slideToggle()
Toggle slide-up and slide-down of selected elements
$(selector).fadeIn()
Fade in selected elements
$(selector).fadeOut()
Fade out selected elements
$(selector).fadeTo()
Fade out selected elements to a given opacity
$(selector).animate()
Run a custom animation on selected elements
For a full jQuery effect reference, please go to our jQuery Effect Reference.
jQuery Callback Functions
A callback function is executed after the current animation is 100% finished.
jQuery Callback Functions
A callback function is executed after the current animation (effect) is finished.
JavaScript statements are executed line by line. However, with animations, the next line of code can be run even though the animation is not finished. This can create errors.
To prevent this, you can create a callback function. The callback function will not be called until after the animation is finished.
jQuery Callback Example
Typical syntax: $(selector).hide(speed,callback)
The callback parameter is a function to be executed after the hide effect is completed:
Example with Callback
$("p").hide(1000,function(){
alert("The paragraph is now hidden");
});
Try it yourself »
Without a callback parameter, the alert box is displayed before the hide effect is completed:
Example without Callback
$("p").hide(1000);
alert("The paragraph is now hidden");
Try it yourself »
jQuery HTML Manipulation
jQuery contains powerful methods (functions) for changing and manipulating HTML elements and attributes.
Changing HTML Content
$(selector).html(content)
The html() method changes the contents (innerHTML) of matching HTML elements.
Example
$("p").html("W3Schools");
Try it yourself »
Adding HTML content
$(selector).append(content)
The append() method appends content to the inside of matching HTML elements.
$(selector).prepend(content)
The prepend() method "prepends" content to the inside of matching HTML elements.
Example
$("p").append(" W3Schools");
Try it yourself »
$(selector).after(content)
The after() method inserts HTML content after all matching elements.
$(selector).before(content)
The before() method inserts HTML content before all matching elements.
Example
$("p").after(" W3Schools.");
Try it yourself »
jQuery HTML Manipulation Methods From This Page:
Function
Description
$(selector).html(content)
Changes the (inner) HTML of selected elements
$(selector).append(content)
Appends content to the (inner) HTML of selected elements
$(selector).after(content)
Adds HTML after selected elements
For a full jQuery HTML reference, please go to our jQuery HTML Methods Reference.
jQuery CSS Manipulation
jQuery css() Method
jQuery has one important method for CSS manipulation: css()
The css() method has three different syntaxes, to perform different tasks.
css(name) - Return CSS property value
css(name,value) - Set CSS property and value
css({properties}) - Set multiple CSS properties and values
Return CSS Property
Use css(name) to return the specified CSS property value of the FIRST matched element:
Example
$(this).css("background-color");
Try it yourself »
Set CSS Property and Value
Use css(name,value) to set the specified CSS property for ALL matched elements:
Example
$("p").css("background-color","yellow");
Try it yourself »
Set Multiple CSS Property/Value Pairs
Use css({properties}) to set one or more CSS property/value pairs for the selected elements:
Example
$("p").css({"background-color":"yellow","font-size":"200%"});
Try it yourself »
jQuery height() and width() Methods
jQuery has two important methods for size manipulation.
height()
width()
Size Manipulation Examples
The height() method sets the height of all matching elements:
Example
$("#div1").height("200px");
Try it yourself »
The width() method sets the width of all matching elements:
Example
$("#div2").width("300px");
Try it yourself »
jQuery CSS Methods From this Page:
CSS Properties
Description
$(selector).css(name)
Get the style property value of the first matched element
$(selector).css(name,value)
Set the value of one style property for matched elements
$(selector).css({properties})
Set multiple style properties for matched elements
$(selector).height(value)
Set the height of matched elements
$(selector).width(value)
Set the width of matched elements
For a full jQuery CSS reference, please go to our jQuery CSS Methods Reference.
jQuery AJAX
jQuery has a rich library of methods (functions) for AJAX development.
jQuery AJAX ExampleAJAX is not a programming language.
It is just a technique for creating better and more interactive web applications.
<html>
<head>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript">
$(document).ready(function(){
$("button").click(function(){
$("div").load('test1.txt');
});
});
</script>
</head>
<body>
<div><h2>Let AJAX change this text</h2></div>
<button>Change Content</button>
</body>
</html>
The example above is taken from our AJAX tutorial, but modified with jQuery syntax.
What is AJAX?
AJAX = Asynchronous JavaScript and XML.
AJAX is a technique for creating fast and dynamic web pages.
AJAX allows web pages to be updated asynchronously by exchanging small amounts of data with the server behind the scenes. This means that it is possible to update parts of a web page, without reloading the whole page.
You can learn more about AJAX in our AJAX tutorial.
AJAX and jQuery
jQuery provides a rich set of methods for AJAX web development.
With jQuery AJAX, you can request TXT, HTML, XML or JSON data from a remote server using both HTTP Get and HTTP Post.
And you can load remote data directly into selected HTML elements of your web page!
Write Less, Do More
The jQuery load() method is a simple (but very powerful) AJAX function. It has the following syntax:
$(selector).load(url,data,callback)
Use the selector to define the HTML element(s) to change, and the url parameter to specify a web address for your data.
Try it yourself »
Only if you want to send data to the server, you need to use the data parameter. Only if you need to trigger a function after completion, you will use the callback parameter.
Low Level AJAX
$.ajax(options) is the syntax of the low level AJAX function.
$.ajax offers more functionality than higher level functions like load, get, and post, but it is also more difficult to use.
The option parameter takes name|value pairs defining url data, passwords, data types, filters, character sets, timeout and error functions.
<html>
<head>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript">
$(document).ready(function(){
$("button").click(function(){
$.ajax({url:"test1.txt", success:function(result){
$("div").html(result);
}});
});});
</script>
</head>
<body>
<div><h2>Let AJAX change this text</h2></div>
<button>Change Content</button>
</body>
</html>
jQuery AJAX Methods From This Page:
Request
Description
$(selector).load(url,data,callback)
Load remote data into selected elements
$.ajax(options)
Load remote data into an XMLHttpRequest object
For a full jQuery AJAX reference, please go to our jQuery AJAX Methods Reference.
W3Schools jQuery Quiz
1. Which of the following is correct?
Correct Answer!
2. jQuery uses CSS selectors and XPath expressions to select elements?
Correct Answer!
3. Which sign does jQuery use as a shortcut for jQuery?
Correct Answer!
4. With jQuery, look at the following selector: $("div"). What does it select?
Correct Answer!
5. Is jQuery a library for client scripting or server scripting?
Correct Answer!
6. Is it possible to use jQuery together with AJAX?
Correct Answer!
7. The jQuery html() method works for both HTML and XML documents
You answered:
True
Wrong Answer!
8. What is the correct jQuery code to set the background color of all p elements to red?
Correct Answer!
9. With jQuery, look at the following selector: $("div.intro"). What does it select?
You answered:
The first div element with class="intro"
Wrong Answer!
10. Which jQuery method is used to hide selected elements?
Correct Answer!
11. Which jQuery method is used to set one or more style properties for selected elements?
Correct Answer!
12. Which jQuery method is used to perform an asynchronous HTTP request?
Correct Answer!
13. What is the correct jQuery code for making all div elements 100 pixels high?
Correct Answer!
14. Which statement is true?
Correct Answer!
15. What scripting language is jQuery written in?
Correct Answer!
16. Which jQuery function is used to prevent code from running, before the document is finished loading?
Correct Answer!
17. Which jQuery method should be used to deal with name conflicts?
Correct Answer!
18. Which jQuery method is used to switch between adding/removing one or more classes (for CSS) from selected elements?
Correct Answer!
19. Look at the following jQuery selector: $("div#intro .head"). What does it select?
Correct Answer!
20. Is jQuery a W3C standard?
You answered:
Yes
Wrong Answer!
12 Key Points why JQuery is Boss
1. Cross browser capability
2. Cross language capability
3. Integrated in Microsoft development products
4. Consistent coding usage
5. Consistent JavaScript library
6. Faster development time
7. JSON for faster and more efficient back end communication.
8. Consistent Ajax support
9. Low Learning Curve
10. Simplified Document Traversal
11. Not Just Objects
12. Better CSS Interaction
jQuery is a library of JavaScript Functions.
jQuery is a lightweight "write less, do more" JavaScript library.
The jQuery library contains the following features:
HTML element selections
HTML element manipulation
CSS manipulation
HTML event functions
JavaScript Effects and animations
HTML DOM traversal and modification
AJAX
Utilities
jQuery Syntax
With jQuery you select (query) HTML elements and perform "actions" on them.
jQuery Syntax Examples
$(this).hide()
Demonstrates the jQuery hide() method, hiding the current HTML element.
$("#test").hide()
Demonstrates the jQuery hide() method, hiding the element with id="test".
$("p").hide()
Demonstrates the jQuery hide() method, hiding all <p> elements.
$(".test").hide()
Demonstrates the jQuery hide() method, hiding all elements with class="test".
jQuery Syntax
The jQuery syntax is tailor made for selecting HTML elements and perform some action on the element(s).
Basic syntax is: $(selector).action()
A dollar sign to define jQuery
A (selector) to "query (or find)" HTML elements
A jQuery action() to be performed on the element(s)
Examples:
$(this).hide() - hides current element
$("p").hide() - hides all paragraphs
$("p.test").hide() - hides all paragraphs with class="test"
$("#test").hide() - hides the element with id="test"
jQuery uses a combination of XPath and CSS selector syntax.
You will learn more about the selector syntax in the next chapter of this tutorial.
The Document Ready Function
You might have noticed that all jQuery methods, in our examples, are inside a document.ready() function:
$(document).ready(function(){
// jQuery functions go here...
});
This is to prevent any jQuery code from running before the document is finished loading (is ready).
Here are some examples of actions that can fail if functions are run before the document is fully loaded:
Trying to hide an element that doesn't exist
Trying to get the size of an image that is not loaded
jQuery Selectors
jQuery selectors allow you to select and manipulate HTML elements as a group or as a single element.
jQuery AJAX
jQuery Examples
jQuery Quiz
jQuery Quiz
jQuery Reference
jQuery Selectors
jQuery Events
jQuery Effects
jQuery HTML
jQuery CSS
jQuery AJAX
jQuery Misc
jQuery Selectors
« Previous
Next Chapter »
jQuery selectors allow you to select and manipulate HTML elements as a group or as a single element.
jQuery Selectors
In the previous chapter we looked at some examples of how to select different HTML elements.
It is a key point to learn how jQuery selects exactly the elements you want to apply an effect to.
jQuery selectors allow you to select HTML elements (or groups of elements) by element name, attribute name or by content.
In HTML DOM terms:
Selectors allow you to manipulate DOM elements as a group or as a single node.
jQuery Element Selectors
jQuery uses CSS selectors to select HTML elements.
$("p") selects all <p> elements.
$("p.intro") selects all <p> elements with class="intro".
$("p#demo") selects all <p> elements with id="demo".
jQuery Attribute Selectors
jQuery uses XPath expressions to select elements with given attributes.
$("[href]") select all elements with an href attribute.
$("[href='#']") select all elements with an href value equal to "#".
$("[href!='#']") select all elements with an href attribute NOT equal to "#".
$("[href$='.jpg']") select all elements with an href attribute that ends with ".jpg".
jQuery CSS Selectors
jQuery CSS selectors can be used to change CSS properties for HTML elements.
The following example changes the background-color of all p elements to yellow:
Example
$("p").css("background-color","yellow");
Try it yourself »
Some More Examples
Syntax
Description
$(this)
Current HTML element
$("p")
All <p> elements
$("p.intro")
All <p> elements with class="intro"
$("p#intro")
All <p> elements with id="intro"
$("p#intro:first")
The first <p> element with id="intro"
$(".intro")
All elements with class="intro"
$("#intro")
The first element with id="intro"
$("ul li:first")
The first <li> element of each <ul>
$("[href$='.jpg']")
All elements with an href attribute that ends with ".jpg"
$("div#intro .head")
All elements with class="head" inside a <div> element with id="intro"
Use our excellent jQuery Selector Tester to experiment with the different selectors.
For a full reference please go to our jQuery Selectors Reference
jQuery Events
jQuery is tailor made to handle events.
jQuery Event Functions
The jQuery event handling methods are core functions in jQuery.
Event handlers are method that are called when "something happens" in HTML. The term "triggered (or "fired") by an event" is often used.
It is common to put jQuery code into event handler methods in the <head> section:
Example
<html>
<head>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript">
$(document).ready(function(){
$("button").click(function(){
$("p").hide();
});
});
</script>
</head>
<body>
<h2>This is a heading</h2>
<p>This is a paragraph.</p>
<p>This is another paragraph.</p>
<button>Click me</button>
</body>
</html>
Try it yourself »
In the example above, a function is called when the click event for the button is triggered:
$("button").click(function() {..some code... } )
The method hides all <p> elements:
$("p").hide();
Functions In a Separate File
If your website contains a lot of pages, and you want your jQuery functions to be easy to maintain, put your jQuery functions in a separate .js file.
When we demonstrate jQuery here, the functions are added directly into the <head> section, However, sometimes it is preferable to place them in a separate file, like this (refer to the file with the src attribute):
Example
<head>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="my_jquery_functions.js"></script>
</head>
jQuery Name Conflicts
jQuery uses the $ sign as a shortcut for jQuery.
Some other JavaScript libraries also use the dollar sign for their functions.
The jQuery noConflict() method specifies a custom name (like jq), instead of using the dollar sign.
<html>
<head>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript">
var jq=jQuery.noConflict();
jq(document).ready(function(){
jq("button").click(function(){
jq("p").hide();
});
});
</script>
</head>
<body>
<h2>This is a heading</h2>
<p>This is a paragraph.</p>
<p>This is another paragraph.</p>
<button>Click me</button>
</body>
</html>
jQuery Events
Here are some examples of event methods in jQuery:
Event Method
Description
$(document).ready(function)
Binds a function to the ready event of a document
(when the document is finished loading)
$(selector).click(function)
Triggers, or binds a function to the click event of selected elements
$(selector).dblclick(function)
Triggers, or binds a function to the double click event of selected elements
$(selector).focus(function)
Triggers, or binds a function to the focus event of selected elements
$(selector).mouseover(function)
Triggers, or binds a function to the mouseover event of selected elements
For a full jQuery event reference, please go to our jQuery Events Reference.
jQuery Effects
Hide, Show, Toggle, Slide, Fade, and Animate. WOW!
Examples
jQuery hide()
Demonstrates a simple jQuery hide() method.
jQuery hide()
Another hide() demonstration. How to hide parts of text.
jQuery slideToggle()
Demonstrates a simple slide panel effect.
jQuery fadeTo()
Demonstrates a simple jQuery fadeTo() method.
jQuery animate()
Demonstrates a simple jQuery animate() method.
jQuery Hide and Show
With jQuery, you can hide and show HTML elements with the hide() and show() methods:
Example
$("#hide").click(function(){
$("p").hide();
});
$("#show").click(function(){
$("p").show();
});
Try it yourself »
Both hide() and show() can take the two optional parameters: speed and callback.
Syntax:
$(selector).hide(speed,callback)
$(selector).show(speed,callback)
The speed parameter specifies the speed of the hiding/showing, and can take the following values: "slow", "fast", "normal", or milliseconds:
Example
$("button").click(function(){
$("p").hide(1000);
});
Try it yourself »
The callback parameter is the name of a function to be executed after the hide (or show) function completes. You will learn more about the callback parameter in the next chapter of this tutorial.
jQuery Toggle
The jQuery toggle() method toggles the visibility of HTML elements using the show() or hide() methods.
Shown elements are hidden and hidden elements are shown.
Syntax:
$(selector).toggle(speed,callback)
The speed parameter can take the following values: "slow", "fast", "normal", or milliseconds.
Example
$("button").click(function(){
$("p").toggle();
});
Try it yourself »
The callback parameter is the name of a function to be executed after the hide (or show) method completes.
jQuery Slide - slideDown, slideUp, slideToggle
The jQuery slide methods gradually change the height for selected elements.
jQuery has the following slide methods:
$(selector).slideDown(speed,callback)
$(selector).slideUp(speed,callback)
$(selector).slideToggle(speed,callback)
The speed parameter can take the following values: "slow", "fast", "normal", or milliseconds.
The callback parameter is the name of a function to be executed after the function completes.
slideDown() Example
$(".flip").click(function(){
$(".panel").slideDown();
});
Try it yourself »
slideUp() Example
$(".flip").click(function(){
$(".panel").slideUp()
})
Try it yourself »
slideToggle() Example
$(".flip").click(function(){
$(".panel").slideToggle();
});
Try it yourself »
jQuery Fade - fadeIn, fadeOut, fadeTo
The jQuery fade methods gradually change the opacity for selected elements.
jQuery has the following fade methods:
$(selector).fadeIn(speed,callback)
$(selector).fadeOut(speed,callback)
$(selector).fadeTo(speed,opacity,callback)
The speed parameter can take the following values: "slow", "fast", "normal", or milliseconds.
The opacity parameter in the fadeTo() method allows fading to a given opacity.
The callback parameter is the name of a function to be executed after the function completes.
fadeTo() Example
$("button").click(function(){
$("div").fadeTo("slow",0.25);
});
Try it yourself »
fadeOut() Example
$("button").click(function(){
$("div").fadeOut(4000);
});
Try it yourself »
jQuery Custom Animations
The syntax of jQuery's method for making custom animations is:
$(selector).animate({params},[duration],[easing],[callback])
The key parameter is params. It defines the CSS properties that will be animated. Many properties can be animated at the same time:
animate({width:"70%",opacity:0.4,marginLeft:"0.6in",fontSize:"3em"});
The second parameter is duration. It specifies the speed of the animation. Possible values are "fast", "slow", "normal", or milliseconds.
Example 1
<script type="text/javascript">
$(document).ready(function(){
$("button").click(function(){
$("div").animate({height:300},"slow");
$("div").animate({width:300},"slow");
$("div").animate({height:100},"slow");
$("div").animate({width:100},"slow");
});
});
</script>
Try it yourself »
Example 2
<script type="text/javascript">
$(document).ready(function(){
$("button").click(function(){
$("div").animate({left:"100px"},"slow");
$("div").animate({fontSize:"3em"},"slow");
});
});
</script>
Try it yourself »
HTML elements are positioned static by default and cannot be moved.
To make elements moveable, set the CSS position property to fixed, relative or absolute.
jQuery Effects
Here are some examples of effect functions in jQuery:
Function
Description
$(selector).hide()
Hide selected elements
$(selector).show()
Show selected elements
$(selector).toggle()
Toggle (between hide and show) selected elements
$(selector).slideDown()
Slide-down (show) selected elements
$(selector).slideUp()
Slide-up (hide) selected elements
$(selector).slideToggle()
Toggle slide-up and slide-down of selected elements
$(selector).fadeIn()
Fade in selected elements
$(selector).fadeOut()
Fade out selected elements
$(selector).fadeTo()
Fade out selected elements to a given opacity
$(selector).animate()
Run a custom animation on selected elements
For a full jQuery effect reference, please go to our jQuery Effect Reference.
jQuery Callback Functions
A callback function is executed after the current animation is 100% finished.
jQuery Callback Functions
A callback function is executed after the current animation (effect) is finished.
JavaScript statements are executed line by line. However, with animations, the next line of code can be run even though the animation is not finished. This can create errors.
To prevent this, you can create a callback function. The callback function will not be called until after the animation is finished.
jQuery Callback Example
Typical syntax: $(selector).hide(speed,callback)
The callback parameter is a function to be executed after the hide effect is completed:
Example with Callback
$("p").hide(1000,function(){
alert("The paragraph is now hidden");
});
Try it yourself »
Without a callback parameter, the alert box is displayed before the hide effect is completed:
Example without Callback
$("p").hide(1000);
alert("The paragraph is now hidden");
Try it yourself »
jQuery HTML Manipulation
jQuery contains powerful methods (functions) for changing and manipulating HTML elements and attributes.
Changing HTML Content
$(selector).html(content)
The html() method changes the contents (innerHTML) of matching HTML elements.
Example
$("p").html("W3Schools");
Try it yourself »
Adding HTML content
$(selector).append(content)
The append() method appends content to the inside of matching HTML elements.
$(selector).prepend(content)
The prepend() method "prepends" content to the inside of matching HTML elements.
Example
$("p").append(" W3Schools");
Try it yourself »
$(selector).after(content)
The after() method inserts HTML content after all matching elements.
$(selector).before(content)
The before() method inserts HTML content before all matching elements.
Example
$("p").after(" W3Schools.");
Try it yourself »
jQuery HTML Manipulation Methods From This Page:
Function
Description
$(selector).html(content)
Changes the (inner) HTML of selected elements
$(selector).append(content)
Appends content to the (inner) HTML of selected elements
$(selector).after(content)
Adds HTML after selected elements
For a full jQuery HTML reference, please go to our jQuery HTML Methods Reference.
jQuery CSS Manipulation
jQuery css() Method
jQuery has one important method for CSS manipulation: css()
The css() method has three different syntaxes, to perform different tasks.
css(name) - Return CSS property value
css(name,value) - Set CSS property and value
css({properties}) - Set multiple CSS properties and values
Return CSS Property
Use css(name) to return the specified CSS property value of the FIRST matched element:
Example
$(this).css("background-color");
Try it yourself »
Set CSS Property and Value
Use css(name,value) to set the specified CSS property for ALL matched elements:
Example
$("p").css("background-color","yellow");
Try it yourself »
Set Multiple CSS Property/Value Pairs
Use css({properties}) to set one or more CSS property/value pairs for the selected elements:
Example
$("p").css({"background-color":"yellow","font-size":"200%"});
Try it yourself »
jQuery height() and width() Methods
jQuery has two important methods for size manipulation.
height()
width()
Size Manipulation Examples
The height() method sets the height of all matching elements:
Example
$("#div1").height("200px");
Try it yourself »
The width() method sets the width of all matching elements:
Example
$("#div2").width("300px");
Try it yourself »
jQuery CSS Methods From this Page:
CSS Properties
Description
$(selector).css(name)
Get the style property value of the first matched element
$(selector).css(name,value)
Set the value of one style property for matched elements
$(selector).css({properties})
Set multiple style properties for matched elements
$(selector).height(value)
Set the height of matched elements
$(selector).width(value)
Set the width of matched elements
For a full jQuery CSS reference, please go to our jQuery CSS Methods Reference.
jQuery AJAX
jQuery has a rich library of methods (functions) for AJAX development.
jQuery AJAX ExampleAJAX is not a programming language.
It is just a technique for creating better and more interactive web applications.
<html>
<head>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript">
$(document).ready(function(){
$("button").click(function(){
$("div").load('test1.txt');
});
});
</script>
</head>
<body>
<div><h2>Let AJAX change this text</h2></div>
<button>Change Content</button>
</body>
</html>
The example above is taken from our AJAX tutorial, but modified with jQuery syntax.
What is AJAX?
AJAX = Asynchronous JavaScript and XML.
AJAX is a technique for creating fast and dynamic web pages.
AJAX allows web pages to be updated asynchronously by exchanging small amounts of data with the server behind the scenes. This means that it is possible to update parts of a web page, without reloading the whole page.
You can learn more about AJAX in our AJAX tutorial.
AJAX and jQuery
jQuery provides a rich set of methods for AJAX web development.
With jQuery AJAX, you can request TXT, HTML, XML or JSON data from a remote server using both HTTP Get and HTTP Post.
And you can load remote data directly into selected HTML elements of your web page!
Write Less, Do More
The jQuery load() method is a simple (but very powerful) AJAX function. It has the following syntax:
$(selector).load(url,data,callback)
Use the selector to define the HTML element(s) to change, and the url parameter to specify a web address for your data.
Try it yourself »
Only if you want to send data to the server, you need to use the data parameter. Only if you need to trigger a function after completion, you will use the callback parameter.
Low Level AJAX
$.ajax(options) is the syntax of the low level AJAX function.
$.ajax offers more functionality than higher level functions like load, get, and post, but it is also more difficult to use.
The option parameter takes name|value pairs defining url data, passwords, data types, filters, character sets, timeout and error functions.
<html>
<head>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript">
$(document).ready(function(){
$("button").click(function(){
$.ajax({url:"test1.txt", success:function(result){
$("div").html(result);
}});
});});
</script>
</head>
<body>
<div><h2>Let AJAX change this text</h2></div>
<button>Change Content</button>
</body>
</html>
jQuery AJAX Methods From This Page:
Request
Description
$(selector).load(url,data,callback)
Load remote data into selected elements
$.ajax(options)
Load remote data into an XMLHttpRequest object
For a full jQuery AJAX reference, please go to our jQuery AJAX Methods Reference.
W3Schools jQuery Quiz
1. Which of the following is correct?
Correct Answer!
2. jQuery uses CSS selectors and XPath expressions to select elements?
Correct Answer!
3. Which sign does jQuery use as a shortcut for jQuery?
Correct Answer!
4. With jQuery, look at the following selector: $("div"). What does it select?
Correct Answer!
5. Is jQuery a library for client scripting or server scripting?
Correct Answer!
6. Is it possible to use jQuery together with AJAX?
Correct Answer!
7. The jQuery html() method works for both HTML and XML documents
You answered:
True
Wrong Answer!
8. What is the correct jQuery code to set the background color of all p elements to red?
Correct Answer!
9. With jQuery, look at the following selector: $("div.intro"). What does it select?
You answered:
The first div element with class="intro"
Wrong Answer!
10. Which jQuery method is used to hide selected elements?
Correct Answer!
11. Which jQuery method is used to set one or more style properties for selected elements?
Correct Answer!
12. Which jQuery method is used to perform an asynchronous HTTP request?
Correct Answer!
13. What is the correct jQuery code for making all div elements 100 pixels high?
Correct Answer!
14. Which statement is true?
Correct Answer!
15. What scripting language is jQuery written in?
Correct Answer!
16. Which jQuery function is used to prevent code from running, before the document is finished loading?
Correct Answer!
17. Which jQuery method should be used to deal with name conflicts?
Correct Answer!
18. Which jQuery method is used to switch between adding/removing one or more classes (for CSS) from selected elements?
Correct Answer!
19. Look at the following jQuery selector: $("div#intro .head"). What does it select?
Correct Answer!
20. Is jQuery a W3C standard?
You answered:
Yes
Wrong Answer!
12 Key Points why JQuery is Boss
1. Cross browser capability
2. Cross language capability
3. Integrated in Microsoft development products
4. Consistent coding usage
5. Consistent JavaScript library
6. Faster development time
7. JSON for faster and more efficient back end communication.
8. Consistent Ajax support
9. Low Learning Curve
10. Simplified Document Traversal
11. Not Just Objects
12. Better CSS Interaction
WCF introduction and interview Qestions
5. Explanations of fundamentals involved
Assuming that the reader has no Background in WCF, there are a number of key concepts that needs to be explained in order for the full application to be understood.
So I will just explain each of these a little bit at a time, so that the final application will be a little easier to understand.
Key Concepts:
a) What is WCF?
WCF stands for Windows Communication Foundation.
WCF is advanced API (Application Programming Interface) for creating distributed applications using .NET framework.
It is introduced in .NET 3.0.
Distributed system in its simplest form is two executable running and exchanging data.
WCF API is found in System.ServiceModel namespace.
WCF is based on basic concepts of Service oriented architecture (SOA)
b) What is a WCF Service?
A WCF service is a program that exposes a collection of Endpoints (connections) for communicating with either client applications or other service applications.
c) What are the components of WCF application?
There are three main components of a WCF application
i) a WCF service
ii) a WCF service host
iii) a WCF service client
d) What is the “ABC” of a WCF Service?
“ABC” of WCF stands for addresses Bindings and contracts respectively.
i) Addresses: This is location of the service in the form of an
URI (Uniform resource Identifier) generally mentioned
In the config file.
ii) Bindings: This includes the type of network protocol used by the
Service. For Example HTTP, TCP/IP or others.
iii) Contracts: This is in fact the methods exposed by the WCF service.
e) What is a Service Contract in WCF application?
Service contract is the name of the attribute which is applied to an interface in a WCF service.
f) What is an Operation Contract in WCF application?
Operation contract is the name of the attribute which is applied to a method inside the interface of a WCF service
6. The demo Service with code
Before I start, I would like to remind you again that this is the simplest of WCF service only for understanding purpose. In real world you might have to build/face much more complicated WCF service.
I have divided this part in five sub-parts as below.
a) Building the WCF service
b) Building the WCF host
c) Building the Proxy to be used by client
d) Building WCF client
e) Testing the working of the whole application.
a) Building the WCF service
To understand the service better we will build the service as a c# class library project. Follow the following steps:
In my case it created the class1.cs with content as below.
i) Open Visual Studio 2008
ii) Select Create Projectà C# class library name it “Sample Service”
iii) It will crate a .cs file in the project. Open that file.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace SampleService
{
public class Class1
{
}
}
Change the namespace SampleService to SampleServiceLib,
Rename the Class1 to SampleService.
Rename the Class1.cs file in the solutionExplorer to SampleService.cs
Add the namesapce using System.ServiceModel at the top.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
namespace SampleServiceLib
{
public class SampleService
{
}
}
The SampleService.cs file should now look like below.
iv) At this point the project will not build, so please add a reference to System.Service Model.
For this, Go to solution Explorer ,Right click on the reference Add Reference .NET Tab Select System.ServiceModel OK.
Now you can successfully build the Project.
v) Create an interface named IAnswer in this file inside SampleServiceLib namespace.Create a method inside the interface IAnswer, named ObtainAnswer The attributes for the interface and the method should be ServiceContract and OperationContract respectively
vi) Implement the IAnswer interface in SampleService class as
Shown in the code sample below.
namespace SampleServiceLib
{
public class SampleService : IAnswer
{
public string ObtainAnswer(string Question)
{
return "My Profession is Software Development";
}
}
[ServiceContract]
public interface IAnswer
{
[OperationContract]
string ObtainAnswer(string Question);
}
}
vii) Now ad a constructor to the class SampleService and the final code should look like this.Build this project.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
namespace SampleServiceLib
{
public class SampleService : IAnswer
{
public SampleService()
{
Console.WriteLine("Ask question to SampleService....");
}
public string ObtainAnswer(string Question)
{
return "Your Profession is Software Developer";
}
}
[ServiceContract]
public interface IAnswer
{
[OperationContract]
string ObtainAnswer(string Question);
}
}
viii) Save the sample service Project by File Save All. Then build it so that you will get a SampleSevice.dll in its bin\release directory.
b) Building the WCF host
A WCF host may be IIS (Internet Information Server) , Windows Service, A console application etc.The simplest of them is a console application host. So we will demonstrate that here.
Follow the following steps:
i) Open Visual Studio 2008
ii) Select Create Projectà C# Console Application name it “Sample Host”
iii) From Solution Explorer,Add the reference of System.ServiceModel to this project as before and
iv) also add the reference of SampleServiceLib.dll from SmpleService Class library project you created before by addreference Browse Tab Browse to the SampleServiceLib.dll in the project SampleService’s Bin/release folder.
v) Open its Program.cs file and add the following two namespace to the
Using Section.
Using System.ServiceModel
Using SampleServiceLib
vi) Build the project successfully.
vii) Add the following console.Writeline codes to program.cs so that the final Program.cs Should look Like as below.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using SampleServiceLib;
namespace SampleHost
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Sample Host of Sample Service is running....");
using (ServiceHost servicehost = new ServiceHost(typeof(SampleService)))
{
servicehost.Open();
Console.WriteLine("The SampleService is ready now...");
Console.WriteLine("Press enter to terminate the SampleService...");
}
Console.ReadLine();
}
}
}
viii) Adding the config File to the Host :
Go to the Solution Explorer of the Sample Host
Right Click Add New Item Application Configuration File
A file named app.config will be added to the solution.
Initial content of the file is given below
ix) Add the code inside the configuration tag of app.cofig so that the final app.cofig should look like as below
x) Build the Service host application and run it. You should get a console Window while host is running.
c) Building the Proxy to be used by client
Before building a client you need to build a proxy of the service which the client will use to interact with the service.
A proxy is nothing but a .cs file and a .config file generated by a tool called svcutil.exe using your service Sampleservice.dll
Steps to create the Proxy:
i) Create a Proxy folder in your c:\ drive.
ii) Search for the svcutil.exe file on your computer and copy it to the Proxy folder.
iii) Copy the dll of the service you created (sampleservice.dll) to this Proxy folder.
iv) Go to Start Run cmd
v) On the command prompt change the directory to Proxy folder.
vi) Run the following command
C:\ Proxy svcutil.exe SampleService.dll
This will create a few files in the current directory like
.wsdl, .xsd etc
vii) The run the following command
C:\ Proxy svcutil.exe *.wsdl *.xsd /language:C#
/out:SampleProxy.cs /config:app.config
It will create two files in the Proxy folder
SampleProxy.cs and app.config.
These are your proxy files to be used in the Client.
viii) Open the SampleProxy.cs file, it has the AnswerClient class which has the ObtainAnswer Method from SampleService.
d) Building WCF client
i) Open Visual Studio 2008
ii) Select Create Projectà C# Console Application name it “SampleClient”
iii) From Solution Explorer,Add the reference of System.ServiceModel to the project as before.
iv) Add the two proxy file SampleProxy.cs and app.config to the solution.
v) Open the app.config File .You will find that inside of client Tag,the endpoint tag does not have “address” attribute.
vi) add the attribute address="http://localhost:8080/SampleService" to the endpoint tag of the app.config file.
vii) Now add code to Program.cs so that final Program.cs should look like as below
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
namespace SampleClient
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Ask question");
//the name AnswerClient is generated autometically by svcutil.exe tool which creates
//chat proxy and app.cofig
//by browsing the service url after reference.
using (AnswerClient client = new AnswerClient())
{
Console.WriteLine("Your Question: ");
string question = Console.ReadLine();
string answer = client.ObtainAnswer(question);
Console.WriteLine(answer);
Console.ReadLine();
}
}
}
}
viii) Build the application. Now the client is ready.
e) Testing the working of the whole application
To Test the service follow the steps below.
i) Run the Sample Host Application
ii) Run the client application
iii) Write the following question on client console “What is my Profession”
iv) The reply fro service will come as “Your Profession is Software Developer.”
Q1. What is WCF?
WCF stands for Windows Communication Foundation. It is a Software development kit for developing services on Windows. WCF is introduced in .NET 3.0. in the System.ServiceModel namespace. WCF is based on basic concepts of Service oriented architecture (SOA)
Q2. What is endpoint in WCF service?
The endpoint is an Interface which defines how a client will communicate with the service. It consists of three main points: Address,Binding and Contract.
Q3. Explain Address,Binding and contract for a WCF Service?
Address:Address defines where the service resides.
Binding:Binding defines how to communicate with the service.
Contract:Contract defines what can be done with the service.
Q4. What are the various address format in WCF?
a)HTTP Address Format:--> http://localhost:
b)TCP Address Format:--> net.tcp://localhost:
c)MSMQ Address Format:--> net.msmq://localhost:
Q5. What are the types of binding available in WCF?
A binding is identified by the transport it supports and the encoding it uses. Transport may be HTTP,TCP etc and encoding may be text,binary etc. The popular types of binding may be as below:
a)BasicHttpBinding
b)NetTcpBinding
c)WSHttpBinding
d)NetMsmqBinding
Q6. What are the types of contract available in WCF?
The main contracts are:
a)Service Contract:Describes what operations the client can perform.
b)Operation Contract : defines the method inside Interface of Service.
c)Data Contract:Defines what data types are passed
d)Message Contract:Defines wheather a service can interact directly with messages
Q7. What are the various ways of hosting a WCF Service?
a)IIS b)Self Hosting c)WAS (Windows Activation Service)
Q8. WWhat is the proxy for WCF Service?
A proxy is a class by which a service client can Interact with the service.
By the use of proxy in the client application we are able to call the different methods exposed by the service
Q9. How can we create Proxy for the WCF Service?
We can create proxy using the tool svcutil.exe after creating the service.
We can use the following command at command line.
svcutil.exe *.wsdl *.xsd /language:C# /out:SampleProxy.cs /config:app.config
Q10.What is the difference between WCF Service and Web Service?
a)WCF Service supports both http and tcp protocol while webservice supports only http protocol.
b)WCF Service is more flexible than web service.
Assuming that the reader has no Background in WCF, there are a number of key concepts that needs to be explained in order for the full application to be understood.
So I will just explain each of these a little bit at a time, so that the final application will be a little easier to understand.
Key Concepts:
a) What is WCF?
WCF stands for Windows Communication Foundation.
WCF is advanced API (Application Programming Interface) for creating distributed applications using .NET framework.
It is introduced in .NET 3.0.
Distributed system in its simplest form is two executable running and exchanging data.
WCF API is found in System.ServiceModel namespace.
WCF is based on basic concepts of Service oriented architecture (SOA)
b) What is a WCF Service?
A WCF service is a program that exposes a collection of Endpoints (connections) for communicating with either client applications or other service applications.
c) What are the components of WCF application?
There are three main components of a WCF application
i) a WCF service
ii) a WCF service host
iii) a WCF service client
d) What is the “ABC” of a WCF Service?
“ABC” of WCF stands for addresses Bindings and contracts respectively.
i) Addresses: This is location of the service in the form of an
URI (Uniform resource Identifier) generally mentioned
In the config file.
ii) Bindings: This includes the type of network protocol used by the
Service. For Example HTTP, TCP/IP or others.
iii) Contracts: This is in fact the methods exposed by the WCF service.
e) What is a Service Contract in WCF application?
Service contract is the name of the attribute which is applied to an interface in a WCF service.
f) What is an Operation Contract in WCF application?
Operation contract is the name of the attribute which is applied to a method inside the interface of a WCF service
6. The demo Service with code
Before I start, I would like to remind you again that this is the simplest of WCF service only for understanding purpose. In real world you might have to build/face much more complicated WCF service.
I have divided this part in five sub-parts as below.
a) Building the WCF service
b) Building the WCF host
c) Building the Proxy to be used by client
d) Building WCF client
e) Testing the working of the whole application.
a) Building the WCF service
To understand the service better we will build the service as a c# class library project. Follow the following steps:
In my case it created the class1.cs with content as below.
i) Open Visual Studio 2008
ii) Select Create Projectà C# class library name it “Sample Service”
iii) It will crate a .cs file in the project. Open that file.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace SampleService
{
public class Class1
{
}
}
Change the namespace SampleService to SampleServiceLib,
Rename the Class1 to SampleService.
Rename the Class1.cs file in the solutionExplorer to SampleService.cs
Add the namesapce using System.ServiceModel at the top.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
namespace SampleServiceLib
{
public class SampleService
{
}
}
The SampleService.cs file should now look like below.
iv) At this point the project will not build, so please add a reference to System.Service Model.
For this, Go to solution Explorer ,Right click on the reference Add Reference .NET Tab Select System.ServiceModel OK.
Now you can successfully build the Project.
v) Create an interface named IAnswer in this file inside SampleServiceLib namespace.Create a method inside the interface IAnswer, named ObtainAnswer The attributes for the interface and the method should be ServiceContract and OperationContract respectively
vi) Implement the IAnswer interface in SampleService class as
Shown in the code sample below.
namespace SampleServiceLib
{
public class SampleService : IAnswer
{
public string ObtainAnswer(string Question)
{
return "My Profession is Software Development";
}
}
[ServiceContract]
public interface IAnswer
{
[OperationContract]
string ObtainAnswer(string Question);
}
}
vii) Now ad a constructor to the class SampleService and the final code should look like this.Build this project.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
namespace SampleServiceLib
{
public class SampleService : IAnswer
{
public SampleService()
{
Console.WriteLine("Ask question to SampleService....");
}
public string ObtainAnswer(string Question)
{
return "Your Profession is Software Developer";
}
}
[ServiceContract]
public interface IAnswer
{
[OperationContract]
string ObtainAnswer(string Question);
}
}
viii) Save the sample service Project by File Save All. Then build it so that you will get a SampleSevice.dll in its bin\release directory.
b) Building the WCF host
A WCF host may be IIS (Internet Information Server) , Windows Service, A console application etc.The simplest of them is a console application host. So we will demonstrate that here.
Follow the following steps:
i) Open Visual Studio 2008
ii) Select Create Projectà C# Console Application name it “Sample Host”
iii) From Solution Explorer,Add the reference of System.ServiceModel to this project as before and
iv) also add the reference of SampleServiceLib.dll from SmpleService Class library project you created before by addreference Browse Tab Browse to the SampleServiceLib.dll in the project SampleService’s Bin/release folder.
v) Open its Program.cs file and add the following two namespace to the
Using Section.
Using System.ServiceModel
Using SampleServiceLib
vi) Build the project successfully.
vii) Add the following console.Writeline codes to program.cs so that the final Program.cs Should look Like as below.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using SampleServiceLib;
namespace SampleHost
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Sample Host of Sample Service is running....");
using (ServiceHost servicehost = new ServiceHost(typeof(SampleService)))
{
servicehost.Open();
Console.WriteLine("The SampleService is ready now...");
Console.WriteLine("Press enter to terminate the SampleService...");
}
Console.ReadLine();
}
}
}
viii) Adding the config File to the Host :
Go to the Solution Explorer of the Sample Host
Right Click Add New Item Application Configuration File
A file named app.config will be added to the solution.
Initial content of the file is given below
ix) Add the code inside the configuration tag of app.cofig so that the final app.cofig should look like as below
x) Build the Service host application and run it. You should get a console Window while host is running.
c) Building the Proxy to be used by client
Before building a client you need to build a proxy of the service which the client will use to interact with the service.
A proxy is nothing but a .cs file and a .config file generated by a tool called svcutil.exe using your service Sampleservice.dll
Steps to create the Proxy:
i) Create a Proxy folder in your c:\ drive.
ii) Search for the svcutil.exe file on your computer and copy it to the Proxy folder.
iii) Copy the dll of the service you created (sampleservice.dll) to this Proxy folder.
iv) Go to Start Run cmd
v) On the command prompt change the directory to Proxy folder.
vi) Run the following command
C:\ Proxy svcutil.exe SampleService.dll
This will create a few files in the current directory like
.wsdl, .xsd etc
vii) The run the following command
C:\ Proxy svcutil.exe *.wsdl *.xsd /language:C#
/out:SampleProxy.cs /config:app.config
It will create two files in the Proxy folder
SampleProxy.cs and app.config.
These are your proxy files to be used in the Client.
viii) Open the SampleProxy.cs file, it has the AnswerClient class which has the ObtainAnswer Method from SampleService.
d) Building WCF client
i) Open Visual Studio 2008
ii) Select Create Projectà C# Console Application name it “SampleClient”
iii) From Solution Explorer,Add the reference of System.ServiceModel to the project as before.
iv) Add the two proxy file SampleProxy.cs and app.config to the solution.
v) Open the app.config File .You will find that inside of client Tag,the endpoint tag does not have “address” attribute.
vi) add the attribute address="http://localhost:8080/SampleService" to the endpoint tag of the app.config file.
vii) Now add code to Program.cs so that final Program.cs should look like as below
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
namespace SampleClient
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Ask question");
//the name AnswerClient is generated autometically by svcutil.exe tool which creates
//chat proxy and app.cofig
//by browsing the service url after reference.
using (AnswerClient client = new AnswerClient())
{
Console.WriteLine("Your Question: ");
string question = Console.ReadLine();
string answer = client.ObtainAnswer(question);
Console.WriteLine(answer);
Console.ReadLine();
}
}
}
}
viii) Build the application. Now the client is ready.
e) Testing the working of the whole application
To Test the service follow the steps below.
i) Run the Sample Host Application
ii) Run the client application
iii) Write the following question on client console “What is my Profession”
iv) The reply fro service will come as “Your Profession is Software Developer.”
Q1. What is WCF?
WCF stands for Windows Communication Foundation. It is a Software development kit for developing services on Windows. WCF is introduced in .NET 3.0. in the System.ServiceModel namespace. WCF is based on basic concepts of Service oriented architecture (SOA)
Q2. What is endpoint in WCF service?
The endpoint is an Interface which defines how a client will communicate with the service. It consists of three main points: Address,Binding and Contract.
Q3. Explain Address,Binding and contract for a WCF Service?
Address:Address defines where the service resides.
Binding:Binding defines how to communicate with the service.
Contract:Contract defines what can be done with the service.
Q4. What are the various address format in WCF?
a)HTTP Address Format:--> http://localhost:
b)TCP Address Format:--> net.tcp://localhost:
c)MSMQ Address Format:--> net.msmq://localhost:
Q5. What are the types of binding available in WCF?
A binding is identified by the transport it supports and the encoding it uses. Transport may be HTTP,TCP etc and encoding may be text,binary etc. The popular types of binding may be as below:
a)BasicHttpBinding
b)NetTcpBinding
c)WSHttpBinding
d)NetMsmqBinding
Q6. What are the types of contract available in WCF?
The main contracts are:
a)Service Contract:Describes what operations the client can perform.
b)Operation Contract : defines the method inside Interface of Service.
c)Data Contract:Defines what data types are passed
d)Message Contract:Defines wheather a service can interact directly with messages
Q7. What are the various ways of hosting a WCF Service?
a)IIS b)Self Hosting c)WAS (Windows Activation Service)
Q8. WWhat is the proxy for WCF Service?
A proxy is a class by which a service client can Interact with the service.
By the use of proxy in the client application we are able to call the different methods exposed by the service
Q9. How can we create Proxy for the WCF Service?
We can create proxy using the tool svcutil.exe after creating the service.
We can use the following command at command line.
svcutil.exe *.wsdl *.xsd /language:C# /out:SampleProxy.cs /config:app.config
Q10.What is the difference between WCF Service and Web Service?
a)WCF Service supports both http and tcp protocol while webservice supports only http protocol.
b)WCF Service is more flexible than web service.
Introduction to DataBinding in Silverlight
Introduction to DataBinding in Silverlight
DataBinding is a link between a data source and a user interface. The data source provides data to the user interface. The data in the user interface may be changed by the user which will be updated to the source and could be saved back to the database.
The data source could be business objects, collections, database tables or any other form of data that support data binding.
In this chapter, we will use a simple class called "Address" with the following properties:
1. Name
2. Address1
3. Address2
4. City
5. State
6. Zip code
Let us create a Silverlight control which accepts user's name and address. You can create a xaml control which has the following TextBlock elements:
1. Name
2. Address1
3. Address2
4. City
5. State
6. Zip code
Here is the XAML which defines a grid and places the appropraite controls for our sample:
<Grid x:Name="LayoutRoot" Background="White" Loaded="LayoutRoot_Loaded">
<Grid.RowDefinitions>
<RowDefinition Height="30"></RowDefinition>
<RowDefinition Height="30"></RowDefinition>
<RowDefinition Height="30"></RowDefinition>
<RowDefinition Height="30"></RowDefinition>
<RowDefinition Height="30"></RowDefinition>
<RowDefinition Height="30"></RowDefinition>
<RowDefinition Height="30"></RowDefinition>
<RowDefinition Height="30"></RowDefinition>
<RowDefinition Height="30"></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
</Grid.ColumnDefinitions>
<TextBlock Text="Name" Grid.Row="0" Grid.Column="0"></TextBlock>
<TextBlock Text="Address 1" Grid.Row="1" Grid.Column="0"></TextBlock>
<TextBlock Text="Address 2" Grid.Row="2" Grid.Column="0"></TextBlock>
<TextBlock Text="City" Grid.Row="3" Grid.Column="0"></TextBlock>
<TextBlock Text="State" Grid.Row="4" Grid.Column="0"></TextBlock>
<TextBlock Text="Zipcode" Grid.Row="5" Grid.Column="0"></TextBlock>
<TextBox x:Name="txtName" Text="{Binding Name, Mode=TwoWay}" Grid.Row="0" Grid.Column="1"></TextBox>
<TextBox x:Name="txtAddress1" Text="{Binding Address1, Mode=TwoWay}" Grid.Row="1" Grid.Column="1"></TextBox>
<TextBox x:Name="txtAddress2" Text="{Binding Address2, Mode=TwoWay}" Grid.Row="2" Grid.Column="1"></TextBox>
<TextBox x:Name="txtCity" Text="{Binding City, Mode=TwoWay}" Grid.Row="3" Grid.Column="1"></TextBox>
<TextBox x:Name="txtState" Text="{Binding State, Mode=TwoWay}" Grid.Row="4" Grid.Column="1"></TextBox>
<TextBox x:Name="txtZipcode" Text="{Binding Zipcode, Mode=TwoWay}" Grid.Row="5" Grid.Column="1"></TextBox>
<Button Grid.Row="6" Grid.Column="0" Grid.ColumnSpan="2" Width="50" Content="Save" x:Name="btnSave" Click="btnSave_Click"></Button>
</Grid>
The above XAML defines a grid with 7 rows and 2 columns. The controls are places in appropriate rows and columns using the Grid.Row and Grid.Column property of individual controls. When placed in a web page, our Silverlight control will look like this:
Now create a class called "Address" which has properties representing various fields we need. See the sample code for the "Address" class:
public class Address
{
public string Name { get; set; }
public string Address1 { get; set; }
public string Address2 { get; set; }
public string City { get; set; }
public string State { get; set; }
public string Zipcode { get; set; }
}
Go to the code behind file of the xaml class and create an instance of the Address class as shown below:
Address address;
In the constructor of the XAML page class, initialize the Address class and bind it to the UI elements as shown below:
address = new Address();
txtName.DataContext = address;
txtAddress1.DataContext = address;
txtAddress2.DataContext = address;
txtCity.DataContext = address;
txtState.DataContext = address;
txtZipcode.DataContext = address;
In the above code, we are setting the DataContext property of each UI control to our "Address" object. But how do the control know which property of the address object to be used ? This is handled in the XAML. Take a look at the "txtAddress1" control. You can see that the property "Text" is set as shown below:
Text="{Binding Address1, Mode=TwoWay}"
The above line defines that we are using data binding for the "Text" property of this control, and it will use the property "Address1" of whatever object it will be bound to. Also, it states that the Mode is "TwoWay" which means the value will be read from the object and set to the "Text" property and also when the value is changed in the textbox control, it is saved back to the data source. In our case, we are binding our Address object to the textbox control. When loaded, it will display the default value from our object in the textbox. When the value is changed by the user, the datasource object will be updated with the new value from text box.
Typically, when we add a new address, the object will be initialized to empty values and the textboxes will be empty. When we edit an existing address, the object will have values populated from database and it will be displayed in the UI controls using the databinding. When values are modified by the user, the datasource object will be automatically modified. All we have to do is, save the modified datasource object in to the database.
Silverlight Tutorial Part 5: Using the ListBox and DataBinding to Display List Data
This is part five of eight tutorials that walk through how to build a simple Digg client application using Silverlight 2. These tutorials are intended to be read in-order, and help explain some of the core programming concepts of Silverlight. Bookmark my Silverlight 2 Reference page for more of Silverlight posts and content.
<Download Code> Click here to download a completed version of this Digg client sample. </Download Code>
Displaying our Digg Stories using the ListBox and DataBinding
Previously we've been using the DataGrid control to display our Digg stories. This works great when we want to display the content in a column format. For our Digg application, though, we probably want to tweak the appearance a little more and have it look less like a DataGrid of stories and more like a List of them. The good news is that this easy - and it doesn't require us to change any of our application code to accomplish this.
We'll start by replacing our DataGrid control with a <ListBox> control. We'll keep the control name the same as before ("StoriesList"):
When we run our application again and search for stories, the ListBox will display the following results:
You might be wondering - why is each item "DiggSample.DiggStory"? The reason for this is because we are binding DiggStory objects to the ListBox (and the default behavior is to call ToString() on them). If we want to display the "Title" property of the DiggStory object instead, we can set the "DisplayMemberPath" property on the ListBox:
When we do this the Title will be what is displayed in the ListBox:
If we want to show more than one value at a time, or customize the layout of each item more, we can override the ListBox control's ItemTemplate and supply a custom DataTemplate. Within this DataTemplate we can customize how each DiggStory object is displayed.
For example, we could display both the DiggStory Title and NumDiggs value using a DataTemplate like below.
We can databind any public properties we want from our DiggStory object within the DataTemplate. Notice above how we are using the {Binding Path=PropertyName} syntax to accomplish this with the two TextBlock controls.
With the above DataTemplate in place, our ListBox will now display its items like below:
Let's then go one step further and change our DataTemplate to the one below. This DataTemplate uses two StackPanels - one to stack row items horizontally, and one to stack some textblocks together vertically:
The above DataTemplate causes our ListBox to display items like the screen-shot below:
when we define the following Style rules in our App.xaml (note how we are using a LinearGradientBrush to get the nice yellow gradient background on the DiggPanel):
One important thing to notice about our ListBox - even though we have customized what the items in it look like, it still automatically provides support for hover and item selection semantics. This is true both when using the mouse and when using the keyboard (up/down arrow keys, home/end, etc):
The ListBox also supports full flow resizing - and will provide automatic scrolling of our custom content when necessary (notice how the horizontal scroll bar appears as the window gets smaller):
Next Steps
We've now switched our data visualization to be List based, and cleaned up the content listing of it.
Let's now complete the last bits of the functionality behavior in the application - and implement a master/details workflow which allows end-users to drill into the specifics of a story when they select an article from the list. To-do that let's jump to our next tutorial: Using User Controls to Implement Master/Detail Scenarios.
Element Data Binding
Element data binding allows you to bind element properties to each other. In previous versions of Silverlight, this would require more work on the code side because the element would fire its changed method and have that update the necessary elements. Silverlight 3 simplifies this process by performing the task directly in XAML.
In this tutorial, we will show you how to use element data binding for a variety of scenarios.
Element Binding
Element binding is performed in the same manner as Data Binding with one addition: the ElementNameproperty. ElementName defines the name of the binding source element.
The following code snippet shows the basic syntax for element binding. The TextBlock is databound toelement's Value property.
<TextBlock Text="{Binding ElementName=element, Path=Value}" />
Slider and TextBlock Scenario
The TextBlock control can maintain the value of the Slider control. This can be used to inform the user of the selected value. When the user moves the slider, the textblock is refreshed with its value.
<StackPanel Orientation="Horizontal" Margin="5">
<Slider x:Name="slider1" Minimum="1" Maximum="100" Width="100" Margin="5" />
<TextBlock Text="{Binding ElementName=slider1, Path=Value}" Width="100" Margin="5" />
</StackPanel>
Slider and TextBox Scenario
The TextBox and Slider controls can manipulate each other using TwoWay binding. This is useful when you want your users to have multiple ways to enter numerical data.
<StackPanel Orientation="Horizontal" Margin="5">
<Slider x:Name="slider2" Minimum="1" Maximum="100" Width="100" Margin="5" />
<TextBox Text="{Binding ElementName=slider2, Path=Value, Mode=TwoWay}" />
</StackPanel>
Sliders and Image Scenario
Slider controls can be used to manipulate a variety of element properties. The following examples demonstrate how a slider control can resize the image and manipulate its rotation.
<Grid HorizontalAlignment="Left" Margin="5">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Slider x:Name="slider3" Minimum="160" Maximum="640" Value="200" Width="100"
<Image Grid.Row="1"
Width="{Binding ElementName=slider3, Path=Value}"
Height="{Binding ElementName=slider3, Path=Value}"
Source="Autumn Leaves.jpg" />
</Grid>
<Grid HorizontalAlignment="Left" Margin="5">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Slider x:Name="slider4" Minimum="0" Maximum="360" Width="100"
Value="{Binding RotationX, Mode=TwoWay, ElementName=projection}" />
<Image Grid.Row="1" Width="160" Height="120" Source="Autumn Leaves.jpg">
<Image.Projection>
<PlaneProjection x:Name="projection" />
</Image.Projection>
</Image>
</Grid>
Selection Scenario
Selection events are useful for element binding with the TextBlock control to display the currently selected item.
<StackPanel Margin="5" >
<controls:Calendar x:Name="cal" />
<TextBlock
Text="{Binding ElementName=cal, Path=SelectedDate}"
Margin="5" HorizontalAlignment="Center" />
</StackPanel>
<StackPanel Margin="5" Width="150">
<ComboBox x:Name="cb">
<sys:String>Apple</sys:String>
<sys:String>Banana</sys:String>
<sys:String>Orange</sys:String>
</ComboBox>
<TextBlock
Text="{Binding ElementName=cb, Path=SelectedItem}"
Margin="5" HorizontalAlignment="Center" />
</StackPanel>
<StackPanel Margin="5" Orientation="Horizontal">
<ListBox x:Name="lb">
<sys:String>Apple</sys:String>
<sys:String>Banana</sys:String>
<sys:String>Orange</sys:String>
</ListBox>
<TextBlock Text="{Binding ElementName=lb, Path=SelectedItem}" Margin="5" />
</StackPanel>
Conclusion
Element Binding extends Silverlight's capabilities by providing advanced binding among XAML elements. The feature also reduces the amount of code required to connect the elements. As shown in this tutorial, there are several scenarios in which element binding can perform powerful binding in minimal XAML code.
Accessing Data Using Silverlight
In this lesson of the Silverlight tutorial, you will learn...
1.Work with XML data in Silverlight
2.Store data to and retrieve data from isolated storage using Silverlight
This lesson will introduce the how to store and retrieve data using Silverlight.
Storing Data in Code
When working with data programmatically, data is typically stored in memory for later reference, while other operations are carried out, or while the data stored in memory is manipulated. Data may be entered by a user, retrieved from a data source, or created programmatically.
Variables
The most basic means of storing data in memory is through the use of variables. All programming languages support some form of variables. A variable is a named location in memory used to store data. The specifics of how data is stored and managed in memory is particular to a programming language. Strongly-typed programming languages are very strict about what type of data can be stored in a variable. Weakly-typed programming languages are not strict about what type of data can be stored in a variable. Strongly-typed programming languages are generally more efficient than weakly-typed programming languages.
Silverlight may be coded using several languages. Some of the languages used in Silverlight, such as JavaScript, are weakly-typed, while others, such as C#, are strongly-typed. A developer must thoroughly understand how to work with variables in the language that they choose for working with Silverlight. The code snippet below illustrates declaration and initialization of a simple integer type variable in C# named x.
// simple variable. int x = 1;
Collections
Most programming languages support not only storing a single piece of data in a named location in memory but also support storing multiple pieces of data in a named location in memory. A collection is a named location in memory, similar to a variable, that is structured for storing multiple pieces of data. Depending upon the programming language used, multiple types of collections may be supported. For example, C# supports simple arrays, ArrayLists, Stacks, Queues, and HashTables. Each type of collection supported is structured for storing and retrieving data in a different fashion.
Collections are located in the System.Collections namespace. The code snippet below illustrates declaration and initialization of a standard string array named customerNames.
// store customer information in an ArrayList. string[]
customerNames = new string[3]; customerNames[0] = "Shannon Horn";
customerNames[1] = "Benny Madrid"; customerNames[2] = "Edwin Dewees";
Generics
Collections are versatile and simplify data storage in code by making it easier to store and transport multiple data items and objects. However, standard collections have some drawbacks as well. A standard collection, including an ArrayList, Stack, Queue, and HashTable, stores data internally as a simple object. By storing data as a simple object, a standard collection can be used to store any type of data. In a nutshell, in C#, a standard collection is a weakly-typed construct that exists in a strongly-typed language. The internal storage design of a standard collection affects performance and type safety negatively.
When a data item is stored in a standard collection, it must be converted to a simple object type. When a data item stored in a standard collection is removed from the collection, it must be converted from a simple object type to the destination type. The process of converting data to and from a simple object degrades performance. Additionally, a simple object can be converted to any more complex type. However, there is no guarantee that the data stored as a simple object will be correctly represented when removed from the standard collection and converted to a more complex type. For example, a complex object that represents data about a customer may be stored in a collection and then removed from the collection and converted to a string. The code written to perform the operation should compile but will, more than likely, cause errors to occur at runtime. hence, type safety is lost.
In the .NET Framework, generic collections are located in the System.Collections.Generic namespace. A generic collection is a strongly-typed collection and requires that the data type to be used for storage be specified at the time the collection is instantiated.
// a generic collection for storing customer names as
strings. List<string> customerNames = new List<string>(3);
customerNames.Add("Shannon Horn"); customerNames.Add("Benny Madrid");
customerNames.Add("Edwin Dewees");
In the code snippet above, the customerNames generic collection will only store string values however the collection could be configured to store and manage any valid .NET type.
Working with XML
The Extensible Markup Language (XML) was released by the World Wide Web Consortium (W3C - http://www.w3.org) in 1999 as a standardized means of storing and transporting data over the Web. XML has proliferated Web development technologies and virtually all software development platforms support some form of XML interaction. The .NET Framework contains a gamut of classes for working with XML data in the System.Xml namespace.
Silverlight contains a subset of XML functionality in the System.Xml namespace. XML data can be read using the XmlReader class and XML data can be written using the XmlWriter class. Additionally, Silverlight includes a class used to specify configuration settings to be used when writing XML data, the XmlWriterSettings class. If configuration settings are not specified using the XmlWriterSettings class, default configuration settings are used. In the code listing below, the XmlReader class, the XmlWriter class, and the XmlWriterSettings class are used to read in a well-formed XML string, parse it, and write the contents of it to a TextBlock.
using System; using System.Collections.Generic; using
System.Linq; using System.Net; using System.Windows; using
System.Windows.Controls; using System.Windows.Documents; using
System.Windows.Input; using System.Windows.Media; using
System.Windows.Media.Animation; using System.Windows.Shapes; using System.Xml;
using System.Text; using System.IO; namespace ADXmlReader { public partial class
Page : UserControl { public Page() { InitializeComponent(); } private void
UserControl_Loaded(object sender, RoutedEventArgs e) { // store names as XML.
string names = "<?xml version='1.0' encoding='utf-8' ?><Names><Name>Shannon
Horn</Name><Name>Benny Madrid</Name><Name>Edwin Dewees</Name></Names>"; //
create a reader. XmlReader reader = XmlReader.Create(new StringReader(names));
XmlWriterSettings settings = new XmlWriterSettings(); settings.Indent = true;
settings.ConformanceLevel = ConformanceLevel.Auto; StringBuilder output = new
StringBuilder(); XmlWriter writer = XmlWriter.Create(output, settings); //
display the names. while (reader.Read()) { if (reader.NodeType ==
XmlNodeType.Text) { writer.WriteString(reader.Value + Environment.NewLine); } }
reader.Close(); writer.Close(); tbNames.Text = output.ToString(); } } }
The results of the code listing above are shown in the figure below.
Language Integrated Query (LINQ)
A major addition to the .NET Framework in version 3.5 is Language Integrated Query (LINQ). Most seasoned developers have mastered or are adequately familiar with the Structured Query Language (SQL). SQL is used to query relational database data. However, in many cases, SQL queries that pull data from a relational database schema are abstracted away from business logic and middle-tier code.
Data may also be stored in formats other than a relational database such as an XML file or a consumed Web service. In each data storage scenario, typically, a specialized language is used to retrieve and query the contained data. Furthermore, data is generally represented at the business logic and code level through objects, arrays, and collections. Developers regularly have to search these constructs by using tailor-made loops.
Many programmers have long requested a language for querying data stored in programming constructs and object oriented mechanisms. SQL is a stable and well-entrenched industry standard. It would be an insurmountable task to attempt to extend SQL so that it could be used to query programming constructs and other data sources. However, Microsoft was determined to make things easier for programmers by creating a standard for querying data stored in multiple data storage mechanisms and coding constructs. The result of their efforts was a new query language that targets data stored in objects and collections, Language Integrated Query (LINQ). LINQ was also extended to be able to query relational data stored in databases, XML data, and other data sources. However, data queried by using LINQ must be stored as objects. If data is queried from a relational data source using LINQ, it must first be represented using an object model. (see footnote)
LINQ is capable of querying any object programmatically that implements the IEnumerable interface. LINQ will present an entirely new programming paradigm to experienced .NET developers but the new functionality and benefits thereof should be quickly enjoyed and adapted by most. To summarize, the primary benefits of using LINQ are a single, consistent language for querying data across any type of data source and a means of doing so that is type safe and supported by the most popular .NET Framework programming languages.
LINQ has grown into an extensive query language. Additionally, in order to make LINQ relevant and a valid solution into the future, Microsoft designed LINQ to be extensible so that it can be extended by Microsoft or third party vendors to support additional data sources. Comprehensive coverage of LINQ is beyond the scope of this course. However, as an example, we will create a simple LINQ query example here using Silverlight. Silverlight supports LINQ using classes in the System.Linq namespace.
The first step in working with LINQ is to identify a data source. In the example created here, we store a list of names in a simple string array. The second step in working with LINQ is to create the LINQ query. A LINQ query uses very similar concepts and vocabulary as an SQL query, however the clauses are presented in a different order. Finally, the third step in working with LINQ is to execute the query. A LINQ query is executed using a foreach loop in C#. The code snippet below illustrates a simple LINQ query against a list of names in a string array. The LINQ query below uses the where clause to filter out all names except those that begin with the letter "E".
// obtain the data source. // list of names. string[]
namesList = new string[3] { "Shannon Horn","Benny Madrid","Edwin Dewees"}; //
create the query. var names = from name in namesList where name.Substring(0, 1)
== "E" select name; // execute the query. foreach (string name in names) {
tbOutput.Text = name; }
The results of the code snippet above are shown in the figure below.
For more information about Language Integrated Query (LINQ), visit the MSDN article entitled Language Integrated Query (LINQ) located at http://msdn.microsoft.com/en-us/library/bb397926.aspx.
Isolated Storage
Due to the security constraints placed upon a Silverlight application (the "sandbox" that it operates in), a Silverlight application cannot write directly to or read directly from the file system on the client's machine. In an effort to allow developers to store some data local to the client, Microsoft designed Silverlight to read data from and write data to a virtual file system called Isolated Storage. Isolated storage is stored inside a User's Application Data directory:
Location of Isolated Storage in Vista
C:\Users\AppData\LocalLow\Microsoft\Silverlight\is
Location of Isolated Storage in Windows XP
C:\Documents and Settings\Local Settings\Application Data\Microsoft\Silverlight\is
Silverlight isolated storage is currently limited to a 100 KB capacity and the classes used to work with isolated storage are located in the System.IO.IsolatedStorage namespace. Isolated Storage is Non-Volatile, and is not cleared by actions such as when the user clears the browser cache or deletes cookies. The code snippet below illustrates saving a user's login credentials to isolated storage in a file named UserCredentials.txt.
// remember the user's credentials for next time. if
(chkRememberMe.IsChecked == true) { using (IsolatedStorageFile isoStore =
IsolatedStorageFile.GetUserStoreForApplication()) { using
(IsolatedStorageFileStream isoStream = new
IsolatedStorageFileStream("UserCredentials.txt", FileMode.Create, isoStore)) {
using (StreamWriter writer = new StreamWriter(isoStream)) {
writer.Write(user.UserName + "|" + user.PasswordHash); } } } }
The code snippet above illustrates using the IsolatedStorageFile class and the IsolatedStorageFileStream class to work with isolated storage. The code snippet below illustrates using the same classes to determine if the UserCredentials.txt file exists in isolated storage and, if it does exist, reads the contents of the file.
// determine if the user's credentials exist in isolated
storage. using (IsolatedStorageFile isoStore =
IsolatedStorageFile.GetUserStoreForApplication()) { using
(IsolatedStorageFileStream isoStream = new
IsolatedStorageFileStream("UserCredentials.txt", FileMode.Open, isoStore)) {
using (StreamReader reader = new StreamReader(isoStream)) { // read the
credentials. string[] sb = reader.ReadLine().Split('|'); // do we have
credentials? if (sb.Length > 0) { // if the credentials exist, parse them out
and authenticate them. user.UserName = sb[0]; user.Password = sb[1]; //
authenticate. svc.AuthenticateUserAsync(user.UserName, user.Password); } } } }
Data Binding
Much of a database oriented application involves reading data from a database and presenting that data to the user. One way to handle filling User Interface elements with data from a database is to simply assign values through code. The code snippet below shows how this might be done...
// assume we have an "Athlete" class as follows: public class
AthleteDisplayInfo { public int AthleteId { get; set; } public string FirstName
{get; set;} public string LastName { get; set; } } // we then retrieve an
athlete from the database AthleteDisplayInfo athlete = e.Result; // we can then
fill UI elements, such as textboxes txtFirstName.Text = athlete.FirstName;
txtLastName.Text = athlete.LastName; // and also get back the values after the
user updates... athlete.FirstName = txtFirstName.Text; athlete.LastName =
txtLastName.Text;
The method shown above is quite adequate for filling UI elements with data values, but it does not allow for separation of User Interface from Business Logic Classes. Without separating our user interface from our business logic code, it will be more difficult to test the application, and have teams of designers and developers work cooperatively on the same project.
This is where data binding comes in. Using data binding, we can declaratively assign values to UI elements instead of using code. Furthermore, the data binding will automatically synchronize changes to the data source to the UI elements.To implement data binding, we use a special syntax in XAML, inside any attribute value: "{Binding PropertyName, Mode=OneWay}" - where "PropertyName" is the property of a data source class, and Mode is either OneTime, OneWay, or TwoWay.
Consider this example:
<TextBox x:Name="txtLastName" Text="{Binding LastName,
Mode=OneWay}" />
The XAML above will automatically fill the "Text" property of txtLastName when databinding occurs. We can tell UI elements what their binding source is by using the DataContext property. The DataContext property can be assigned to a Container Control, such as a Canvas or Grid, and all child controls within that container will receive their bound data from that DataContext. For example, if txtLastName from the example above exists within a Canvas container named "LayoutRoot", then we can assign a business logic class to LayoutRoot.DataContext:
LayoutRoot.DataContext = athlete;
The assignment to DataContext above would cause txtLastName to show the value of athlete.LastName in its Text property.
Data Binding Modes
When you are specifying the Mode for data binding, you have three choices:
OneTime: Updates the target property when the binding is created.
OneWay: Updates the target property when the binding is created. Changes to the source object can also propogate to the target.
TwoWay: Updates either the target or the source object when either change. When the binding is created, the target property is updated from the source.
If you have a read-only UI element where the source data does not change, you might consider using OneTime mode data binding. If you have a read-only UI element, and the user may be selecting different records at times (causing the source data to change), you might consider using OneWay databinding. TwoWay databinding is handy in Master/Details scenarios, where a DataGrid can be linked to controls in a "Detail" section of the screen.
Accessing Data Using Silverlight Conclusion
Lab: Accessing Data In Silverlight
In this lab, you will extend the athlete management application login dialog by providing the user the option to save their credentials and automatically login on future visits. The user credentials will be stored in isolated storage.
Store User Credentials in Isolated Storage
30 45
In this exercise, you will store user credentials in isolated storage.
1.Let's improve the login dialog by adding a checkbox to the canvas so that users can select an option to automatically log them in on follow-up visits. We'll implement this by storing the user's login credentials in isolated storage. Bear in mind that isolated storage is not guaranteed to be persistent. Isolated storage presents a virtual file system to the developer by using cookies. If a user deletes the associated cookies, they will remove their login information and will be required to login again on following visits (just as with any Web site).
2.We will need to add references to the System.IO and System.IO.IsolatedStorage namespace. Add this to the top of the Page.xaml.cs code file:
using System.IO.IsolatedStorage; using System.IO;
3.The AuthenticateUserCompleted event is the place we'll want to store the user's information in isolated storage if they select the checkbox for us to do so. That way we don't forget to store the credentials away at a later point. When writing to isolated storage, you can gain access to the isolated storage mechanism through the System.IO.IsolatedStorage.IsolatedStorageFile class. Once an instance of the file class is created, a stream must be created for reading from and writing to the file. Finally, a file stream is used to actually write into the stream. The example version of the updated AuthenticateUserCompleted event is shown below:
void svc_AuthenticateUserCompleted(object sender, AthleteManager.AthleteService.AuthenticateUserCompletedEventArgs e) { if (e.Result) { ucLoginStatus1.IsLoggedIn = true; // remember the user's credentials for next time. if (chkRememberMe.IsChecked == true) { using (IsolatedStorageFile isoStore = IsolatedStorageFile.GetUserStoreForApplication()) { using (IsolatedStorageFileStream isoStream = new IsolatedStorageFileStream("UserCredentials.txt", FileMode.Create, isoStore)) { using (StreamWriter writer = new StreamWriter(isoStream)) { writer.Write(txtUserName.Text + "|" + txtPassword.Password); } } } } } else { ucLoginStatus1.IsLoggedIn = false; } }
4.Next, we'll need to read the user's credentials from isolated storage on follow up visits, if the information is stored in isolated storage. We'll want to completely subvert the login dialog in this scenario, if we can, so we'll add code to the code behind class constructor to check for the user's credentials in isolated storage.
5.The process of reading from isolated storage is almost exactly the opposite to the process of writing to isolated storage. The updated example code behind constructor is shown below:
public Page() { InitializeComponent(); svc.AuthenticateUserCompleted += new EventHandler<AthleteManager.AthleteService.AuthenticateUserCompletedEventArgs>(svc_AuthenticateUserCompleted); // determine if the user's credentials exist in isolated storage. using (IsolatedStorageFile isoStore = IsolatedStorageFile.GetUserStoreForApplication()) { using (IsolatedStorageFileStream isoStream = new IsolatedStorageFileStream("UserCredentials.txt", FileMode.Open, isoStore)) { using (StreamReader reader = new StreamReader(isoStream)) { // read the credentials. string[] sb = reader.ReadLine().Split('|'); // if the credentials exist, parse them out and authenticate them. string username = sb[0]; string password = sb[1]; // authenticate. svc.AuthenticateUserAsync(username, password); } } } btnLogin.Click += new RoutedEventHandler(btnLogin_Click); }
Add Controls to Display Athlete Information
45 60
In this exercise, you will add controls to the athlete management application design area to display athlete information.
1.Let's enhance our web service so that it can read Athlete information from the database. First, add a few namespace imports to the top of AthleteService.cs in the web project:
using System.Data.SqlClient; using System.Configuration; using System.Data;
2.We need a Connection object to the database. Add this declaration just inside the AthleteService class:
SqlConnection cn = new SqlConnection(ConfigurationManager.ConnectionStrings["athleteDB"].ConnectionString);
3.Next we add a new web service method to AthleteService.cs to retrieve the athlete information:
[WebMethod] public List<Athlete> ReadAthletes() { List<Athlete> athletes = new List<Athlete>(); cn.Open(); using (SqlCommand cmd = new SqlCommand("select * from Athletes", cn)) { cmd.CommandType = CommandType.Text; SqlDataReader rdr = cmd.ExecuteReader(); if (rdr.HasRows) { Athlete athlete; while (rdr.Read()) { athlete = new Athlete(); athlete.AthleteId = int.Parse(rdr["AthleteId"].ToString()); athlete.SportId = int.Parse(rdr["SportId"].ToString()); athlete.FirstName = rdr["FirstName"].ToString(); athlete.LastName = rdr["LastName"].ToString(); athlete.Address = rdr["Address"].ToString(); athlete.City = rdr["City"].ToString(); athlete.State = rdr["State"].ToString(); athlete.Zip = rdr["Zip"].ToString(); athletes.Add(athlete); } } } cn.Close(); cn.Dispose(); return athletes; }
4.Since we have added a method to the Web Service, we need to refresh the Service Reference from the Silverlight application. In the Silverlight project, expand the Service References node and then right-click the AthleteService control and select "Update Service Reference." Then, wire up the event handler for the call to ReadAthletes on the web service. Place this code in the Page constructor, just after the event wire-up for AuthenticateUserCompleted:
svc.ReadAthletesCompleted += new EventHandler<AthleteManager.AthleteService.ReadAthletesCompletedEventArgs>(svc_ReadAthletesCompleted);
5.The next step of the process is to display the athletes that are in the database in a datagrid. The datagrid is a control that is included in the Silverlight SDK. It might be easiest to set the visibility of the login dialog to Collapsed while designing the DataGrid and data display. Add code to the svc_AuthenticateUserCompleted event handler to hide the login dialog if the user has successfully authenticated, and call the ReadAthletesAsync method of the web service:
canvasLogin.Visibility = Visibility.Collapsed; svc.ReadAthletesAsync();
6.Drag a DataGrid from the toolbox to the Silverlight XAML. Assign the DataGrid a name and set the AutoGenerateColumns property to True.
<my:DataGrid x:Name="grdAthletes" AutoGenerateColumns="True"></my:DataGrid>
7.In the ReadAthletesCompleted callback event handler, write code to set the results of the method as the DataGrid ItemSource. We are returning an array of athlete objects from the ReadAthletes method.
void svc_ReadAthletesCompleted(object sender, AthleteManager.AthleteService.ReadAthletesCompletedEventArgs e) { grdAthletes.ItemsSource = e.Result; }
8.If you find that the DataGrid is not displaying data correctly, ensure that you specify Height and Width property values for the DataGrid. Test the Silverlight control to ensure that the DataGrid is displaying data correctly.
9.Modify the Silverlight control by adding additional controls for displaying athlete information, and buttons for Save, Add New and Delete. Use Expression Blend to design this data entry form. First create a new Canvas named canvasMain and be sure to place all of the following controls inside the Canvas (we will later show/hide this Canvas as necessary). The figures below illustrate the controls added to canvasMain and the resulting appearance.
1.txtFirstName: A TextBox for first name.
2.txtLastName: A TextBox for last name.
3.txtAddress: A TextBox for address.
4.txtCity: A TextBox for city.
5.txtState: A TextBox for state.
6.txtZip: A TextBox for zip.
7.btnSave: A button to save the current record.
8.btnAddNew: A button for entering "new record" mode.
9.btnDelete: A button for deleting the current record.
10.Complete the Silverlight control by adding additional controls to the control for displaying athlete information.
11.Add Data Binding markup syntax to the textboxes in XAML so that they show the value of the fields when databound:
<TextBox Height="20" x:Name="txtFirstName" Width="137" Canvas.Left="89" Canvas.Top="255" Text="{Binding FirstName, Mode=TwoWay}" TextWrapping="Wrap" /> <TextBox Height="20" x:Name="txtLastName" Width="137" Text="{Binding LastName, Mode=TwoWay}" TextWrapping="Wrap" Canvas.Top="255" Canvas.Left="240"/> <TextBox Height="20" x:Name="txtAddress" Width="285" Text="{Binding Address, Mode=TwoWay}" TextWrapping="Wrap" Canvas.Left="89" Canvas.Top="288"/> <TextBox Height="20" x:Name="txtCity" Width="99" Text="{Binding City, Mode=TwoWay}" TextWrapping="Wrap" Canvas.Left="89" Canvas.Top="320"/> <TextBox Height="20" x:Name="txtState" Width="29.539" Text="{Binding State, Mode=TwoWay}" TextWrapping="Wrap" Canvas.Left="240" Canvas.Top="320"/> <TextBox Height="20" x:Name="txtZip" Width="60" Text="{Binding Zip, Mode=TwoWay}" TextWrapping="Wrap" Canvas.Top="320" Canvas.Left="314"/>
12.Ensure that the new controls only display when the user has successfully logged into the application. You can do this by adding code to the svc_AuthenticateUserCompleted event:
canvasMain.Visibility = Visibility.Visible;
13.Add an event handler to the DataGrid SelectionChange event. In the event handler, set the DataContext to data bind the values displayed in the controls to the athlete information for the currently selected athlete in the DataGrid list. The example code is shown below.
void grdAthletes_SelectionChanged(object sender, SelectionChangedEventArgs e) { AthleteService.Athlete athlete = (AthleteService.Athlete)grdAthletes.SelectedItem; LayoutRoot.DataContext = athlete; }
14.Run the application. You should be able to browse the available records.
15.Next we'll add update capabilities to the Save, Delete and Add New buttons. Inside the AthleteService.cs Web Service class, add the following two Web Methods:
[WebMethod] public void SaveAthlete(Athlete athlete) { string sqlText = string.Empty; if (athlete.AthleteId > 0) sqlText = "update Athletes set FirstName=@FirstName, LastName=@LastName, Address=@Address, City=@City, State=@State, Zip=@Zip where AthleteId = @AthleteId"; else sqlText = "insert into Athletes (FirstName, LastName, Address, City, State, Zip) values (@FirstName, @LastName, @Address, @City, @State, @Zip)"; cn.Open(); using (SqlCommand cmd = new SqlCommand(sqlText, cn)) { cmd.Parameters.Add(new SqlParameter("@FirstName", athlete.FirstName)); cmd.Parameters.Add(new SqlParameter("@LastName", athlete.LastName)); cmd.Parameters.Add(new SqlParameter("@Address", athlete.Address)); cmd.Parameters.Add(new SqlParameter("@City", athlete.City)); cmd.Parameters.Add(new SqlParameter("@State", athlete.State)); cmd.Parameters.Add(new SqlParameter("@Zip", athlete.Zip)); cmd.Parameters.Add(new SqlParameter("@AthleteId", athlete.AthleteId)); cmd.CommandType = CommandType.Text; cmd.ExecuteNonQuery(); } cn.Close(); cn.Dispose(); } [WebMethod] public void DeleteAthlete(Athlete athlete) { string sqlText = "delete from Athletes where AthleteId = @AthleteId"; cn.Open(); using (SqlCommand cmd = new SqlCommand(sqlText, cn)) { cmd.CommandType = CommandType.Text; cmd.ExecuteNonQuery(); } cn.Close(); cn.Dispose(); }
16.Build the application and then refresh the Service References in the Silverlight project again as you did in a previous step (right-click the AthleteService reference and select "Update Service Reference.")
17.Inside Page.xaml.cs, inside the constructor, wire up the Completed event handlers for the new Save and Delete methods:
svc.DeleteAthleteCompleted += new EventHandler<System.ComponentModel.AsyncCompletedEventArgs>(svc_DeleteAthleteCompleted); svc.SaveAthleteCompleted += new EventHandler<System.ComponentModel.AsyncCompletedEventArgs>(svc_SaveAthleteCompleted);
18.Now wire up the click event handlers for our Save, Add New, and Delete buttons. Add this to the Page.xaml.cs constructor code:
btnSave.Click += new RoutedEventHandler(btnSave_Click); btnAddNew.Click += new RoutedEventHandler(btnAddNew_Click); btnDelete.Click += new RoutedEventHandler(btnDelete_Click);
19.Lastly, we can call the web methods inside the button handers.
void btnDelete_Click(object sender, RoutedEventArgs e) { AthleteService.Athlete athlete = (LayoutRoot.DataContext as AthleteService.Athlete); svc.DeleteAthleteAsync(athlete); } void btnAddNew_Click(object sender, RoutedEventArgs e) { AthleteService.Athlete athlete = new AthleteService.Athlete(); LayoutRoot.DataContext = athlete; } void btnSave_Click(object sender, RoutedEventArgs e) { AthleteService.Athlete athlete = (LayoutRoot.DataContext as AthleteService.Athlete); svc.SaveAthleteAsync(athlete); }
20.Run the application, and try adding, updating and deleting a record.
Error. This text should not be shown. Please email courseware@webucator.com to report it:
Lab: Accessing Data In Silverlight
In this lab, you will extend the athlete management application login dialog by providing the user the option to save their credentials and automatically login on future visits. The user credentials will be stored in isolated storage.
Exercise: Store User Credentials in Isolated Storage
Duration: 30 to 45 minutes.
In this exercise, you will store user credentials in isolated storage.
1.Let's improve the login dialog by adding a checkbox to the canvas so that users can select an option to automatically log them in on follow-up visits. We'll implement this by storing the user's login credentials in isolated storage. Bear in mind that isolated storage is not guaranteed to be persistent. Isolated storage presents a virtual file system to the developer by using cookies. If a user deletes the associated cookies, they will remove their login information and will be required to login again on following visits (just as with any Web site).
2.We will need to add references to the System.IO and System.IO.IsolatedStorage namespace. Add this to the top of the Page.xaml.cs code file:
using System.IO.IsolatedStorage; using System.IO;
3.The AuthenticateUserCompleted event is the place we'll want to store the user's information in isolated storage if they select the checkbox for us to do so. That way we don't forget to store the credentials away at a later point. When writing to isolated storage, you can gain access to the isolated storage mechanism through the System.IO.IsolatedStorage.IsolatedStorageFile class. Once an instance of the file class is created, a stream must be created for reading from and writing to the file. Finally, a file stream is used to actually write into the stream. The example version of the updated AuthenticateUserCompleted event is shown below:
void svc_AuthenticateUserCompleted(object sender,
AthleteManager.AthleteService.AuthenticateUserCompletedEventArgs e) { if
(e.Result) { ucLoginStatus1.IsLoggedIn = true; // remember the user's
credentials for next time. if (chkRememberMe.IsChecked == true) { using
(IsolatedStorageFile isoStore =
IsolatedStorageFile.GetUserStoreForApplication()) { using
(IsolatedStorageFileStream isoStream = new
IsolatedStorageFileStream("UserCredentials.txt", FileMode.Create, isoStore)) {
using (StreamWriter writer = new StreamWriter(isoStream)) {
writer.Write(txtUserName.Text + "|" + txtPassword.Password); } } } } } else {
ucLoginStatus1.IsLoggedIn = false; } }
4.Next, we'll need to read the user's credentials from isolated storage on follow up visits, if the information is stored in isolated storage. We'll want to completely subvert the login dialog in this scenario, if we can, so we'll add code to the code behind class constructor to check for the user's credentials in isolated storage.
5.The process of reading from isolated storage is almost exactly the opposite to the process of writing to isolated storage. The updated example code behind constructor is shown below:
public Page() { InitializeComponent();
svc.AuthenticateUserCompleted += new
EventHandler<AthleteManager.AthleteService.AuthenticateUserCompletedEventArgs>(svc_AuthenticateUserCompleted);
// determine if the user's credentials exist in isolated storage. using
(IsolatedStorageFile isoStore =
IsolatedStorageFile.GetUserStoreForApplication()) { using
(IsolatedStorageFileStream isoStream = new
IsolatedStorageFileStream("UserCredentials.txt", FileMode.Open, isoStore)) {
using (StreamReader reader = new StreamReader(isoStream)) { // read the
credentials. string[] sb = reader.ReadLine().Split('|'); // if the credentials
exist, parse them out and authenticate them. string username = sb[0]; string
password = sb[1]; // authenticate. svc.AuthenticateUserAsync(username,
password); } } } btnLogin.Click += new RoutedEventHandler(btnLogin_Click); }
Exercise: Add Controls to Display Athlete Information
Duration: 45 to 60 minutes.
In this exercise, you will add controls to the athlete management application design area to display athlete information.
1.Let's enhance our web service so that it can read Athlete information from the database. First, add a few namespace imports to the top of AthleteService.cs in the web project:
using System.Data.SqlClient; using
System.Configuration; using System.Data;
2.We need a Connection object to the database. Add this declaration just inside the AthleteService class:
SqlConnection cn = new
SqlConnection(ConfigurationManager.ConnectionStrings["athleteDB"].ConnectionString);
3.Next we add a new web service method to AthleteService.cs to retrieve the athlete information:
[WebMethod] public List<Athlete>
ReadAthletes() { List<Athlete> athletes = new List<Athlete>(); cn.Open(); using
(SqlCommand cmd = new SqlCommand("select * from Athletes", cn)) {
cmd.CommandType = CommandType.Text; SqlDataReader rdr = cmd.ExecuteReader(); if
(rdr.HasRows) { Athlete athlete; while (rdr.Read()) { athlete = new Athlete();
athlete.AthleteId = int.Parse(rdr["AthleteId"].ToString()); athlete.SportId =
int.Parse(rdr["SportId"].ToString()); athlete.FirstName =
rdr["FirstName"].ToString(); athlete.LastName = rdr["LastName"].ToString();
athlete.Address = rdr["Address"].ToString(); athlete.City =
rdr["City"].ToString(); athlete.State = rdr["State"].ToString(); athlete.Zip =
rdr["Zip"].ToString(); athletes.Add(athlete); } } } cn.Close(); cn.Dispose();
return athletes; }
4.Since we have added a method to the Web Service, we need to refresh the Service Reference from the Silverlight application. In the Silverlight project, expand the Service References node and then right-click the AthleteService control and select "Update Service Reference." Then, wire up the event handler for the call to ReadAthletes on the web service. Place this code in the Page constructor, just after the event wire-up for AuthenticateUserCompleted:
svc.ReadAthletesCompleted += new
EventHandler<AthleteManager.AthleteService.ReadAthletesCompletedEventArgs>(svc_ReadAthletesCompleted);
5.The next step of the process is to display the athletes that are in the database in a datagrid. The datagrid is a control that is included in the Silverlight SDK. It might be easiest to set the visibility of the login dialog to Collapsed while designing the DataGrid and data display. Add code to the svc_AuthenticateUserCompleted event handler to hide the login dialog if the user has successfully authenticated, and call the ReadAthletesAsync method of the web service:
canvasLogin.Visibility = Visibility.Collapsed; svc.ReadAthletesAsync();
6.Drag a DataGrid from the toolbox to the Silverlight XAML. Assign the DataGrid a name and set the AutoGenerateColumns property to True.
<my:DataGrid x:Name="grdAthletes" AutoGenerateColumns="True"></my:DataGrid>
7.In the ReadAthletesCompleted callback event handler, write code to set the results of the method as the DataGrid ItemSource. We are returning an array of athlete objects from the ReadAthletes method.
void
svc_ReadAthletesCompleted(object sender,
AthleteManager.AthleteService.ReadAthletesCompletedEventArgs e) {
grdAthletes.ItemsSource = e.Result; }
8.If you find that the DataGrid is not displaying data correctly, ensure that you specify Height and Width property values for the DataGrid. Test the Silverlight control to ensure that the DataGrid is displaying data correctly.
9.Modify the Silverlight control by adding additional controls for displaying athlete information, and buttons for Save, Add New and Delete. Use Expression Blend to design this data entry form. First create a new Canvas named canvasMain and be sure to place all of the following controls inside the Canvas (we will later show/hide this Canvas as necessary). The figures below illustrate the controls added to canvasMain and the resulting appearance.
1.txtFirstName: A TextBox for first name.
2.txtLastName: A TextBox for last name.
3.txtAddress: A TextBox for address.
4.txtCity: A TextBox for city.
5.txtState: A TextBox for state.
6.txtZip: A TextBox for zip.
7.btnSave: A button to save the current record.
8.btnAddNew: A button for entering "new record" mode.
9.btnDelete: A button for deleting the current record.
10.Complete the Silverlight control by adding additional controls to the control for displaying athlete information.
11.Add Data Binding markup syntax to the textboxes in XAML so that they show the value of the fields when databound:
<TextBox Height="20" x:Name="txtFirstName" Width="137" Canvas.Left="89"
Canvas.Top="255" Text="{Binding FirstName, Mode=TwoWay}" TextWrapping="Wrap" />
<TextBox Height="20" x:Name="txtLastName" Width="137" Text="{Binding LastName,
Mode=TwoWay}" TextWrapping="Wrap" Canvas.Top="255" Canvas.Left="240"/> <TextBox
Height="20" x:Name="txtAddress" Width="285" Text="{Binding Address,
Mode=TwoWay}" TextWrapping="Wrap" Canvas.Left="89" Canvas.Top="288"/> <TextBox
Height="20" x:Name="txtCity" Width="99" Text="{Binding City, Mode=TwoWay}"
TextWrapping="Wrap" Canvas.Left="89" Canvas.Top="320"/> <TextBox Height="20"
x:Name="txtState" Width="29.539" Text="{Binding State, Mode=TwoWay}"
TextWrapping="Wrap" Canvas.Left="240" Canvas.Top="320"/> <TextBox Height="20"
x:Name="txtZip" Width="60" Text="{Binding Zip, Mode=TwoWay}" TextWrapping="Wrap"
Canvas.Top="320" Canvas.Left="314"/>
12.Ensure that the new controls only display when the user has successfully logged into the application. You can do this by adding code to the svc_AuthenticateUserCompleted event:
canvasMain.Visibility = Visibility.Visible;
13.Add an event handler to the DataGrid SelectionChange event. In the event handler, set the DataContext to data bind the values displayed in the controls to the athlete information for the currently selected athlete in the DataGrid list. The example code is shown below.
void grdAthletes_SelectionChanged(object sender, SelectionChangedEventArgs e) {
AthleteService.Athlete athlete =
(AthleteService.Athlete)grdAthletes.SelectedItem; LayoutRoot.DataContext =
athlete; }
14.Run the application. You should be able to browse the available records.
15.Next we'll add update capabilities to the Save, Delete and Add New buttons. Inside the AthleteService.cs Web Service class, add the following two Web Methods:
[WebMethod] public void SaveAthlete(Athlete athlete) {
string sqlText = string.Empty; if (athlete.AthleteId > 0) sqlText = "update
Athletes set FirstName=@FirstName, LastName=@LastName, Address=@Address,
City=@City, State=@State, Zip=@Zip where AthleteId = @AthleteId"; else sqlText =
"insert into Athletes (FirstName, LastName, Address, City, State, Zip) values
(@FirstName, @LastName, @Address, @City, @State, @Zip)"; cn.Open(); using
(SqlCommand cmd = new SqlCommand(sqlText, cn)) { cmd.Parameters.Add(new
SqlParameter("@FirstName", athlete.FirstName)); cmd.Parameters.Add(new
SqlParameter("@LastName", athlete.LastName)); cmd.Parameters.Add(new
SqlParameter("@Address", athlete.Address)); cmd.Parameters.Add(new
SqlParameter("@City", athlete.City)); cmd.Parameters.Add(new
SqlParameter("@State", athlete.State)); cmd.Parameters.Add(new
SqlParameter("@Zip", athlete.Zip)); cmd.Parameters.Add(new
SqlParameter("@AthleteId", athlete.AthleteId)); cmd.CommandType =
CommandType.Text; cmd.ExecuteNonQuery(); } cn.Close(); cn.Dispose(); }
[WebMethod] public void DeleteAthlete(Athlete athlete) { string sqlText =
"delete from Athletes where AthleteId = @AthleteId"; cn.Open(); using
(SqlCommand cmd = new SqlCommand(sqlText, cn)) { cmd.CommandType =
CommandType.Text; cmd.ExecuteNonQuery(); } cn.Close(); cn.Dispose(); }
16.Build the application and then refresh the Service References in the Silverlight project again as you did in a previous step (right-click the AthleteService reference and select "Update Service Reference.")
17.Inside Page.xaml.cs, inside the constructor, wire up the Completed event handlers for the new Save and Delete methods:
svc.DeleteAthleteCompleted += new
EventHandler<System.ComponentModel.AsyncCompletedEventArgs>(svc_DeleteAthleteCompleted);
svc.SaveAthleteCompleted += new
EventHandler<System.ComponentModel.AsyncCompletedEventArgs>(svc_SaveAthleteCompleted);
18.Now wire up the click event handlers for our Save, Add New, and Delete buttons. Add this to the Page.xaml.cs constructor code:
btnSave.Click += new
RoutedEventHandler(btnSave_Click); btnAddNew.Click += new
RoutedEventHandler(btnAddNew_Click); btnDelete.Click += new
RoutedEventHandler(btnDelete_Click);
19.Lastly, we can call the web methods inside the button handers.
void btnDelete_Click(object sender, RoutedEventArgs e) { AthleteService.Athlete
athlete = (LayoutRoot.DataContext as AthleteService.Athlete);
svc.DeleteAthleteAsync(athlete); } void btnAddNew_Click(object sender,
RoutedEventArgs e) { AthleteService.Athlete athlete = new
AthleteService.Athlete(); LayoutRoot.DataContext = athlete; } void
btnSave_Click(object sender, RoutedEventArgs e) { AthleteService.Athlete athlete
= (LayoutRoot.DataContext as AthleteService.Athlete);
svc.SaveAthleteAsync(athlete); }
20.Run the application, and try adding, updating and deleting a record.
In this lesson of the Silverlight tutorial, you
Managed data by using LINQ
Stored and retrieved XML using Silverlight
Stored data to and retrieved data from isolated storage
Footnotes
1.Comprehensive coverage of LINQ is well beyond the scope of this course. To learn more about LINQ, visit the LINQ Developer Center (the LINQ Project) located at http://msdn2.microsoft.com/en-us/netframework/aa904594.aspx.
To continue to learn Silverlight go to the top of this page and click on the next lesson in this Silverlight Tutorial's Table of Contents.
Tutorial on Silverlight 4 databinding in code-behind, custom user controls, etc.
19102010
Introduction
This small tutorial was written to show the students the following aspects of Silverlight:
Writing a class that can be used for databinding
Perform data-binding through code instead of XAML
Creating a custom user control
Writing simple data converters
Suppose we are creating a Silverlight game in which each player is represented as a pawn. However, the player class itself is somewhere deep inside the game-engine and we would like the pawn user control to be only loosely coupled to this player class. By doing this, we are able to make a rapid Silverlight prototype and if we later decide that the frontend is pretty lame, we can simply redesign it without too much fuss.
Player class
We create a small class that represents a player, with its name, color and location:
public class Player
{
private string name;
public string Name {
get { return name; }
set { name = value; }
}
private Point location;
public Point Location {
get { return location; }
set { location = value; }
}
private Color color;
public Color Color {
get { return color; }
set { color = value; }
}
}
For two-way databinding to work in Silverlight (and WPF) the Player class needs to implement the INotifyPropertyChanged interface:
public class Player: INotifyPropertyChanged
{
private string name;
public string Name {
get { return name; }
set {
name = value;
NotifyPropertyChanged("Name");
}
}
private Point location;
public Point Location {
get { return location; }
set {
location = value;
NotifyPropertyChanged("Location");
}
}
private Color color;
public Color Color {
get { return color; }
set {
color = value;
NotifyPropertyChanged("Color");
}
}
//Notify
public event PropertyChangedEventHandler PropertyChanged;
public void NotifyPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this,
new PropertyChangedEventArgs(propertyName));
}
}
}
We can now create a Player object anywhere it’s needed, e.g. :
Player player1 = new Player() {
Location = new Point(0, 0),
Name = "Tim",
Color=Colors.Blue };
Creating a user control
We create a custom user control that will represent the player in the game. Right-click your project and choose “Add new item…”. Next pick Silverlight User Control and give the control a meaningful name, such as pawn.
Set the DesignHeight and DesignWidth to 30 and then insert the following the XAML-code:
<Grid x:Name="LayoutRoot" Background="{x:Null}" >
<Ellipse x:Name="playerEllipse" Stroke="Black"
StrokeThickness="2" Height="30" Width="30" Fill="#FFFF1717"/>
</Grid>
By defining Background=”{x:Null} we make sure that the background of our control is transparent and thus will blend nicely on the game-board.
It is important to explicitly name each element if we wish to be able to bind certain properties to it later on.
Adding the user control to a canvas
Suppose we define a canvas somewhere on our MainPage.xaml:
<Canvas x:Name="playboardCanvas" Background="#FFD7FF07"
Width="400" Height="200">
Yeah, it’s a very ugly color, but let’s keep the design to other people.
If we wish to add the newly created user control to this canvas we need to perform the following steps:
1. Create a new instance of the usercontrol
2. Define any bindings needed
3. Add the control to the children of the canvas
This results in:
//Step 1
Pawn pawn = new Pawn();
//Step 2: bindings and datacontext comes here (discussed further on)
//Step 3
playboardCanvas.Children.Add(pawn);
Binding the pawn control to the player class
In order for the pawn to be bound to the player, we first point the pawns datacontext to the player:
pawn.DataContext = player1;
We then create a binding object in which we will bind the location of the player to the location of the pawn on the canvas.
//Bind location.X
Binding c = new Binding();
c.Source = player1;
c.Path = new PropertyPath("Location.X");
c.Mode = BindingMode.OneWay;
pawn.SetBinding(Canvas.LeftProperty, c);
We do the same for the Y-coordinate, only this one needs to be bound to the TopProperty of the pawn:
pawn.SetBinding(Canvas.TopProperty, c);
Writing a convertor
Suppose we defined the Location of our player to be an (x,y)coordinate between (0,0) and (8,8) (for example to define a pawn on a checkerboard). Our previously databound pawn would then be able to move between the (0,0) and (8,8) zone on the canvas…that’s a pretty small canvas.
We’ll write convertor that takes the actual dimensions of the canvas on the screen in account. The convertor will then transform the Location of the player to an equivalent location on the canvas.
The convertor is pretty straightforward. value will contain the X or Y coordinate of the player, and the extra parameter will contain a reference to the canvas on which the pawn is drawn:
public class CanvasLocationWidthConvertor : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
Canvas canv = (Canvas)parameter;
return (double)value * (canv.ActualWidth / 5);
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
We now simply add the convertor to the binding object we created earlier, so our binding code now is:
//Bind location.Y
Binding c = new Binding();
c.Source = player1;
c.Path = new PropertyPath("Location.X");
c.Mode = BindingMode.OneWay;
c.Converter = new CanvasLocationWidthConvertor();
c.ConverterParameter = playboardCanvas;
pionCanvas.SetBinding(Canvas.LeftProperty, c);
Binding the color
To bind the color of the player object to the pawn, we write the following binding in which the fillproperty of the ellipse is bound to the Color property:
Binding e = new Binding();
e.Source = player1;
e.Path = new PropertyPath("Color");
e.Mode = BindingMode.OneWay;
e.Converter = new PlayerColorConvertor();
pionCanvas.pionEllipse.SetBinding(Ellipse.FillProperty, e);
Since the FillProperty is defined by a SolidColorBrush instead of a Color we have to write a small convertor for that. Again, pretty straightforward:
public class PlayerColorConvertor : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return new SolidColorBrush((Color)value);
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
Binding to a grid
The fun thing of databinding in Silverlight (and WPF) is that we kind bind any property of an object to any property of an XAML element. Suppose we defined a 5-by-5 checkerboard grid in xaml (note: make your life easy and write this kind of stuff in the code behind using some loops) :
<Grid x:Name="playGrid" >
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Rectangle Grid.Row="0" Grid.Column="0" Fill="Black"></Rectangle>
<Rectangle Grid.Row="0" Grid.Column="2" Fill="Black"></Rectangle>
<Rectangle Grid.Row="0" Grid.Column="4" Fill="Black"></Rectangle>
<Rectangle Grid.Row="1" Grid.Column="1" Fill="Black"></Rectangle>
<Rectangle Grid.Row="1" Grid.Column="3" Fill="Black"></Rectangle>
<Rectangle Grid.Row="2" Grid.Column="0" Fill="Black"></Rectangle>
<Rectangle Grid.Row="2" Grid.Column="2" Fill="Black"></Rectangle>
<Rectangle Grid.Row="2" Grid.Column="4" Fill="Black"></Rectangle>
<Rectangle Grid.Row="3" Grid.Column="1" Fill="Black"></Rectangle>
<Rectangle Grid.Row="3" Grid.Column="3" Fill="Black"></Rectangle>
<Rectangle Grid.Row="4" Grid.Column="0" Fill="Black"></Rectangle>
<Rectangle Grid.Row="4" Grid.Column="2" Fill="Black"></Rectangle>
<Rectangle Grid.Row="4" Grid.Column="4" Fill="Black"></Rectangle>
</Grid>
Simply bind the X and Y coordinates of the player to the respective Grid.Row and Grid.Column properties of the playGrid object, e.g.:
//Bind location.X
Binding c2 = new Binding();
c2.Source = player1;
c2.Path = new PropertyPath("Location.X");
c2.Mode = BindingMode.OneWay;
playGrid.SetBinding(Grid.RowProperty,c2);
DataBinding is a link between a data source and a user interface. The data source provides data to the user interface. The data in the user interface may be changed by the user which will be updated to the source and could be saved back to the database.
The data source could be business objects, collections, database tables or any other form of data that support data binding.
In this chapter, we will use a simple class called "Address" with the following properties:
1. Name
2. Address1
3. Address2
4. City
5. State
6. Zip code
Let us create a Silverlight control which accepts user's name and address. You can create a xaml control which has the following TextBlock elements:
1. Name
2. Address1
3. Address2
4. City
5. State
6. Zip code
Here is the XAML which defines a grid and places the appropraite controls for our sample:
<Grid x:Name="LayoutRoot" Background="White" Loaded="LayoutRoot_Loaded">
<Grid.RowDefinitions>
<RowDefinition Height="30"></RowDefinition>
<RowDefinition Height="30"></RowDefinition>
<RowDefinition Height="30"></RowDefinition>
<RowDefinition Height="30"></RowDefinition>
<RowDefinition Height="30"></RowDefinition>
<RowDefinition Height="30"></RowDefinition>
<RowDefinition Height="30"></RowDefinition>
<RowDefinition Height="30"></RowDefinition>
<RowDefinition Height="30"></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
</Grid.ColumnDefinitions>
<TextBlock Text="Name" Grid.Row="0" Grid.Column="0"></TextBlock>
<TextBlock Text="Address 1" Grid.Row="1" Grid.Column="0"></TextBlock>
<TextBlock Text="Address 2" Grid.Row="2" Grid.Column="0"></TextBlock>
<TextBlock Text="City" Grid.Row="3" Grid.Column="0"></TextBlock>
<TextBlock Text="State" Grid.Row="4" Grid.Column="0"></TextBlock>
<TextBlock Text="Zipcode" Grid.Row="5" Grid.Column="0"></TextBlock>
<TextBox x:Name="txtName" Text="{Binding Name, Mode=TwoWay}" Grid.Row="0" Grid.Column="1"></TextBox>
<TextBox x:Name="txtAddress1" Text="{Binding Address1, Mode=TwoWay}" Grid.Row="1" Grid.Column="1"></TextBox>
<TextBox x:Name="txtAddress2" Text="{Binding Address2, Mode=TwoWay}" Grid.Row="2" Grid.Column="1"></TextBox>
<TextBox x:Name="txtCity" Text="{Binding City, Mode=TwoWay}" Grid.Row="3" Grid.Column="1"></TextBox>
<TextBox x:Name="txtState" Text="{Binding State, Mode=TwoWay}" Grid.Row="4" Grid.Column="1"></TextBox>
<TextBox x:Name="txtZipcode" Text="{Binding Zipcode, Mode=TwoWay}" Grid.Row="5" Grid.Column="1"></TextBox>
<Button Grid.Row="6" Grid.Column="0" Grid.ColumnSpan="2" Width="50" Content="Save" x:Name="btnSave" Click="btnSave_Click"></Button>
</Grid>
The above XAML defines a grid with 7 rows and 2 columns. The controls are places in appropriate rows and columns using the Grid.Row and Grid.Column property of individual controls. When placed in a web page, our Silverlight control will look like this:
Now create a class called "Address" which has properties representing various fields we need. See the sample code for the "Address" class:
public class Address
{
public string Name { get; set; }
public string Address1 { get; set; }
public string Address2 { get; set; }
public string City { get; set; }
public string State { get; set; }
public string Zipcode { get; set; }
}
Go to the code behind file of the xaml class and create an instance of the Address class as shown below:
Address address;
In the constructor of the XAML page class, initialize the Address class and bind it to the UI elements as shown below:
address = new Address();
txtName.DataContext = address;
txtAddress1.DataContext = address;
txtAddress2.DataContext = address;
txtCity.DataContext = address;
txtState.DataContext = address;
txtZipcode.DataContext = address;
In the above code, we are setting the DataContext property of each UI control to our "Address" object. But how do the control know which property of the address object to be used ? This is handled in the XAML. Take a look at the "txtAddress1" control. You can see that the property "Text" is set as shown below:
Text="{Binding Address1, Mode=TwoWay}"
The above line defines that we are using data binding for the "Text" property of this control, and it will use the property "Address1" of whatever object it will be bound to. Also, it states that the Mode is "TwoWay" which means the value will be read from the object and set to the "Text" property and also when the value is changed in the textbox control, it is saved back to the data source. In our case, we are binding our Address object to the textbox control. When loaded, it will display the default value from our object in the textbox. When the value is changed by the user, the datasource object will be updated with the new value from text box.
Typically, when we add a new address, the object will be initialized to empty values and the textboxes will be empty. When we edit an existing address, the object will have values populated from database and it will be displayed in the UI controls using the databinding. When values are modified by the user, the datasource object will be automatically modified. All we have to do is, save the modified datasource object in to the database.
Silverlight Tutorial Part 5: Using the ListBox and DataBinding to Display List Data
This is part five of eight tutorials that walk through how to build a simple Digg client application using Silverlight 2. These tutorials are intended to be read in-order, and help explain some of the core programming concepts of Silverlight. Bookmark my Silverlight 2 Reference page for more of Silverlight posts and content.
<Download Code> Click here to download a completed version of this Digg client sample. </Download Code>
Displaying our Digg Stories using the ListBox and DataBinding
Previously we've been using the DataGrid control to display our Digg stories. This works great when we want to display the content in a column format. For our Digg application, though, we probably want to tweak the appearance a little more and have it look less like a DataGrid of stories and more like a List of them. The good news is that this easy - and it doesn't require us to change any of our application code to accomplish this.
We'll start by replacing our DataGrid control with a <ListBox> control. We'll keep the control name the same as before ("StoriesList"):
When we run our application again and search for stories, the ListBox will display the following results:
You might be wondering - why is each item "DiggSample.DiggStory"? The reason for this is because we are binding DiggStory objects to the ListBox (and the default behavior is to call ToString() on them). If we want to display the "Title" property of the DiggStory object instead, we can set the "DisplayMemberPath" property on the ListBox:
When we do this the Title will be what is displayed in the ListBox:
If we want to show more than one value at a time, or customize the layout of each item more, we can override the ListBox control's ItemTemplate and supply a custom DataTemplate. Within this DataTemplate we can customize how each DiggStory object is displayed.
For example, we could display both the DiggStory Title and NumDiggs value using a DataTemplate like below.
We can databind any public properties we want from our DiggStory object within the DataTemplate. Notice above how we are using the {Binding Path=PropertyName} syntax to accomplish this with the two TextBlock controls.
With the above DataTemplate in place, our ListBox will now display its items like below:
Let's then go one step further and change our DataTemplate to the one below. This DataTemplate uses two StackPanels - one to stack row items horizontally, and one to stack some textblocks together vertically:
The above DataTemplate causes our ListBox to display items like the screen-shot below:
when we define the following Style rules in our App.xaml (note how we are using a LinearGradientBrush to get the nice yellow gradient background on the DiggPanel):
One important thing to notice about our ListBox - even though we have customized what the items in it look like, it still automatically provides support for hover and item selection semantics. This is true both when using the mouse and when using the keyboard (up/down arrow keys, home/end, etc):
The ListBox also supports full flow resizing - and will provide automatic scrolling of our custom content when necessary (notice how the horizontal scroll bar appears as the window gets smaller):
Next Steps
We've now switched our data visualization to be List based, and cleaned up the content listing of it.
Let's now complete the last bits of the functionality behavior in the application - and implement a master/details workflow which allows end-users to drill into the specifics of a story when they select an article from the list. To-do that let's jump to our next tutorial: Using User Controls to Implement Master/Detail Scenarios.
Element Data Binding
Element data binding allows you to bind element properties to each other. In previous versions of Silverlight, this would require more work on the code side because the element would fire its changed method and have that update the necessary elements. Silverlight 3 simplifies this process by performing the task directly in XAML.
In this tutorial, we will show you how to use element data binding for a variety of scenarios.
Element Binding
Element binding is performed in the same manner as Data Binding with one addition: the ElementNameproperty. ElementName defines the name of the binding source element.
The following code snippet shows the basic syntax for element binding. The TextBlock is databound toelement's Value property.
<TextBlock Text="{Binding ElementName=element, Path=Value}" />
Slider and TextBlock Scenario
The TextBlock control can maintain the value of the Slider control. This can be used to inform the user of the selected value. When the user moves the slider, the textblock is refreshed with its value.
<StackPanel Orientation="Horizontal" Margin="5">
<Slider x:Name="slider1" Minimum="1" Maximum="100" Width="100" Margin="5" />
<TextBlock Text="{Binding ElementName=slider1, Path=Value}" Width="100" Margin="5" />
</StackPanel>
Slider and TextBox Scenario
The TextBox and Slider controls can manipulate each other using TwoWay binding. This is useful when you want your users to have multiple ways to enter numerical data.
<StackPanel Orientation="Horizontal" Margin="5">
<Slider x:Name="slider2" Minimum="1" Maximum="100" Width="100" Margin="5" />
<TextBox Text="{Binding ElementName=slider2, Path=Value, Mode=TwoWay}" />
</StackPanel>
Sliders and Image Scenario
Slider controls can be used to manipulate a variety of element properties. The following examples demonstrate how a slider control can resize the image and manipulate its rotation.
<Grid HorizontalAlignment="Left" Margin="5">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Slider x:Name="slider3" Minimum="160" Maximum="640" Value="200" Width="100"
<Image Grid.Row="1"
Width="{Binding ElementName=slider3, Path=Value}"
Height="{Binding ElementName=slider3, Path=Value}"
Source="Autumn Leaves.jpg" />
</Grid>
<Grid HorizontalAlignment="Left" Margin="5">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Slider x:Name="slider4" Minimum="0" Maximum="360" Width="100"
Value="{Binding RotationX, Mode=TwoWay, ElementName=projection}" />
<Image Grid.Row="1" Width="160" Height="120" Source="Autumn Leaves.jpg">
<Image.Projection>
<PlaneProjection x:Name="projection" />
</Image.Projection>
</Image>
</Grid>
Selection Scenario
Selection events are useful for element binding with the TextBlock control to display the currently selected item.
<StackPanel Margin="5" >
<controls:Calendar x:Name="cal" />
<TextBlock
Text="{Binding ElementName=cal, Path=SelectedDate}"
Margin="5" HorizontalAlignment="Center" />
</StackPanel>
<StackPanel Margin="5" Width="150">
<ComboBox x:Name="cb">
<sys:String>Apple</sys:String>
<sys:String>Banana</sys:String>
<sys:String>Orange</sys:String>
</ComboBox>
<TextBlock
Text="{Binding ElementName=cb, Path=SelectedItem}"
Margin="5" HorizontalAlignment="Center" />
</StackPanel>
<StackPanel Margin="5" Orientation="Horizontal">
<ListBox x:Name="lb">
<sys:String>Apple</sys:String>
<sys:String>Banana</sys:String>
<sys:String>Orange</sys:String>
</ListBox>
<TextBlock Text="{Binding ElementName=lb, Path=SelectedItem}" Margin="5" />
</StackPanel>
Conclusion
Element Binding extends Silverlight's capabilities by providing advanced binding among XAML elements. The feature also reduces the amount of code required to connect the elements. As shown in this tutorial, there are several scenarios in which element binding can perform powerful binding in minimal XAML code.
Accessing Data Using Silverlight
In this lesson of the Silverlight tutorial, you will learn...
1.Work with XML data in Silverlight
2.Store data to and retrieve data from isolated storage using Silverlight
This lesson will introduce the how to store and retrieve data using Silverlight.
Storing Data in Code
When working with data programmatically, data is typically stored in memory for later reference, while other operations are carried out, or while the data stored in memory is manipulated. Data may be entered by a user, retrieved from a data source, or created programmatically.
Variables
The most basic means of storing data in memory is through the use of variables. All programming languages support some form of variables. A variable is a named location in memory used to store data. The specifics of how data is stored and managed in memory is particular to a programming language. Strongly-typed programming languages are very strict about what type of data can be stored in a variable. Weakly-typed programming languages are not strict about what type of data can be stored in a variable. Strongly-typed programming languages are generally more efficient than weakly-typed programming languages.
Silverlight may be coded using several languages. Some of the languages used in Silverlight, such as JavaScript, are weakly-typed, while others, such as C#, are strongly-typed. A developer must thoroughly understand how to work with variables in the language that they choose for working with Silverlight. The code snippet below illustrates declaration and initialization of a simple integer type variable in C# named x.
// simple variable. int x = 1;
Collections
Most programming languages support not only storing a single piece of data in a named location in memory but also support storing multiple pieces of data in a named location in memory. A collection is a named location in memory, similar to a variable, that is structured for storing multiple pieces of data. Depending upon the programming language used, multiple types of collections may be supported. For example, C# supports simple arrays, ArrayLists, Stacks, Queues, and HashTables. Each type of collection supported is structured for storing and retrieving data in a different fashion.
Collections are located in the System.Collections namespace. The code snippet below illustrates declaration and initialization of a standard string array named customerNames.
// store customer information in an ArrayList. string[]
customerNames = new string[3]; customerNames[0] = "Shannon Horn";
customerNames[1] = "Benny Madrid"; customerNames[2] = "Edwin Dewees";
Generics
Collections are versatile and simplify data storage in code by making it easier to store and transport multiple data items and objects. However, standard collections have some drawbacks as well. A standard collection, including an ArrayList, Stack, Queue, and HashTable, stores data internally as a simple object. By storing data as a simple object, a standard collection can be used to store any type of data. In a nutshell, in C#, a standard collection is a weakly-typed construct that exists in a strongly-typed language. The internal storage design of a standard collection affects performance and type safety negatively.
When a data item is stored in a standard collection, it must be converted to a simple object type. When a data item stored in a standard collection is removed from the collection, it must be converted from a simple object type to the destination type. The process of converting data to and from a simple object degrades performance. Additionally, a simple object can be converted to any more complex type. However, there is no guarantee that the data stored as a simple object will be correctly represented when removed from the standard collection and converted to a more complex type. For example, a complex object that represents data about a customer may be stored in a collection and then removed from the collection and converted to a string. The code written to perform the operation should compile but will, more than likely, cause errors to occur at runtime. hence, type safety is lost.
In the .NET Framework, generic collections are located in the System.Collections.Generic namespace. A generic collection is a strongly-typed collection and requires that the data type to be used for storage be specified at the time the collection is instantiated.
// a generic collection for storing customer names as
strings. List<string> customerNames = new List<string>(3);
customerNames.Add("Shannon Horn"); customerNames.Add("Benny Madrid");
customerNames.Add("Edwin Dewees");
In the code snippet above, the customerNames generic collection will only store string values however the collection could be configured to store and manage any valid .NET type.
Working with XML
The Extensible Markup Language (XML) was released by the World Wide Web Consortium (W3C - http://www.w3.org) in 1999 as a standardized means of storing and transporting data over the Web. XML has proliferated Web development technologies and virtually all software development platforms support some form of XML interaction. The .NET Framework contains a gamut of classes for working with XML data in the System.Xml namespace.
Silverlight contains a subset of XML functionality in the System.Xml namespace. XML data can be read using the XmlReader class and XML data can be written using the XmlWriter class. Additionally, Silverlight includes a class used to specify configuration settings to be used when writing XML data, the XmlWriterSettings class. If configuration settings are not specified using the XmlWriterSettings class, default configuration settings are used. In the code listing below, the XmlReader class, the XmlWriter class, and the XmlWriterSettings class are used to read in a well-formed XML string, parse it, and write the contents of it to a TextBlock.
using System; using System.Collections.Generic; using
System.Linq; using System.Net; using System.Windows; using
System.Windows.Controls; using System.Windows.Documents; using
System.Windows.Input; using System.Windows.Media; using
System.Windows.Media.Animation; using System.Windows.Shapes; using System.Xml;
using System.Text; using System.IO; namespace ADXmlReader { public partial class
Page : UserControl { public Page() { InitializeComponent(); } private void
UserControl_Loaded(object sender, RoutedEventArgs e) { // store names as XML.
string names = "<?xml version='1.0' encoding='utf-8' ?><Names><Name>Shannon
Horn</Name><Name>Benny Madrid</Name><Name>Edwin Dewees</Name></Names>"; //
create a reader. XmlReader reader = XmlReader.Create(new StringReader(names));
XmlWriterSettings settings = new XmlWriterSettings(); settings.Indent = true;
settings.ConformanceLevel = ConformanceLevel.Auto; StringBuilder output = new
StringBuilder(); XmlWriter writer = XmlWriter.Create(output, settings); //
display the names. while (reader.Read()) { if (reader.NodeType ==
XmlNodeType.Text) { writer.WriteString(reader.Value + Environment.NewLine); } }
reader.Close(); writer.Close(); tbNames.Text = output.ToString(); } } }
The results of the code listing above are shown in the figure below.
Language Integrated Query (LINQ)
A major addition to the .NET Framework in version 3.5 is Language Integrated Query (LINQ). Most seasoned developers have mastered or are adequately familiar with the Structured Query Language (SQL). SQL is used to query relational database data. However, in many cases, SQL queries that pull data from a relational database schema are abstracted away from business logic and middle-tier code.
Data may also be stored in formats other than a relational database such as an XML file or a consumed Web service. In each data storage scenario, typically, a specialized language is used to retrieve and query the contained data. Furthermore, data is generally represented at the business logic and code level through objects, arrays, and collections. Developers regularly have to search these constructs by using tailor-made loops.
Many programmers have long requested a language for querying data stored in programming constructs and object oriented mechanisms. SQL is a stable and well-entrenched industry standard. It would be an insurmountable task to attempt to extend SQL so that it could be used to query programming constructs and other data sources. However, Microsoft was determined to make things easier for programmers by creating a standard for querying data stored in multiple data storage mechanisms and coding constructs. The result of their efforts was a new query language that targets data stored in objects and collections, Language Integrated Query (LINQ). LINQ was also extended to be able to query relational data stored in databases, XML data, and other data sources. However, data queried by using LINQ must be stored as objects. If data is queried from a relational data source using LINQ, it must first be represented using an object model. (see footnote)
LINQ is capable of querying any object programmatically that implements the IEnumerable interface. LINQ will present an entirely new programming paradigm to experienced .NET developers but the new functionality and benefits thereof should be quickly enjoyed and adapted by most. To summarize, the primary benefits of using LINQ are a single, consistent language for querying data across any type of data source and a means of doing so that is type safe and supported by the most popular .NET Framework programming languages.
LINQ has grown into an extensive query language. Additionally, in order to make LINQ relevant and a valid solution into the future, Microsoft designed LINQ to be extensible so that it can be extended by Microsoft or third party vendors to support additional data sources. Comprehensive coverage of LINQ is beyond the scope of this course. However, as an example, we will create a simple LINQ query example here using Silverlight. Silverlight supports LINQ using classes in the System.Linq namespace.
The first step in working with LINQ is to identify a data source. In the example created here, we store a list of names in a simple string array. The second step in working with LINQ is to create the LINQ query. A LINQ query uses very similar concepts and vocabulary as an SQL query, however the clauses are presented in a different order. Finally, the third step in working with LINQ is to execute the query. A LINQ query is executed using a foreach loop in C#. The code snippet below illustrates a simple LINQ query against a list of names in a string array. The LINQ query below uses the where clause to filter out all names except those that begin with the letter "E".
// obtain the data source. // list of names. string[]
namesList = new string[3] { "Shannon Horn","Benny Madrid","Edwin Dewees"}; //
create the query. var names = from name in namesList where name.Substring(0, 1)
== "E" select name; // execute the query. foreach (string name in names) {
tbOutput.Text = name; }
The results of the code snippet above are shown in the figure below.
For more information about Language Integrated Query (LINQ), visit the MSDN article entitled Language Integrated Query (LINQ) located at http://msdn.microsoft.com/en-us/library/bb397926.aspx.
Isolated Storage
Due to the security constraints placed upon a Silverlight application (the "sandbox" that it operates in), a Silverlight application cannot write directly to or read directly from the file system on the client's machine. In an effort to allow developers to store some data local to the client, Microsoft designed Silverlight to read data from and write data to a virtual file system called Isolated Storage. Isolated storage is stored inside a User's Application Data directory:
Location of Isolated Storage in Vista
C:\Users\AppData\LocalLow\Microsoft\Silverlight\is
Location of Isolated Storage in Windows XP
C:\Documents and Settings\Local Settings\Application Data\Microsoft\Silverlight\is
Silverlight isolated storage is currently limited to a 100 KB capacity and the classes used to work with isolated storage are located in the System.IO.IsolatedStorage namespace. Isolated Storage is Non-Volatile, and is not cleared by actions such as when the user clears the browser cache or deletes cookies. The code snippet below illustrates saving a user's login credentials to isolated storage in a file named UserCredentials.txt.
// remember the user's credentials for next time. if
(chkRememberMe.IsChecked == true) { using (IsolatedStorageFile isoStore =
IsolatedStorageFile.GetUserStoreForApplication()) { using
(IsolatedStorageFileStream isoStream = new
IsolatedStorageFileStream("UserCredentials.txt", FileMode.Create, isoStore)) {
using (StreamWriter writer = new StreamWriter(isoStream)) {
writer.Write(user.UserName + "|" + user.PasswordHash); } } } }
The code snippet above illustrates using the IsolatedStorageFile class and the IsolatedStorageFileStream class to work with isolated storage. The code snippet below illustrates using the same classes to determine if the UserCredentials.txt file exists in isolated storage and, if it does exist, reads the contents of the file.
// determine if the user's credentials exist in isolated
storage. using (IsolatedStorageFile isoStore =
IsolatedStorageFile.GetUserStoreForApplication()) { using
(IsolatedStorageFileStream isoStream = new
IsolatedStorageFileStream("UserCredentials.txt", FileMode.Open, isoStore)) {
using (StreamReader reader = new StreamReader(isoStream)) { // read the
credentials. string[] sb = reader.ReadLine().Split('|'); // do we have
credentials? if (sb.Length > 0) { // if the credentials exist, parse them out
and authenticate them. user.UserName = sb[0]; user.Password = sb[1]; //
authenticate. svc.AuthenticateUserAsync(user.UserName, user.Password); } } } }
Data Binding
Much of a database oriented application involves reading data from a database and presenting that data to the user. One way to handle filling User Interface elements with data from a database is to simply assign values through code. The code snippet below shows how this might be done...
// assume we have an "Athlete" class as follows: public class
AthleteDisplayInfo { public int AthleteId { get; set; } public string FirstName
{get; set;} public string LastName { get; set; } } // we then retrieve an
athlete from the database AthleteDisplayInfo athlete = e.Result; // we can then
fill UI elements, such as textboxes txtFirstName.Text = athlete.FirstName;
txtLastName.Text = athlete.LastName; // and also get back the values after the
user updates... athlete.FirstName = txtFirstName.Text; athlete.LastName =
txtLastName.Text;
The method shown above is quite adequate for filling UI elements with data values, but it does not allow for separation of User Interface from Business Logic Classes. Without separating our user interface from our business logic code, it will be more difficult to test the application, and have teams of designers and developers work cooperatively on the same project.
This is where data binding comes in. Using data binding, we can declaratively assign values to UI elements instead of using code. Furthermore, the data binding will automatically synchronize changes to the data source to the UI elements.To implement data binding, we use a special syntax in XAML, inside any attribute value: "{Binding PropertyName, Mode=OneWay}" - where "PropertyName" is the property of a data source class, and Mode is either OneTime, OneWay, or TwoWay.
Consider this example:
<TextBox x:Name="txtLastName" Text="{Binding LastName,
Mode=OneWay}" />
The XAML above will automatically fill the "Text" property of txtLastName when databinding occurs. We can tell UI elements what their binding source is by using the DataContext property. The DataContext property can be assigned to a Container Control, such as a Canvas or Grid, and all child controls within that container will receive their bound data from that DataContext. For example, if txtLastName from the example above exists within a Canvas container named "LayoutRoot", then we can assign a business logic class to LayoutRoot.DataContext:
LayoutRoot.DataContext = athlete;
The assignment to DataContext above would cause txtLastName to show the value of athlete.LastName in its Text property.
Data Binding Modes
When you are specifying the Mode for data binding, you have three choices:
OneTime: Updates the target property when the binding is created.
OneWay: Updates the target property when the binding is created. Changes to the source object can also propogate to the target.
TwoWay: Updates either the target or the source object when either change. When the binding is created, the target property is updated from the source.
If you have a read-only UI element where the source data does not change, you might consider using OneTime mode data binding. If you have a read-only UI element, and the user may be selecting different records at times (causing the source data to change), you might consider using OneWay databinding. TwoWay databinding is handy in Master/Details scenarios, where a DataGrid can be linked to controls in a "Detail" section of the screen.
Accessing Data Using Silverlight Conclusion
Lab: Accessing Data In Silverlight
In this lab, you will extend the athlete management application login dialog by providing the user the option to save their credentials and automatically login on future visits. The user credentials will be stored in isolated storage.
Store User Credentials in Isolated Storage
30 45
In this exercise, you will store user credentials in isolated storage.
1.Let's improve the login dialog by adding a checkbox to the canvas so that users can select an option to automatically log them in on follow-up visits. We'll implement this by storing the user's login credentials in isolated storage. Bear in mind that isolated storage is not guaranteed to be persistent. Isolated storage presents a virtual file system to the developer by using cookies. If a user deletes the associated cookies, they will remove their login information and will be required to login again on following visits (just as with any Web site).
2.We will need to add references to the System.IO and System.IO.IsolatedStorage namespace. Add this to the top of the Page.xaml.cs code file:
using System.IO.IsolatedStorage; using System.IO;
3.The AuthenticateUserCompleted event is the place we'll want to store the user's information in isolated storage if they select the checkbox for us to do so. That way we don't forget to store the credentials away at a later point. When writing to isolated storage, you can gain access to the isolated storage mechanism through the System.IO.IsolatedStorage.IsolatedStorageFile class. Once an instance of the file class is created, a stream must be created for reading from and writing to the file. Finally, a file stream is used to actually write into the stream. The example version of the updated AuthenticateUserCompleted event is shown below:
void svc_AuthenticateUserCompleted(object sender, AthleteManager.AthleteService.AuthenticateUserCompletedEventArgs e) { if (e.Result) { ucLoginStatus1.IsLoggedIn = true; // remember the user's credentials for next time. if (chkRememberMe.IsChecked == true) { using (IsolatedStorageFile isoStore = IsolatedStorageFile.GetUserStoreForApplication()) { using (IsolatedStorageFileStream isoStream = new IsolatedStorageFileStream("UserCredentials.txt", FileMode.Create, isoStore)) { using (StreamWriter writer = new StreamWriter(isoStream)) { writer.Write(txtUserName.Text + "|" + txtPassword.Password); } } } } } else { ucLoginStatus1.IsLoggedIn = false; } }
4.Next, we'll need to read the user's credentials from isolated storage on follow up visits, if the information is stored in isolated storage. We'll want to completely subvert the login dialog in this scenario, if we can, so we'll add code to the code behind class constructor to check for the user's credentials in isolated storage.
5.The process of reading from isolated storage is almost exactly the opposite to the process of writing to isolated storage. The updated example code behind constructor is shown below:
public Page() { InitializeComponent(); svc.AuthenticateUserCompleted += new EventHandler<AthleteManager.AthleteService.AuthenticateUserCompletedEventArgs>(svc_AuthenticateUserCompleted); // determine if the user's credentials exist in isolated storage. using (IsolatedStorageFile isoStore = IsolatedStorageFile.GetUserStoreForApplication()) { using (IsolatedStorageFileStream isoStream = new IsolatedStorageFileStream("UserCredentials.txt", FileMode.Open, isoStore)) { using (StreamReader reader = new StreamReader(isoStream)) { // read the credentials. string[] sb = reader.ReadLine().Split('|'); // if the credentials exist, parse them out and authenticate them. string username = sb[0]; string password = sb[1]; // authenticate. svc.AuthenticateUserAsync(username, password); } } } btnLogin.Click += new RoutedEventHandler(btnLogin_Click); }
Add Controls to Display Athlete Information
45 60
In this exercise, you will add controls to the athlete management application design area to display athlete information.
1.Let's enhance our web service so that it can read Athlete information from the database. First, add a few namespace imports to the top of AthleteService.cs in the web project:
using System.Data.SqlClient; using System.Configuration; using System.Data;
2.We need a Connection object to the database. Add this declaration just inside the AthleteService class:
SqlConnection cn = new SqlConnection(ConfigurationManager.ConnectionStrings["athleteDB"].ConnectionString);
3.Next we add a new web service method to AthleteService.cs to retrieve the athlete information:
[WebMethod] public List<Athlete> ReadAthletes() { List<Athlete> athletes = new List<Athlete>(); cn.Open(); using (SqlCommand cmd = new SqlCommand("select * from Athletes", cn)) { cmd.CommandType = CommandType.Text; SqlDataReader rdr = cmd.ExecuteReader(); if (rdr.HasRows) { Athlete athlete; while (rdr.Read()) { athlete = new Athlete(); athlete.AthleteId = int.Parse(rdr["AthleteId"].ToString()); athlete.SportId = int.Parse(rdr["SportId"].ToString()); athlete.FirstName = rdr["FirstName"].ToString(); athlete.LastName = rdr["LastName"].ToString(); athlete.Address = rdr["Address"].ToString(); athlete.City = rdr["City"].ToString(); athlete.State = rdr["State"].ToString(); athlete.Zip = rdr["Zip"].ToString(); athletes.Add(athlete); } } } cn.Close(); cn.Dispose(); return athletes; }
4.Since we have added a method to the Web Service, we need to refresh the Service Reference from the Silverlight application. In the Silverlight project, expand the Service References node and then right-click the AthleteService control and select "Update Service Reference." Then, wire up the event handler for the call to ReadAthletes on the web service. Place this code in the Page constructor, just after the event wire-up for AuthenticateUserCompleted:
svc.ReadAthletesCompleted += new EventHandler<AthleteManager.AthleteService.ReadAthletesCompletedEventArgs>(svc_ReadAthletesCompleted);
5.The next step of the process is to display the athletes that are in the database in a datagrid. The datagrid is a control that is included in the Silverlight SDK. It might be easiest to set the visibility of the login dialog to Collapsed while designing the DataGrid and data display. Add code to the svc_AuthenticateUserCompleted event handler to hide the login dialog if the user has successfully authenticated, and call the ReadAthletesAsync method of the web service:
canvasLogin.Visibility = Visibility.Collapsed; svc.ReadAthletesAsync();
6.Drag a DataGrid from the toolbox to the Silverlight XAML. Assign the DataGrid a name and set the AutoGenerateColumns property to True.
<my:DataGrid x:Name="grdAthletes" AutoGenerateColumns="True"></my:DataGrid>
7.In the ReadAthletesCompleted callback event handler, write code to set the results of the method as the DataGrid ItemSource. We are returning an array of athlete objects from the ReadAthletes method.
void svc_ReadAthletesCompleted(object sender, AthleteManager.AthleteService.ReadAthletesCompletedEventArgs e) { grdAthletes.ItemsSource = e.Result; }
8.If you find that the DataGrid is not displaying data correctly, ensure that you specify Height and Width property values for the DataGrid. Test the Silverlight control to ensure that the DataGrid is displaying data correctly.
9.Modify the Silverlight control by adding additional controls for displaying athlete information, and buttons for Save, Add New and Delete. Use Expression Blend to design this data entry form. First create a new Canvas named canvasMain and be sure to place all of the following controls inside the Canvas (we will later show/hide this Canvas as necessary). The figures below illustrate the controls added to canvasMain and the resulting appearance.
1.txtFirstName: A TextBox for first name.
2.txtLastName: A TextBox for last name.
3.txtAddress: A TextBox for address.
4.txtCity: A TextBox for city.
5.txtState: A TextBox for state.
6.txtZip: A TextBox for zip.
7.btnSave: A button to save the current record.
8.btnAddNew: A button for entering "new record" mode.
9.btnDelete: A button for deleting the current record.
10.Complete the Silverlight control by adding additional controls to the control for displaying athlete information.
11.Add Data Binding markup syntax to the textboxes in XAML so that they show the value of the fields when databound:
<TextBox Height="20" x:Name="txtFirstName" Width="137" Canvas.Left="89" Canvas.Top="255" Text="{Binding FirstName, Mode=TwoWay}" TextWrapping="Wrap" /> <TextBox Height="20" x:Name="txtLastName" Width="137" Text="{Binding LastName, Mode=TwoWay}" TextWrapping="Wrap" Canvas.Top="255" Canvas.Left="240"/> <TextBox Height="20" x:Name="txtAddress" Width="285" Text="{Binding Address, Mode=TwoWay}" TextWrapping="Wrap" Canvas.Left="89" Canvas.Top="288"/> <TextBox Height="20" x:Name="txtCity" Width="99" Text="{Binding City, Mode=TwoWay}" TextWrapping="Wrap" Canvas.Left="89" Canvas.Top="320"/> <TextBox Height="20" x:Name="txtState" Width="29.539" Text="{Binding State, Mode=TwoWay}" TextWrapping="Wrap" Canvas.Left="240" Canvas.Top="320"/> <TextBox Height="20" x:Name="txtZip" Width="60" Text="{Binding Zip, Mode=TwoWay}" TextWrapping="Wrap" Canvas.Top="320" Canvas.Left="314"/>
12.Ensure that the new controls only display when the user has successfully logged into the application. You can do this by adding code to the svc_AuthenticateUserCompleted event:
canvasMain.Visibility = Visibility.Visible;
13.Add an event handler to the DataGrid SelectionChange event. In the event handler, set the DataContext to data bind the values displayed in the controls to the athlete information for the currently selected athlete in the DataGrid list. The example code is shown below.
void grdAthletes_SelectionChanged(object sender, SelectionChangedEventArgs e) { AthleteService.Athlete athlete = (AthleteService.Athlete)grdAthletes.SelectedItem; LayoutRoot.DataContext = athlete; }
14.Run the application. You should be able to browse the available records.
15.Next we'll add update capabilities to the Save, Delete and Add New buttons. Inside the AthleteService.cs Web Service class, add the following two Web Methods:
[WebMethod] public void SaveAthlete(Athlete athlete) { string sqlText = string.Empty; if (athlete.AthleteId > 0) sqlText = "update Athletes set FirstName=@FirstName, LastName=@LastName, Address=@Address, City=@City, State=@State, Zip=@Zip where AthleteId = @AthleteId"; else sqlText = "insert into Athletes (FirstName, LastName, Address, City, State, Zip) values (@FirstName, @LastName, @Address, @City, @State, @Zip)"; cn.Open(); using (SqlCommand cmd = new SqlCommand(sqlText, cn)) { cmd.Parameters.Add(new SqlParameter("@FirstName", athlete.FirstName)); cmd.Parameters.Add(new SqlParameter("@LastName", athlete.LastName)); cmd.Parameters.Add(new SqlParameter("@Address", athlete.Address)); cmd.Parameters.Add(new SqlParameter("@City", athlete.City)); cmd.Parameters.Add(new SqlParameter("@State", athlete.State)); cmd.Parameters.Add(new SqlParameter("@Zip", athlete.Zip)); cmd.Parameters.Add(new SqlParameter("@AthleteId", athlete.AthleteId)); cmd.CommandType = CommandType.Text; cmd.ExecuteNonQuery(); } cn.Close(); cn.Dispose(); } [WebMethod] public void DeleteAthlete(Athlete athlete) { string sqlText = "delete from Athletes where AthleteId = @AthleteId"; cn.Open(); using (SqlCommand cmd = new SqlCommand(sqlText, cn)) { cmd.CommandType = CommandType.Text; cmd.ExecuteNonQuery(); } cn.Close(); cn.Dispose(); }
16.Build the application and then refresh the Service References in the Silverlight project again as you did in a previous step (right-click the AthleteService reference and select "Update Service Reference.")
17.Inside Page.xaml.cs, inside the constructor, wire up the Completed event handlers for the new Save and Delete methods:
svc.DeleteAthleteCompleted += new EventHandler<System.ComponentModel.AsyncCompletedEventArgs>(svc_DeleteAthleteCompleted); svc.SaveAthleteCompleted += new EventHandler<System.ComponentModel.AsyncCompletedEventArgs>(svc_SaveAthleteCompleted);
18.Now wire up the click event handlers for our Save, Add New, and Delete buttons. Add this to the Page.xaml.cs constructor code:
btnSave.Click += new RoutedEventHandler(btnSave_Click); btnAddNew.Click += new RoutedEventHandler(btnAddNew_Click); btnDelete.Click += new RoutedEventHandler(btnDelete_Click);
19.Lastly, we can call the web methods inside the button handers.
void btnDelete_Click(object sender, RoutedEventArgs e) { AthleteService.Athlete athlete = (LayoutRoot.DataContext as AthleteService.Athlete); svc.DeleteAthleteAsync(athlete); } void btnAddNew_Click(object sender, RoutedEventArgs e) { AthleteService.Athlete athlete = new AthleteService.Athlete(); LayoutRoot.DataContext = athlete; } void btnSave_Click(object sender, RoutedEventArgs e) { AthleteService.Athlete athlete = (LayoutRoot.DataContext as AthleteService.Athlete); svc.SaveAthleteAsync(athlete); }
20.Run the application, and try adding, updating and deleting a record.
Error. This text should not be shown. Please email courseware@webucator.com to report it:
Lab: Accessing Data In Silverlight
In this lab, you will extend the athlete management application login dialog by providing the user the option to save their credentials and automatically login on future visits. The user credentials will be stored in isolated storage.
Exercise: Store User Credentials in Isolated Storage
Duration: 30 to 45 minutes.
In this exercise, you will store user credentials in isolated storage.
1.Let's improve the login dialog by adding a checkbox to the canvas so that users can select an option to automatically log them in on follow-up visits. We'll implement this by storing the user's login credentials in isolated storage. Bear in mind that isolated storage is not guaranteed to be persistent. Isolated storage presents a virtual file system to the developer by using cookies. If a user deletes the associated cookies, they will remove their login information and will be required to login again on following visits (just as with any Web site).
2.We will need to add references to the System.IO and System.IO.IsolatedStorage namespace. Add this to the top of the Page.xaml.cs code file:
using System.IO.IsolatedStorage; using System.IO;
3.The AuthenticateUserCompleted event is the place we'll want to store the user's information in isolated storage if they select the checkbox for us to do so. That way we don't forget to store the credentials away at a later point. When writing to isolated storage, you can gain access to the isolated storage mechanism through the System.IO.IsolatedStorage.IsolatedStorageFile class. Once an instance of the file class is created, a stream must be created for reading from and writing to the file. Finally, a file stream is used to actually write into the stream. The example version of the updated AuthenticateUserCompleted event is shown below:
void svc_AuthenticateUserCompleted(object sender,
AthleteManager.AthleteService.AuthenticateUserCompletedEventArgs e) { if
(e.Result) { ucLoginStatus1.IsLoggedIn = true; // remember the user's
credentials for next time. if (chkRememberMe.IsChecked == true) { using
(IsolatedStorageFile isoStore =
IsolatedStorageFile.GetUserStoreForApplication()) { using
(IsolatedStorageFileStream isoStream = new
IsolatedStorageFileStream("UserCredentials.txt", FileMode.Create, isoStore)) {
using (StreamWriter writer = new StreamWriter(isoStream)) {
writer.Write(txtUserName.Text + "|" + txtPassword.Password); } } } } } else {
ucLoginStatus1.IsLoggedIn = false; } }
4.Next, we'll need to read the user's credentials from isolated storage on follow up visits, if the information is stored in isolated storage. We'll want to completely subvert the login dialog in this scenario, if we can, so we'll add code to the code behind class constructor to check for the user's credentials in isolated storage.
5.The process of reading from isolated storage is almost exactly the opposite to the process of writing to isolated storage. The updated example code behind constructor is shown below:
public Page() { InitializeComponent();
svc.AuthenticateUserCompleted += new
EventHandler<AthleteManager.AthleteService.AuthenticateUserCompletedEventArgs>(svc_AuthenticateUserCompleted);
// determine if the user's credentials exist in isolated storage. using
(IsolatedStorageFile isoStore =
IsolatedStorageFile.GetUserStoreForApplication()) { using
(IsolatedStorageFileStream isoStream = new
IsolatedStorageFileStream("UserCredentials.txt", FileMode.Open, isoStore)) {
using (StreamReader reader = new StreamReader(isoStream)) { // read the
credentials. string[] sb = reader.ReadLine().Split('|'); // if the credentials
exist, parse them out and authenticate them. string username = sb[0]; string
password = sb[1]; // authenticate. svc.AuthenticateUserAsync(username,
password); } } } btnLogin.Click += new RoutedEventHandler(btnLogin_Click); }
Exercise: Add Controls to Display Athlete Information
Duration: 45 to 60 minutes.
In this exercise, you will add controls to the athlete management application design area to display athlete information.
1.Let's enhance our web service so that it can read Athlete information from the database. First, add a few namespace imports to the top of AthleteService.cs in the web project:
using System.Data.SqlClient; using
System.Configuration; using System.Data;
2.We need a Connection object to the database. Add this declaration just inside the AthleteService class:
SqlConnection cn = new
SqlConnection(ConfigurationManager.ConnectionStrings["athleteDB"].ConnectionString);
3.Next we add a new web service method to AthleteService.cs to retrieve the athlete information:
[WebMethod] public List<Athlete>
ReadAthletes() { List<Athlete> athletes = new List<Athlete>(); cn.Open(); using
(SqlCommand cmd = new SqlCommand("select * from Athletes", cn)) {
cmd.CommandType = CommandType.Text; SqlDataReader rdr = cmd.ExecuteReader(); if
(rdr.HasRows) { Athlete athlete; while (rdr.Read()) { athlete = new Athlete();
athlete.AthleteId = int.Parse(rdr["AthleteId"].ToString()); athlete.SportId =
int.Parse(rdr["SportId"].ToString()); athlete.FirstName =
rdr["FirstName"].ToString(); athlete.LastName = rdr["LastName"].ToString();
athlete.Address = rdr["Address"].ToString(); athlete.City =
rdr["City"].ToString(); athlete.State = rdr["State"].ToString(); athlete.Zip =
rdr["Zip"].ToString(); athletes.Add(athlete); } } } cn.Close(); cn.Dispose();
return athletes; }
4.Since we have added a method to the Web Service, we need to refresh the Service Reference from the Silverlight application. In the Silverlight project, expand the Service References node and then right-click the AthleteService control and select "Update Service Reference." Then, wire up the event handler for the call to ReadAthletes on the web service. Place this code in the Page constructor, just after the event wire-up for AuthenticateUserCompleted:
svc.ReadAthletesCompleted += new
EventHandler<AthleteManager.AthleteService.ReadAthletesCompletedEventArgs>(svc_ReadAthletesCompleted);
5.The next step of the process is to display the athletes that are in the database in a datagrid. The datagrid is a control that is included in the Silverlight SDK. It might be easiest to set the visibility of the login dialog to Collapsed while designing the DataGrid and data display. Add code to the svc_AuthenticateUserCompleted event handler to hide the login dialog if the user has successfully authenticated, and call the ReadAthletesAsync method of the web service:
canvasLogin.Visibility = Visibility.Collapsed; svc.ReadAthletesAsync();
6.Drag a DataGrid from the toolbox to the Silverlight XAML. Assign the DataGrid a name and set the AutoGenerateColumns property to True.
<my:DataGrid x:Name="grdAthletes" AutoGenerateColumns="True"></my:DataGrid>
7.In the ReadAthletesCompleted callback event handler, write code to set the results of the method as the DataGrid ItemSource. We are returning an array of athlete objects from the ReadAthletes method.
void
svc_ReadAthletesCompleted(object sender,
AthleteManager.AthleteService.ReadAthletesCompletedEventArgs e) {
grdAthletes.ItemsSource = e.Result; }
8.If you find that the DataGrid is not displaying data correctly, ensure that you specify Height and Width property values for the DataGrid. Test the Silverlight control to ensure that the DataGrid is displaying data correctly.
9.Modify the Silverlight control by adding additional controls for displaying athlete information, and buttons for Save, Add New and Delete. Use Expression Blend to design this data entry form. First create a new Canvas named canvasMain and be sure to place all of the following controls inside the Canvas (we will later show/hide this Canvas as necessary). The figures below illustrate the controls added to canvasMain and the resulting appearance.
1.txtFirstName: A TextBox for first name.
2.txtLastName: A TextBox for last name.
3.txtAddress: A TextBox for address.
4.txtCity: A TextBox for city.
5.txtState: A TextBox for state.
6.txtZip: A TextBox for zip.
7.btnSave: A button to save the current record.
8.btnAddNew: A button for entering "new record" mode.
9.btnDelete: A button for deleting the current record.
10.Complete the Silverlight control by adding additional controls to the control for displaying athlete information.
11.Add Data Binding markup syntax to the textboxes in XAML so that they show the value of the fields when databound:
<TextBox Height="20" x:Name="txtFirstName" Width="137" Canvas.Left="89"
Canvas.Top="255" Text="{Binding FirstName, Mode=TwoWay}" TextWrapping="Wrap" />
<TextBox Height="20" x:Name="txtLastName" Width="137" Text="{Binding LastName,
Mode=TwoWay}" TextWrapping="Wrap" Canvas.Top="255" Canvas.Left="240"/> <TextBox
Height="20" x:Name="txtAddress" Width="285" Text="{Binding Address,
Mode=TwoWay}" TextWrapping="Wrap" Canvas.Left="89" Canvas.Top="288"/> <TextBox
Height="20" x:Name="txtCity" Width="99" Text="{Binding City, Mode=TwoWay}"
TextWrapping="Wrap" Canvas.Left="89" Canvas.Top="320"/> <TextBox Height="20"
x:Name="txtState" Width="29.539" Text="{Binding State, Mode=TwoWay}"
TextWrapping="Wrap" Canvas.Left="240" Canvas.Top="320"/> <TextBox Height="20"
x:Name="txtZip" Width="60" Text="{Binding Zip, Mode=TwoWay}" TextWrapping="Wrap"
Canvas.Top="320" Canvas.Left="314"/>
12.Ensure that the new controls only display when the user has successfully logged into the application. You can do this by adding code to the svc_AuthenticateUserCompleted event:
canvasMain.Visibility = Visibility.Visible;
13.Add an event handler to the DataGrid SelectionChange event. In the event handler, set the DataContext to data bind the values displayed in the controls to the athlete information for the currently selected athlete in the DataGrid list. The example code is shown below.
void grdAthletes_SelectionChanged(object sender, SelectionChangedEventArgs e) {
AthleteService.Athlete athlete =
(AthleteService.Athlete)grdAthletes.SelectedItem; LayoutRoot.DataContext =
athlete; }
14.Run the application. You should be able to browse the available records.
15.Next we'll add update capabilities to the Save, Delete and Add New buttons. Inside the AthleteService.cs Web Service class, add the following two Web Methods:
[WebMethod] public void SaveAthlete(Athlete athlete) {
string sqlText = string.Empty; if (athlete.AthleteId > 0) sqlText = "update
Athletes set FirstName=@FirstName, LastName=@LastName, Address=@Address,
City=@City, State=@State, Zip=@Zip where AthleteId = @AthleteId"; else sqlText =
"insert into Athletes (FirstName, LastName, Address, City, State, Zip) values
(@FirstName, @LastName, @Address, @City, @State, @Zip)"; cn.Open(); using
(SqlCommand cmd = new SqlCommand(sqlText, cn)) { cmd.Parameters.Add(new
SqlParameter("@FirstName", athlete.FirstName)); cmd.Parameters.Add(new
SqlParameter("@LastName", athlete.LastName)); cmd.Parameters.Add(new
SqlParameter("@Address", athlete.Address)); cmd.Parameters.Add(new
SqlParameter("@City", athlete.City)); cmd.Parameters.Add(new
SqlParameter("@State", athlete.State)); cmd.Parameters.Add(new
SqlParameter("@Zip", athlete.Zip)); cmd.Parameters.Add(new
SqlParameter("@AthleteId", athlete.AthleteId)); cmd.CommandType =
CommandType.Text; cmd.ExecuteNonQuery(); } cn.Close(); cn.Dispose(); }
[WebMethod] public void DeleteAthlete(Athlete athlete) { string sqlText =
"delete from Athletes where AthleteId = @AthleteId"; cn.Open(); using
(SqlCommand cmd = new SqlCommand(sqlText, cn)) { cmd.CommandType =
CommandType.Text; cmd.ExecuteNonQuery(); } cn.Close(); cn.Dispose(); }
16.Build the application and then refresh the Service References in the Silverlight project again as you did in a previous step (right-click the AthleteService reference and select "Update Service Reference.")
17.Inside Page.xaml.cs, inside the constructor, wire up the Completed event handlers for the new Save and Delete methods:
svc.DeleteAthleteCompleted += new
EventHandler<System.ComponentModel.AsyncCompletedEventArgs>(svc_DeleteAthleteCompleted);
svc.SaveAthleteCompleted += new
EventHandler<System.ComponentModel.AsyncCompletedEventArgs>(svc_SaveAthleteCompleted);
18.Now wire up the click event handlers for our Save, Add New, and Delete buttons. Add this to the Page.xaml.cs constructor code:
btnSave.Click += new
RoutedEventHandler(btnSave_Click); btnAddNew.Click += new
RoutedEventHandler(btnAddNew_Click); btnDelete.Click += new
RoutedEventHandler(btnDelete_Click);
19.Lastly, we can call the web methods inside the button handers.
void btnDelete_Click(object sender, RoutedEventArgs e) { AthleteService.Athlete
athlete = (LayoutRoot.DataContext as AthleteService.Athlete);
svc.DeleteAthleteAsync(athlete); } void btnAddNew_Click(object sender,
RoutedEventArgs e) { AthleteService.Athlete athlete = new
AthleteService.Athlete(); LayoutRoot.DataContext = athlete; } void
btnSave_Click(object sender, RoutedEventArgs e) { AthleteService.Athlete athlete
= (LayoutRoot.DataContext as AthleteService.Athlete);
svc.SaveAthleteAsync(athlete); }
20.Run the application, and try adding, updating and deleting a record.
In this lesson of the Silverlight tutorial, you
Managed data by using LINQ
Stored and retrieved XML using Silverlight
Stored data to and retrieved data from isolated storage
Footnotes
1.Comprehensive coverage of LINQ is well beyond the scope of this course. To learn more about LINQ, visit the LINQ Developer Center (the LINQ Project) located at http://msdn2.microsoft.com/en-us/netframework/aa904594.aspx.
To continue to learn Silverlight go to the top of this page and click on the next lesson in this Silverlight Tutorial's Table of Contents.
Tutorial on Silverlight 4 databinding in code-behind, custom user controls, etc.
19102010
Introduction
This small tutorial was written to show the students the following aspects of Silverlight:
Writing a class that can be used for databinding
Perform data-binding through code instead of XAML
Creating a custom user control
Writing simple data converters
Suppose we are creating a Silverlight game in which each player is represented as a pawn. However, the player class itself is somewhere deep inside the game-engine and we would like the pawn user control to be only loosely coupled to this player class. By doing this, we are able to make a rapid Silverlight prototype and if we later decide that the frontend is pretty lame, we can simply redesign it without too much fuss.
Player class
We create a small class that represents a player, with its name, color and location:
public class Player
{
private string name;
public string Name {
get { return name; }
set { name = value; }
}
private Point location;
public Point Location {
get { return location; }
set { location = value; }
}
private Color color;
public Color Color {
get { return color; }
set { color = value; }
}
}
For two-way databinding to work in Silverlight (and WPF) the Player class needs to implement the INotifyPropertyChanged interface:
public class Player: INotifyPropertyChanged
{
private string name;
public string Name {
get { return name; }
set {
name = value;
NotifyPropertyChanged("Name");
}
}
private Point location;
public Point Location {
get { return location; }
set {
location = value;
NotifyPropertyChanged("Location");
}
}
private Color color;
public Color Color {
get { return color; }
set {
color = value;
NotifyPropertyChanged("Color");
}
}
//Notify
public event PropertyChangedEventHandler PropertyChanged;
public void NotifyPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this,
new PropertyChangedEventArgs(propertyName));
}
}
}
We can now create a Player object anywhere it’s needed, e.g. :
Player player1 = new Player() {
Location = new Point(0, 0),
Name = "Tim",
Color=Colors.Blue };
Creating a user control
We create a custom user control that will represent the player in the game. Right-click your project and choose “Add new item…”. Next pick Silverlight User Control and give the control a meaningful name, such as pawn.
Set the DesignHeight and DesignWidth to 30 and then insert the following the XAML-code:
<Grid x:Name="LayoutRoot" Background="{x:Null}" >
<Ellipse x:Name="playerEllipse" Stroke="Black"
StrokeThickness="2" Height="30" Width="30" Fill="#FFFF1717"/>
</Grid>
By defining Background=”{x:Null} we make sure that the background of our control is transparent and thus will blend nicely on the game-board.
It is important to explicitly name each element if we wish to be able to bind certain properties to it later on.
Adding the user control to a canvas
Suppose we define a canvas somewhere on our MainPage.xaml:
<Canvas x:Name="playboardCanvas" Background="#FFD7FF07"
Width="400" Height="200">
Yeah, it’s a very ugly color, but let’s keep the design to other people.
If we wish to add the newly created user control to this canvas we need to perform the following steps:
1. Create a new instance of the usercontrol
2. Define any bindings needed
3. Add the control to the children of the canvas
This results in:
//Step 1
Pawn pawn = new Pawn();
//Step 2: bindings and datacontext comes here (discussed further on)
//Step 3
playboardCanvas.Children.Add(pawn);
Binding the pawn control to the player class
In order for the pawn to be bound to the player, we first point the pawns datacontext to the player:
pawn.DataContext = player1;
We then create a binding object in which we will bind the location of the player to the location of the pawn on the canvas.
//Bind location.X
Binding c = new Binding();
c.Source = player1;
c.Path = new PropertyPath("Location.X");
c.Mode = BindingMode.OneWay;
pawn.SetBinding(Canvas.LeftProperty, c);
We do the same for the Y-coordinate, only this one needs to be bound to the TopProperty of the pawn:
pawn.SetBinding(Canvas.TopProperty, c);
Writing a convertor
Suppose we defined the Location of our player to be an (x,y)coordinate between (0,0) and (8,8) (for example to define a pawn on a checkerboard). Our previously databound pawn would then be able to move between the (0,0) and (8,8) zone on the canvas…that’s a pretty small canvas.
We’ll write convertor that takes the actual dimensions of the canvas on the screen in account. The convertor will then transform the Location of the player to an equivalent location on the canvas.
The convertor is pretty straightforward. value will contain the X or Y coordinate of the player, and the extra parameter will contain a reference to the canvas on which the pawn is drawn:
public class CanvasLocationWidthConvertor : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
Canvas canv = (Canvas)parameter;
return (double)value * (canv.ActualWidth / 5);
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
We now simply add the convertor to the binding object we created earlier, so our binding code now is:
//Bind location.Y
Binding c = new Binding();
c.Source = player1;
c.Path = new PropertyPath("Location.X");
c.Mode = BindingMode.OneWay;
c.Converter = new CanvasLocationWidthConvertor();
c.ConverterParameter = playboardCanvas;
pionCanvas.SetBinding(Canvas.LeftProperty, c);
Binding the color
To bind the color of the player object to the pawn, we write the following binding in which the fillproperty of the ellipse is bound to the Color property:
Binding e = new Binding();
e.Source = player1;
e.Path = new PropertyPath("Color");
e.Mode = BindingMode.OneWay;
e.Converter = new PlayerColorConvertor();
pionCanvas.pionEllipse.SetBinding(Ellipse.FillProperty, e);
Since the FillProperty is defined by a SolidColorBrush instead of a Color we have to write a small convertor for that. Again, pretty straightforward:
public class PlayerColorConvertor : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return new SolidColorBrush((Color)value);
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
Binding to a grid
The fun thing of databinding in Silverlight (and WPF) is that we kind bind any property of an object to any property of an XAML element. Suppose we defined a 5-by-5 checkerboard grid in xaml (note: make your life easy and write this kind of stuff in the code behind using some loops) :
<Grid x:Name="playGrid" >
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Rectangle Grid.Row="0" Grid.Column="0" Fill="Black"></Rectangle>
<Rectangle Grid.Row="0" Grid.Column="2" Fill="Black"></Rectangle>
<Rectangle Grid.Row="0" Grid.Column="4" Fill="Black"></Rectangle>
<Rectangle Grid.Row="1" Grid.Column="1" Fill="Black"></Rectangle>
<Rectangle Grid.Row="1" Grid.Column="3" Fill="Black"></Rectangle>
<Rectangle Grid.Row="2" Grid.Column="0" Fill="Black"></Rectangle>
<Rectangle Grid.Row="2" Grid.Column="2" Fill="Black"></Rectangle>
<Rectangle Grid.Row="2" Grid.Column="4" Fill="Black"></Rectangle>
<Rectangle Grid.Row="3" Grid.Column="1" Fill="Black"></Rectangle>
<Rectangle Grid.Row="3" Grid.Column="3" Fill="Black"></Rectangle>
<Rectangle Grid.Row="4" Grid.Column="0" Fill="Black"></Rectangle>
<Rectangle Grid.Row="4" Grid.Column="2" Fill="Black"></Rectangle>
<Rectangle Grid.Row="4" Grid.Column="4" Fill="Black"></Rectangle>
</Grid>
Simply bind the X and Y coordinates of the player to the respective Grid.Row and Grid.Column properties of the playGrid object, e.g.:
//Bind location.X
Binding c2 = new Binding();
c2.Source = player1;
c2.Path = new PropertyPath("Location.X");
c2.Mode = BindingMode.OneWay;
playGrid.SetBinding(Grid.RowProperty,c2);
Subscribe to:
Posts (Atom)