miércoles, julio 30, 2008

Value Converters - Databinding 101

This is the first of several posts related to Value Converts. Trying to minimize the length of the posts I break it in 4 deliveries, but the first one will have to be an intro to databinding before I can get into Value Converters tomorrow.

Databinding is great and probably one of the best features in WPF and SL (I know I have said that before for others), well, it's great, but somehow inflexible as we will see tomorrow and Value Converters will add a bit of flexibility.

As with winforms or ASP.NET to do databinding we will need a DataSource. We will define our person class.

public class Person
{
public string Name { get; set; }
public string LastName { get; set; }
public string PhoneNumber { get; set; }
}



In our Codebehind we will add this to the DataContext property of the control

public partial class Page : UserControl
{

public Page()
{
InitializeComponent();
DataContext = new Person {Name = "Miguel", LastName = "Madero", PhoneNumber = "+52 (871) 123-4567"};
}
}

Obviously in a real example we won't hard code the values and instead get our data from a Service. Then in XAML we will define the controls that will be bound to our object. In this case we're using only textboxes inside inside a StackPanel.

<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Name}" TextWrapping="Wrap"/>
<TextBlock Text="{Binding LastName}" TextWrapping="Wrap"/>
<TextBlock Text="{Binding PhoneNumber}" TextWrapping="Wrap"/>
</StackPanel>

That's it, super simple. There are obviously more complex examples, but I probably won't go there since other people have already have done a great job covering them, for example binding to a List Box (read Scott's post) or a DataGrid (all Scott Morris blog), or a step by step tutorial by Jesse Liberty who explains Binding objects, change notifications implenting INotifyPropertyChanged, Binding Modes (OneTime, OneWay, TwoWay). This is not an intro to databinding, rather an intro to Value Converters and why is it needed.


After a couple of modifications (see attached code) the page will look like this:


image

Everything looks as expected, so why would we need value converters. Imagines some people won't have phone numbers, we would be displaying a blank space, that might not be the desired experience. What if we want to show a default value like "Not available". Tomorrow we will see how to show default values using ValueConverters.


You can download the attached code here
I format my code using Manoli's website
Don't forget to vote for your favorite topics.

No More Need to Change Your URIs

It's a pain having to remember to edit your ServiceReferences.ClientConfig (the file with the service proxies configuration) or editing your code to point to another path when changing between developing, testing and production environments. Well, it's time to stop the pain:

   1:              Uri uri = HtmlPage.Document.DocumentUri;
2: return String.Format("{0}://{1}:{2}/", uri.Scheme, uri.Host, uri.Port);

It would be better to encapsulate this in a class:

   1:  public static class UriHelper
2: {
3: public static string GetHost()
4: {
5: if(!HtmlPage.IsEnabled) // Get design time URI
6: return http://localhost:1650/;
7: Uri uri = HtmlPage.Document.DocumentUri;
8: return String.Format("{0}://{1}:{2}/", uri.Scheme, uri.Host, uri.Port);
9: }
10: }

I suggest you to update your proxies, so instead of using the URL defined in your ServiceReferences file it will use the URI provided by your method:


   1:  public AuthenticationServiceClient()
2: : base("BasicHttpBinding_AuthenticationService", UriHelper.GetHost() + "B2B2/Cotizador/AuthenticationService.svc"){}


It will be useful for pictures too:

   1:              string uri = String.Format("{0}/Images/{1}.jpg", UriHelper.GetHost(), productId);
2: image.ImageSource = new BitmapImage(new Uri(uri, UriKind.RelativeOrAbsolute));

Hope this helps.
Don't forget to vote for your favorite topics.
I format my code using Manoli's website

martes, julio 29, 2008

Silverlight Tip of The Day - Vote for The Future Posts

Before I started writing this column, I began writing ideas for future posts and the list seems to grow faster than the daily frequency my posts have. So this is a list of posts in the queue, you can vote for them either by e-mail of leaving a comment.

Because of time constraints I have not been able to post some of the interesting topics.

  • Debugging Tips
  • Deploying
  • Cross Domain Calls
  • Problems Debugging
  • Recommendation of cool tools (for Dependency Injection, AOP, extensions, etc)
  • Model-View-ViewModel Pattern
  • Handling Image Paths
  • Using ASP.NET Providers (Membership, Roles, Profile)
  • Styles and Templates
    • Basics
    • Controls
    • Create a Clean Style for ListBox or ItemsControl
    • Change ListItemStyle
    • Blend and Styles
    • Blend and Templates
    • Visual State Manager
    • Visual State Manager and Blend
  • Blogs I read and cool links
  • Patterns for code reuse between Silverlight and .NET or .NET Compact Framework
  • Patterns for XAML code reuse between Silverlight and WPF
  • Silverlight Unit Testing
  • Test Code reuse
  • Refactoring your ASP.NET code to Silverligtht
  • Changing patterns from ASP.NET to Silverlight
  • Dummy Data and Better Design Experience (See controls with data in Blend)
  • Services and Security
  • Interoperability (JavaScript-.NET)
  • Caching and ClientSide Persistence
  • Silverlight Disconnected Client - Designing for Occasionally Disconnected Systems

Vote for your favorite topics, but remember, they might take a while to appear, If you want to learn a topic for today's project, probably this is not the place and you would be better off in the SL Forum, another blog or reading a book that gets you from a to z, but this can be an useful resource to learn SL a step a day or find some hidden tricks.

The idea of this column is it to be something simple and a quick daily read. Something won't take you more than 5 minutes (and that probably won't take me that much time to write either). When needed I will point you to other places to get deeper info, so open your favorite RSS reader and subscribe now and remember to vote through e-mail or leave a message for the topics you would like to read soon here.

lunes, julio 28, 2008

How to Update a TextBox Binding OnPropertyChanged

When using TwoWay Binding, most properties get updated after the control's property changes, but the Text in a TextBlock is a different case, it gets updated after the TextBox lost focus. It makes sense, since the value might be incomplete and validations and other logic triggered at the Business Object level unnecessarily, but sometimes this is not the desired behavior.

WPF has an UpdateSourceTrigger as part of the Binding object and you could say something like:

      <TextBox Text={Binding Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}>

This is not available in Silverlight, but there's a quick workaround provided by Yi-Lun Luo in this thread.

        private void cantidadTextBox_TextChanged(object sender, TextChangedEventArgs e)
        {
            otherControl.Focus();
            cantidadTextBox.Focus();
        }

It's really ugly, but works.

 

viernes, julio 25, 2008

Style Inspector

Go check it out, it's a cool tool from the Delay, the name is self explanatory and the tool is really easy to use so this post is one line long. Well an a screenshot.

SilverlightDefaultStyleBrowser sample image 

jueves, julio 24, 2008

Sniffers and Silverlight

It's very useful to know what Silverlight is doing behind the scenes, what is requesting, from which URI, what it sends and what was received. My preferred sniffer is Web Development Helper by Nikhil Kothari. The important part of this tools, related to SL is that you can see exactly what is happening at the network stack, but go try it out. It's probably not a tool you will use daily, but add it to your toolbox and keep it close to your hand.

The bar integrates nicely into IE, here we can see that it got my TestPage, the XAP Package, called a Service and then get several pictures and finally called another Service. This information is important, we can determine the order in which things are hapenning, if a Service is being called to much or if we probably misspelled some address (more on this tomorrow).

image

The filter option is really useful, we might not care about images and only want to look for URLs with a svc extension.

image

We can go deeper and see the exact content of each request/response. In the following image we see the Request Headers and the XML of the Response.

image

Today I only presented the Silverlight related features, but the Web Development Helper does a lot more stuff than just a simple HTTP Logger.

Tomorrow I will talk about how to get different URIs based on the original request's address. I am running out of topics. Please suggest and I will write.

miércoles, julio 23, 2008

Visual State Manager

The Visual State Manager allows us to define different states for our controls. Most controls in Silverlight already use this technology and we can change them editing their template. The best example is the button, the next picture shows its different VisualStateGroups and its VisualStates in Blend.

image

VSM its a big topic and I will get to it in better detail in another topic, but for now consider it as the way to decouple behavior and design. The creator of the control would typically define the states and its transitions in response to certain events, for example, when the mouse is over the programmer will change the state to MouseOver. The designer can use blend to change the look of each state and define transitions (animations) between them. To start with, you would typically change the defined states of some other people's controls, once you start doing your own controls you might want to expose States, to change between them in response to events, simply use the following method:

VisualStateManager.GoToState(myControl, "myNewState", true);

It's not available for WPF yet, but it will in a next update (probably in SP1).

For a complete tutorial go to http://www.nibblestutorials.net/ and look for the new Blend 2.5 tutorials or check this webpage for an example on how to change a button style for the MouseOver state.

viernes, julio 18, 2008

Silverlight's DropDownList

SL doesn't have a DropDownList. It will in a next release, but while this happen we had to write one ourselves. I tried different options from here and here. The first is a really simple control we used as a basis, the second one is a dll with a lot of control, I only tried the ddl and have to say it had a couple of bugs, didn't worked as expected, specially with databinding.

Get the source code and tests. This is not a complete, fully functional, tested, component, it's simply an easy to use, composite control. The test suite only met what we needed and there might be a lot of uncovered scenarios. Anyway, you can either use it as it is, improve it to meet your need or simply as a rough example on how to do composite controls.

This control has a TextBlock and a Listbox. The listbox is collapsed and it contains the items of the ddl, when the TextBlock is clicked the listbox becomes visible and when the mouse leaves the listBox it's collapsed again. To use it, you can bind something to the control's DataContext and you're done. This will work for the default scenario where you just need to display text for each item and update the text in the TextBlock. The control doesnt support templates, and this is an enhancement you could easily made, simply exposing the listbox templates so you could change, for example, how each item is displayed and databound.

I left my post about the Visual State Manager for tomorrow since I have been asked for the ddl sample in this thread and by e-mail.

 

Professional Visual Studio 2008 is almost

 

In March of this year, Nick Randolph invited me as a guest author of Professional Visual Studio 2008 from Wrox. I wrote only 5 chapters, all about Team System (Server, Dev, Tester, Architect and DB Pro), it was tough, but was a great experience. I thought writing a few pages of topics I know would be easier, but being the first time I write something formal and amongst other projects, courses and all the VISA paperwork for Australia it was hard to get the time. Writing at 2:00 am was fun, more than correcting the mistakes the next morning. I'm really glad Nick invited me.

We are getting closer to its release date (July 28th). You can preorder it now on Amazon, read the table of contents or read more about this on a post from Dave Gardner or visit the book's webpage. I hope you like it. 

Use VisualTreeHelper to Navigate Through Objects Hierarchy - Part 2

Yesterday I wrote about the VisualTreeHelper class, today, I will present a class with extension methods useful to search for objects in a more convenient way. You can download the code here.

It's a static class with extension methods like GetChild, GetChildrenCount and GetParent, similar to the VisualTreeHelper methods, but cleaner to use. Compare:

VisualTreeHelper.GetChild(myControl, 0);

myControl.GetChild(0);

Ok, it's cleaner, but really doesn't add much value, but what about getting an Item by name instead of only by index (as provided by the VisualTreeHelper method):

myControl.GetChild("childrenName");

Or better yet doing recursive searches through all the object hierarchy:

myControl.GetChild("childrenName", true);

Methods like that would make scenarios like the one presented yesterday really easy to solve, for example to get an Item of a ListBox using VisualTreeHelper you would have to do something like this:

DependencyObject grid = VisualTreeHelper.GetChild(listBox, 0);
DependencyObject stack = VisualTreeHelper.GetChild(grid,0);
DependencyObject scrollViewer= VisualTreeHelper.GetChild(stack, 0);
DependencyObject scrollPresenter = VisualTreeHelper.GetChild(scrollViewer,0);
DependencyObject border= VisualTreeHelper.GetChild(scrollPresenter ,0);
DependencyObject grid2 = VisualTreeHelper.GetChild(border,0);
DependencyObject etc = VisualTreeHelper.GetChild(grid2, 0);
DependencyObject itemIReallyCareAbout = VisualTreeHelper.GetChild(etc,1);

Using extension methods you could nest calls and made it a bit simpler in one line of code, but not necessarily simpler.

//       Grid,          Stack,       ScrollViewer,ScrollPresenter,Border,Grid,etc,etc, MyItem
listBox.GetChild(0).GetChild(0).GetChild(0).GetChild(0).GetChild(0).GetChild(0).GetChild(1);

Not only that looks horrible, but the worst part is than if the designer decides to change the ItesmPanel or the ListBox Template, you would probably have to change your code, with recursive searches you would simply do something like:

listBox.GetChild("innerControlName", true);

Another useful method is GetChildren wich return an IEnumerable<DependencyObject>.

Tomorrow I will talk about the Visual State Manager.

miércoles, julio 16, 2008

Use VisualTreeHelper to Navigate through Objects Hierarchy - Part 1

In many scenarios we will require to get to the inner elements of our UserControl. The first option is to define x:Name attributes in XAML or use the FindName. But in scenarios where the hierarchy is created dynamically either through code or databinding this wont work. The VisualTreeHelper will allow us to get to the Childrens of an element.

A common scenarios is how to get to the rendered elements of a ListBox. Since Silverlight is datacentric instead of control centric, the Items collection will return the actual DataSource and not the controls as the GridView would in Web. For most scenarios databinding would do the trick, but imagine if you need to change the color of a TextBox inside a ListBoxItem or if you have nested ListBoxes and you need to iterate all the ListBoxes and get the value of their InnerListBoxe's SelectedItem. Well for this and other scenarios you can use VisualTreeHelper its a static class with many straightforward methods that receive a depencency object.

public static class VisualTreeHelper
{
// Methods
public static DependencyObject GetChild(DependencyObject reference, int childIndex);
public static int GetChildrenCount(DependencyObject reference);
public static DependencyObject GetParent(DependencyObject reference);
}


Tomorrow I will talk about how I created a simpler API using extension method and a bit of LINQ.



viernes, julio 11, 2008

Download Silverlight Applications from WebServers

This is something really easy to do, but can be confusing. Keep in mind SL will be run at the client and all your server needs to do is serve the package. The .xap file generated when you compile your application is nothing but a zip file. Some servers won't allow users to download content with a XAP (or unknown) extension, so an easy trick is to simply rename it to .zip.

For more information you can check this website

Tomorrow I will post about changing URLs between different webserver/deployment scenarios.

 

miércoles, julio 09, 2008

Open in Full XAML View

The XAML designer in VS 2008 is terrible, is not even as a XAML Pad tool because its slower. There's blend doing a great job, even if it were only for previews because it interprets the attributes of the desigener Namespace (xmlns:d="http://schemas.microsoft.com/expression/blend/2008") like d:DesignWidth="800" d:DesignHeight="80"  to set a Width and Height for design time. Well to the point in VS 2008 you will mainly work in XAML View, there VS is better than blend because of the intellisense, XML formatting and event handler generation, but it takes time to open the file and then switch. To set it as the default view go to Tool/Options/TextEditor/XAML/Miscellaneous and check the option "Always open documents in full XAML view".

image

This is the first post of a series, look for the Silverlight tip of the day tag in this blog for similar articles.

 

Silverlight Tip of The Day

Silverlight tip of the day is a new 'column' I'll be writing as a part of this blog. Simply look for the tag 'Silverlight tip of the Day'. I will try to do it daily, brief and to the point. It could be an useful resource for any SL developer.

jueves, julio 03, 2008

Contribupendence Day

El día de hoy se celebra el contribupendence day. Medio irónico el nombre y el hecho de que sea un día antes del Independence Day en Estados Unidos, pero el concepto es interesante. Definido por Jeffrey Blankenburg en este post.

Consiste en escribir recomendaciones o comentarios en alguna de las redes sociales o profesionales a 5 personas con las que hayan trabajado. Yo no soy muy fan de las redes sociales, sólo uso Facebook, así que ahí es donde dejaré mis comentarios.

Si leen este post hoy, ojala alcancen a dejar sus comentarios. Si ya lo ven otro día, ya paso y tendrán que esperar al próximo anio, ya que este tipo de recomendaciones no se pueden hacer cualquier día. Bueno por ser el primer anio pueden dejarlos un poco después.