MCTS: Microsoft Silverlight 4 Development (70-506) Certification Guide
MCTS: Microsoft Silverlight 4 Development (70-506) Certification Guide
Johnny Tordgeman
Chapter 7, Structuring Applications, covers how to make your code look cleaner, and behave better. Chapter 8, Deploying Applications, packs things up by diving deep into configuring the Silverlight plugin, and reducing its size by dynamically loading resources.
OneWay: The target of the bind operation will update with the source every time the source changes. Using the same example as before, if the TextBlock
element is bound to a property using the one-way binding mode, it will update its value every time the source property updates as well. This is the default data binding mode in Silverlight.
TwoWay: The bind operation will update both the source and the target when TextBlock element, because this mode allows the UI element to update its source property, as well as the other way around. (TextBlock, as opposed to TextBox only displays text and doesn't allow editing). This mode is used
when we wish to get data from the user and a very common use for it is in forms.
In order for the automatic update to occur, the source of the binding must implement an interface known as INotifyPropertyChanged. This interface, in a nutshell, contains the PropertyChanged event, which is in charge of telling the binding engine that the source has been changed, and it's time to update its bound UI element. We will discuss the INotifyPropertyChanged interface in more details in just a bit. To have a better understanding of the whole binding process we have discussed so far, imagine that you need to create a form for adding a new user to your site. The form consists of several text areas the user needs to ll in, including a username eld. You want the username eld to light up in green if the chosen username is available and red if the username is already taken. By using two-way data binding, the form will update a backend property with the text the user has typed. The property in its turn performs some logic to check for the availability of the username, and then by having a property bound to the border property of the text box, it sets the new color. At the heart of the binding engine is DataContext, and before we go on and dig deeper into binding, let's discuss this important concept.
Setting DataContext
DataContext, in a nutshell, allows us to dene a common source for all the UI binding in XAML under a certain level. You can set the DataContext property at
either the page level or an element level depending on your needs. Consider the following code snippet:
<toolkit:DataForm HorizontalAlignment="Stretch" Margin="12" Name="dataForm1" VerticalAlignment="Stretch"> <toolkit:DataForm.NewItemTemplate> <DataTemplate> <StackPanel>
[ 160 ]
Chapter 5 <StackPanel Orientation="Horizontal"> <toolkit:DataField> <TextBox Text="{Binding FirstName, Mode=TwoWay}" MinWidth="200"/> </toolkit:DataField> <toolkit:DataField> <TextBox Text="{Binding LastName, Mode=TwoWay}" MinWidth="200"/> </toolkit:DataField> </StackPanel> <toolkit:DataField> <TextBox Text="{Binding EmailAddress, Mode=TwoWay}" /> </toolkit:DataField> </StackPanel> </DataTemplate> </toolkit:DataForm.NewItemTemplate> </toolkit:DataForm>
The preceding code snippet creates a DataForm element with three eldsFirstName, LastName, and EmailAddress. These elds are bound to three different properties. How does the DataForm control know to bind these properties? How does the DataForm control know where the EmailAddress property is, and how does it update it when the TextBox element's text changes? (Remember, two-way binding can update both the source property and the target UI element of the bind operation). The answer to these questions is the DataContext object. Open the Chapter5-DataContext project in Visual Studio 2010. The project can be found in the downloadable content of the book and can be downloaded from http://www.packtpub.com. If I run this code right now, I will get the result, as shown in the following screenshot:
[ 161 ]
Nothing gets rendered, but the nice default background of the DataForm element. The reason for this is that DataForm has no context. As stated previously, it has no idea where to take the bound properties from and, thus, doesn't render itself at all. Let's x this problem. First, open the MainPage.xaml.cs le, and add the following code snippet in the constructor method, below the call to InitializeComponent:
ObservableCollection<FormEntity> entities = new ObservableCollection< FormEntity>(); dataForm1.DataContext = entities; dataForm1.AddNewItem();
The DataContext property can also be set directly from XAML. This method requires a bit more work, as it needs a class that holds a collection of items and a resource that references to that class. Have a look at a post by Emil Stoychev at http://estoychev.wordpress. com/2010/04/24/data-binding-in-silverlight/ for more information on this topic.
The code we added creates a collection of the FormEntity class named entities. Once the collection is created, it is set as DataContext for the DataForm control we have in the UI (XAML) layer. Finally, we are telling the DataForm control that we wish to add a new item to the collection by using the AddNewItem method. If we were to run the application now, we would have got the same result as beforenothing but a nice background. The reason for that is pretty simple; we declared the source of the data that we wish to bind to DataForm (If you take a look at the FormEntity class in the project les, you will see that it contains the three properties we are binding toFirstName, LastName, and EmailAddress), but we didn't tell the DataForm control itself who is holding its items! Switch back to the MainPage.xaml le, and add the ItemsSource property to the opening DataForm element, so it will look as follows:
<toolkit:DataForm HorizontalAlignment="Stretch" Margin="12" Name="dataForm1" VerticalAlignment="Stretch" ItemsSource="{Binding}">
By setting the ItemsSource property to self-binding (you will learn more on that in a moment), DataForm now has a source for the binding (the entities observable collection), and it knows who holds its items. Run the application now, and you should get the result, as shown in the following screenshot:
[ 162 ]
Chapter 5
Self-binding refers to a state when an element binds to the DataContext property of the element above it in the hierarchy. In our preceding example, the ItemsSource property is bound to the DataContext object of the element above it in the hierarchy, that is, the page itself. DataContext can be bound to any FrameworkElement control, and it's not
uncommon to see several different data contexts assigned to several different controls within a single page or container control. Now that we understand what the DataContext property is and how it works, it's time to move on to binding data sets to controls.
[ 163 ]
Most of the code is pretty straightforward. We are adding a new DataField element to the DataForm control with a ComboBox control as its input control. The less trivial part here is the binding. We are basically binding two propertiesItemsSource and SelectedItem. The ItemsSource property is what the ComboBox control is going to show to the user. This is the data set of items that the ComboBox control uses as its source. In the following code snippet, Statuses is the name of the property that holds the collection of items. Add Statuses to the FormEntity class in your project as follows:
private List<string> statuses = new List<string>() { "Single", "Married", "Divorced" }; public List<string> Statuses { get { return statuses; } set { statuses = value; } }
We rst create a hardcoded list of strings called statuses. Then, we create the Statuses property, which will set and return the statuses variable. The SelectedItem property is the value of the item the user chose from ComboBox. As we are binding a list of string items as the ComboBox control's items source, the selected item will also be a string. In addition, as SelectedStatus is a property that the user sets from the UI layer, we set its binding mode to TwoWay. Let's add the SelectedStatus property to the FormEntity class now. Add the following code snippet to the Statuses property:
private string selectedStatus; public string SelectedStatus { get { return selectedStatus; } set { selectedStatus = value; } }
That's it! Build and run your application, and you should get the result, as shown in the following screenshot:
[ 164 ]
Chapter 5
Setting ItemsSource in code behind Setting the ItemsSource property from code behind is as simple as it gets. If we were to set ItemsSource to dataForm1 in the code behind, all we would have done is use the ItemsSource property as follows: dataForm1.ItemsSource = entities
[ 165 ]
Create a new Silverlight project in Visual Studio 2010 and name it Chapter5-ElementBinding. Add the following code snippet to your MainPage.xaml le under the LayoutRoot Grid control:
<Rectangle HorizontalAlignment="Center" Margin="0,15,0,0" Name="rectangle1" Stroke="#FFFF9800" StrokeThickness="1" VerticalAlignment="Top" Width="{Binding ElementName=slider1,P ath=Value}" Height="{Binding ElementName=slider1,Path=Value}" Fill="#FFFFD200" /> <Slider Height="23" HorizontalAlignment="Center" Name="slider1" VerticalAlignment="Center" Width="100" Minimum="100" Maximum="150" Value="100" />
Can you spot the bindings in the preceding code example? Elements binding have a constant syntax; we rst declare the Binding keyword, then we use the ElementName property to set the source element for the binding, and nally we set the Path property, which is the value of the source element we wish to bind. In our example, we are binding the Value property of the slider1 control as both the width and height of our rectangle. Build and run your application, and you should get the result, as shown in the following screenshot:
Move the slider to the right, and you should see that the rectangle grows. Move the slider to the left and the rectangle shrinks:
[ 166 ]
Chapter 5
[ 167 ]
To implement the interface, mark INotifyPropertyChanged, then click on Implement interface 'INotifyPropertyChanged', as shown in the following screenshot:
To actually raise the event, we add the OnPropertyChanged method to the class. Add the following code snippet below the PropertyChanged event declaration:
public void OnPropertyChanged(string propertyName) { var handler = PropertyChanged; if (handler != null) { handler(this, new PropertyChangedEventArgs(propertyName)); } }
Now, whenever a property wishes to raise the PropertyChanged event to let the binding engine know it's time to update its bounded UI element, all it has to do is call the OnPropertyChanged event and pass its name as an argument to it. Change the SelectedStatus property so that it uses the OnPropertyChanged method as follows:
public string SelectedStatus { get { return selectedStatus; } set { selectedStatus = value; OnPropertyChanged("SelectedStatus"); } }
To actually see it in action, add the following DataField control to your DataForm control on MainPage.xaml:
[ 168 ]
Build and run your application, and you should get the result, as shown in the following screenshot:
Change the Marital status combobox, and you should notice that whenever the value in the combobox changes, the newly added Selected status eld is updated with the new value, as shown in the following screenshot:
[ 169 ]
Try to remove the call to the OnPropertyChanged method from the FormEntity.cs class, and you'll see that the Selected status eld no longer gets updated.
If you are binding to a collection of items, and you want the UI to stay in sync with the source, you should use the ObservableCollection collection type. This collection already implements the INotifyPropertyChanged interface and, thus, whenever an item in ObservableCollection updates, the binding engine updates the UI as well.
The TargetNullValue property is set to a string, which acts as the fallback value for this binding. Run the application now and you should get the result, as shown in the following screenshot:
[ 170 ]
Chapter 5
Another property that we have for fallback values is the FallBackValue property. Not surprisingly, this property can also be used to set a default fallback value for our binding.
Formatting data
New to Silverlight 4 is the ability to format bound data using the StringFormat property that we all know and love from .NET. Using the StringFormat property when doing data binding is perfect for when you wish to format the value that returns from the bind in a specic way, such as currency or any numerical format. Using StringFormat is pretty straightforward; just add the StringFormat property after the binding declaration, just like you did with the mode earlier:
<TextBlock Text="{Binding Price, StringFormat=c}"/>
The preceding line of code will format the Price property to a currency, which on my machine translates to 5.00$. But why did it choose the dollar symbol and not any other currency symbol? The reason for that is that formatting picks up on the default culture of the system. As my default culture is en-US, I get the dollar symbol. If I had my culture set as he-IL, I would have got the New Israeli Shekel (NIS) symbol.
[ 171 ]
Currency is just one example of use for StringFormat, of course. Another example for this feature can be formatting strings. Let's say we wish to have a dynamic label, for example, "Your teacher expects to receive X apples today!", where X is a random number between 1-10. Instead of using three separate TextBlock elements (one for the text until the random number, the second for binding the random number, and the last one for the rest of the phrase), we can use a single TextBlock element as follows:
<TextBlock Text="{Binding RandomNumber, StringFormat='Your teacher expects to receive \{0\} apples today!'}"/>
There are many usages for StringFormat and when building an LOB application using Silverlight, you will nd yourself using this feature for a fair amount of time. For a list of options and usages of StringFormat, visit Matthias Shapiro's great post in his blog at http://www.designersilverlight.com/2010/05/28/silverlight4-binding-and-stringformat-in-xaml/.
[ 172 ]
Chapter 5
This application allows you to change the color of the rectangle by using the Choose your color drop-down menu above it. The thing is that if you try to change the color using that drop-down menu now, nothing happens. If you think about it for a minute, you'll realize we now have two completely different types of values, which we are going to work with in order to change the color of the rectangle's llthe combobox color names (strings) and the actual color for the rectangle ll (SolidColorBrush). This is where value converters come into play. We are going to use a string value on the Fill attribute of the rectangle, and by using a value converter, we'll convert it into something the Fill attribute can understandSolidColorBrush. Under the Classes folder in the project, create a new class called ColorConverter.cs. Change the class declaration so that it will inherit from the IValueConverter interface and implement the interface. Your class should look as follows:
public class ColorConverter:IValueConverter { public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { throw new NotImplementedException(); } public object ConvertBack(object value, Type targetType, object [ 173 ]
The interface requires us to implement two methodsConvert and ConvertBack. The Convert method is used when the data is moving from the source to the target; in our example that would be when the Fill property of the rectangle receives its string binding. ConvertBack is the exact opposite; it is used when the data moves from the target back to the source. We won't be using the ConvertBack method in our example, so you can leave it as not implemented. Now it's time to implement the Convert method. We know we are getting a string as input, and based on that string, we will output a SolidColorBrush object. Replace the content of the Convert method with the following code snippet:
string ChosenColor = value!=null ? (value as ComboBoxItem).Content. ToString() : null; switch (ChosenColor) { case "Red": return new SolidColorBrush(Colors.Red); case "Blue": return new SolidColorBrush(Colors.Blue); case "Black": return new SolidColorBrush(Colors.Black); } return null;
Here, there's nothing that we haven't seen before. We rst check if the value that we receive from the binding expression is not null. If it isn't, we are casting the value as ComboBoxItem, because this is the item that we receive from the binding (check the ColorEntity class, and you'll see that the TheColor property is dened as ComboBoxItem type), and then use the ToString method on its content to get the name of the color the user chose from the drop-down menu. Once we have the color name, we will use a simple switch/case statement to return the correct SolidColorBrush based on the chosen color. Our converter is now complete, so it's time to use it in our binding expression by using the Converter object of the Binding class. In order to be able to use our new converter in XAML, we rst have to add it as a resource. We will discuss resources in detail in Chapter 7, Structuring Applications, but for now it's enough to know that a resource is a piece of code or style that you can reference in your XAML. Resources, like styling, which we discussed earlier, can be dened on various levels from
[ 174 ]
Chapter 5
element to page. In this case, we are going to add the element to the page level, so open the App.xaml le and add the namespace for the Classes folder of our project as local:
xmlns:local="clr-namespace:Chapter5_Converters.Classes"
Next, we need to add the converter itself as a resource. Resources are accessed in XAML by their Key property, so make sure you use that property when setting your resource. Add the following line of code between the opening and closing of the Application.Resources elements:
<local:ColorConverter x:Key="ColorConverter"/>
That's it. We can now access our converter in XAML by using its Key valueColorConverter. Open the MainPage.xaml le and change the rectangle's Fill property as follows:
Fill="{Binding TheColor,Converter={StaticResource ColorConverter}}"
The syntax here is as follows; we rst tell the Fill property that it is bound to the TheColor property. We then use the Converter object and bind it to the ColorConverter resource we dened earlier using the StaticResource keyword. Can you tell the reason why the ll will change every time the drop-down value changes? (Hint: it's got to do with an interface). Build and run your application, and you will see that every time you change the value of the combobox, the rectangle's ll changes accordingly:
[ 175 ]
As parameter is an object you can practically pass on to it just about anything you want. This can be useful if you need to pass more than just a single parameter to your converter. Once set, you can read this parameter back in your converter class using the parameter argument. While binding is most commonly done in the XAML layer, sometimes you may need to create dynamic binding in code behind. The following code snippet is a representation of the preceding binding expression in the code behind layer of the application:
Binding binding = new Binding("TheColor"); binding.Source = entity; binding.Converter = new ColorConverter(); binding.ConverterParameter = true; rect.SetBinding(Rectangle.FillProperty, binding);
We rst initiate a new instance of the Binding class and pass it the name of the property we are binding to. Next, we set the source of the binding, the converter if needed, a converter parameter. Finally, we use the SetBinding method on FrameworkElement we wish to use (in our case, rect is the rectangle we used so far), and specify the name of the property we wish to bind and the binding instance.
Chapter 5
Throughout this topic, we are going to work with a sole projectChapter5DataValidation. The project contains a simple grid with a few text boxes that we will validate using the various data validation approaches in Silverlight. If you build and run the application right now, it will look, as shown in the following screenshot:
Now, the Binding class knows it needs to notify the user about exceptions. But where do exceptions come from? If your guess was the numDays property's Setter method, you were correct. If we throw an exception in a property's Setter method, and the same property is bound to an element, and has ValidatesOnException set as true; whatever we throw in the exception will be shown to the user. We have already set ValidatesOnException to true in the NumDays binding expression, so let's throw an exception now if the data the user enters isn't a number. Open the FormEntity.cs le and change the numDays property as follows:
public string NumDays { get { return numDays; } set { try [ 177 ]
Working with Data { int number = Convert.ToInt32(value); numDays = number.ToString(); OnPropertyChanged("NumDays"); } catch { throw new Exception("Only numbers are allowed!"); } } }
In the preceding code snippet, we are trying to convert the value that the user inputs to the Int32 type. If the conversation succeeds, then we will set the internal numDays property to the value. If it fails, we will throw an exception to the UI letting the user know that something went wrong. Run the application now and enter letters in the Duration textbox. You will see the result, as shown in the following screenshot:
Using this method, we are not limited to just one exception. If we want to add another exception where the user inputs 0 as the duration length, all we had to do is to change the property as follows:
public string NumDays { get { return numDays; } set { try { int number = Convert.ToInt32(value); if(number==0) [ 178 ]
Chapter 5 throw new Exception("Invalid duration!"); numDays = number.ToString(); OnPropertyChanged("NumDays"); } catch { throw new Exception("Only numbers are allowed!"); } } }
Now, when the user inputs 0, another exception will raise, as shown in the following screenshot:
[ 179 ]
In order for our XAML to respond to the IDataErrorInfo inherited class, we must add the ValidatesOnDataErrors object of the Binding class to our binding expression and set its value to true. This object tells the binding engine that instead of responding to exception-based errors, it needs to watch the IDataErrorInfo inherited class for any error reporting. Add the ValidatesOnDataErrors property to the binding of the Password eld, so its Password property looks as follows:
Password="{Binding Password,Mode=TwoWay,ValidatesOnDataErrors=True}"
Now, it's time to change the FormEntity class so that it inherits from IDataErrorInfo as well as INotifyPropertyChanged. Change the class declaration as follows:
public class FormEntity:INotifyPropertyChanged,IDataErrorInfo
Implement the new interface, and you should see two new properties added to your class:
public string Error { get { throw new NotImplementedException(); } } public string this[string columnName] { get { throw new NotImplementedException(); } }
These are the two properties we mentioned earlier. Error is the class-level error message property, and the second property is the Item property, which is based on a column name returning an error message. As Error is referring to the object itself, we have no use for it for now, and we will deal with the Item property now. The validation we wish to implement for the Password eld is that the minimum length for a password must be ve characters. Let's change the Item property of the IDataErrorInfo interface to implicate our logic:
public string this[string columnName] { get { string errorMessage = string.Empty; switch (columnName) { case "Password": [ 180 ]
Chapter 5 if (Password.Length < 5) errorMessage = "Minimum password length is 5 charecters"; break; } return errorMessage; } }
By using a switch/case method on the columnName argument, we can set the logic for any object in our application that has the ValidatesOnDataErrors object set to true in its binding expression. Once we nd the column that raised the property, we will just set the error message we wish and return it to the object. Running the application now will result in the following screenshot:
[ 181 ]
HasErrors: This is a simple Boolean property that returns true if the object contains any errors, or false if it doesn't. ErrorsChanged: This is an event similar to the PropertyChanged event in the INotifyPropertyChanged interface, which must be raised when you
either add, remove, or change errors to notify the binding system that a change has occurred.
It's important to note that Silverlight will call the GetErrors method on each public member of the class, even if you didn't specically set it up. If you implement the INotifyDataErrorInfo interface, you must take care of the GetErrors method. First, let's add an event handler just like we did with the INotifyPropertyChanged interface so that the properties can raise the ErrorsChanged event. Add the following code snippet to your FormEntity.cs le:
private void NotifyErrorsChanged(string propertyName) { var handler = ErrorsChanged; if (handler != null) handler(this, new DataErrorsChangedEventArgs(propertyName)); }
Next, we need to add a Dictionary object that uses the property name as key and a list of strings for the error messages for that property. Add the following private dictionary to your FormEntity.cs le:
private Dictionary<string, List<string>> errors;
To read data from the errors dictionary, add the following property:
public Dictionary<string,List<string>> Errors { get { if (errors == null) { errors = new Dictionary<string, List<string>>(); } return errors; } }
When we call the Errors property for the rst time, it will initiate the dictionary. The next time, it will just return it.
[ 182 ]
Chapter 5
Next, let's implement the HasErrors property. This is going to be a very easy implementation as the HasErrors property's job is just to return true if there are any errors we stored or not. Change the HasErrors property as follows:
public bool HasErrors { get { return Errors.Values.Count > 0; } }
The last method of the INotifyDataErrorInfo interface members we need to implement is the GetErrors method. Just like the IDataErrorInfo interface's Item property, the GetErrors method gets a property name as argument and outputs a list of errors for that specic property name. Change the GetErrors method as follows:
public System.Collections.IEnumerable GetErrors(string propertyName) { if (!Errors.ContainsKey(propertyName)) { Errors.Add(propertyName, new List<string>()); } return Errors[propertyName]; }
Within our web project we have a WCF service. The service is called UsernameService.svc and it contains a single method, CheckUsername, which gets a username as an argument and checks if it's one of the three predened occupied usernames. If the supplied username is already taken, the method will return false; if it's free, it will return true. To add a reference to the web service in the Silverlight project, right-click on References, add service reference, and click on Discover. Use UsernameService as the namespace. Once we have the entire infrastructure ready, let's add a call to the method to actually check if the username is taken or not. In the FormEntity.cs le, change the Login property setter as follows:
set { login = value; OnPropertyChanged("Login"); CheckForUsername(); }
[ 183 ]
Now, we must add the CheckForUsername method. Add the following code snippet to the FormEntity.cs le:
public void CheckForUsername() { UsernameService.UsernameServiceClient proxyClass = new UsernameService.UsernameServiceClient(); proxyClass.CheckUsernameCompleted += new EventHandler<UsernameService.CheckUsernameCompletedEventArgs> (proxy_CheckUsernameCompleted); proxyClass.CheckUsernameAsync(Login); }
Just like we did in the previous chapter, we will add a proxy class for the Username service, attach a complete event handler, and call the CheckUsername method asynchronously, passing to it the currently typed login name. The implementation of the completed event handler of the Checkusername method is as follows:
void proxy_CheckUsernameCompleted(object sender, UsernameService. CheckUsernameCompletedEventArgs e) { if (e.Error == null) { bool result = e.Result; if (result == false) { CreateErrorInDictionary("Login"); Errors["Login"].Add("Username taken!"); NotifyErrorsChanged("Login"); } } }
First, we cast the result of the method as Boolean, as we know it can return either true or false. If the result is false, that means the username is not available, and we should notify the user. To do that, we call the CreateErrorInDictionary method, which checks if the property already has a key in the dictionary and if not, it creates a key. The implementation of CreateErrorInDictionary is as follows:
private void CreateErrorInDictionary(string property) { if (!Errors.ContainsKey(property)) { Errors.Add(property, new List<string>()); } } [ 184 ]
Chapter 5
Once we know for sure that the Errors dictionary contains a key for our property, we will add an error message and use the NotifyErrorChanged method we created earlier to let the binding engine know an error was raised. That's it! You've created a working implementation of the INotifyDataErrorInfo! Run your application, and try to enter one of the following usernamesSilverlight, SL4, or Packt. Your screen will be similar to the following screenshot:
In a real-world scenario, the web service will probably perform a check against a database or something similar to check if a username is taken. An action like this can be time consuming and, thus, performing this activity asynchronously makes a lot of sense. We want the user to keep on going with the form, and once we get back a result from the web service, we should update him. That concludes our discussion on data validation in Silverlight. I hope you'll take what you learned here and use it to create a better, safer, and interactive experience for the user while interacting with him/her through your application.
Visibility.Collapsed;
} return Visibility.Collapsed;
b. Only implement the ConvertBack method with the following code snippet:
if (value != null) { bool result = (Boolean)value; return result == true ? Visibility.Visible : Visibility.Collapsed; } return Visibility.Collapsed;
c.
Only implement the Convert method with the following code snippet:
if (value != null) { bool result = (Boolean)value; return result; } return Visibility.Collapsed;
d. Only implement the ConvertBack method with the following code snippet:
if (value != null) { bool result = (Boolean)value; return result; } return Visibility.Collapsed;
2. You are developing a Silverlight 4 based form. The form contains a TextBox control that is data bound to a property in a class that implements the INotifyPropertyChanged interface. When an invalid value is entered to the TextBox, the property throws an exception. You need to display the error message the property throws to the user. Which code segment should you use? a. <TextBox Text="{Binding ZipCode,Mode=TwoWay,ValidatesOnDa
taErrors=True}"/>
[ 186 ]
Chapter 5
c.
d. <TextBox Text="{Binding ZipCode,Mode=TwoWay,NotifyOnValid 3. You are developing a Silverlight 4 based application. The application contains a TextBlock control that is bound to a property called FirstName. The TextBlock control needs to display the string "Welcome back" before the value of FirstName. Which code segment should you use? a. <TextBlock Text="{Binding FirstName,StringFormat='Welcome
back {FirstName}'}"/>
c.
d. <TextBlock Text="{Binding FirstName,ConverterParameter='W 4. You are developing a Silverlight 4 based application that contains a slider control. The slider is named Degrees and its values are between 1 and 360. You need to display the value of the control in a TextBlock control. Which code segment should you use? a. <TextBlock Text="{Binding Path=Value,
ElementName=Degrees}"/>
c.
d. <TextBlock Text="{Binding Path=Degree, 5. You are developing a Silverlight 4 application that contains a eld that is bound to a property called TotalPrice. The eld must be read-only, and it should not update the backend property. When a user updates other elds in the application, TotalPrice changes and needs to update the UI layer. Which binding mode should you use? a. TwoWay b. OneTime c. c. None
OneWay
[ 187 ]
Summary
In this chapter, we got to work with one of the more commonly used aspects of Silverlight, which is data handling. We discussed data bindings in details, learned about the different modes and options it offers, understood how to bind elements to other elements and how to validate the data we are binding. In addition, we learned how to format the data we get back from the binding and we got to use the all-important concept of converters. In the next chapter, we are going to discuss how to work with the host platform. We will discuss printing directly from Silverlight using the new printing API. Then, we will move on to discuss out-of-browser applications and interacting with different variables of the host-like network connectivity or the clipboard. We will also discuss how to work against the COM Interop and updating our out-of-browser application remotely. We will then move on to discuss interacting with the HTML DOM and nish off discussing how to handle alternative input methods such as the mouse's right-click or wheel.
[ 188 ]
Alternatively, you can buy the book from Amazon, BN.com, Computer Manuals and most internet book retailers.
www.PacktPub.com