General, Presentations and sessions »

[26 May 2009 | 0 Comments]

Quick "plug" ;-) 

 

In the upcoming weeks, Maarten Balliauw (one of my collegues, an expert in ASP .NET MVC & PHP) and I will be giving a few sessions together in The Netherlands: on Friday the 29th of May, we'll be speaking @ Microsoft's DevDays in Den Haag, and on Friday the 12th, we'll be speaking @ the Dutch PHP Conference in Amsterdam.  The session we're delivering is called "PHP & Silverlight".

 

What can you expect?  Well, we'll have a look at how to integrate PHP & Silverlight, and at the SL programming model in general.  I'm delivering the Silverlight-part, my collegue Maarten is delivering the PHP-part of the session.  It's not an in-depth level 400 session, but it's meant to give you an idea of how you can use PHP & Silverlight together (creating a SL-project in Eclipse, hosting SL on a PHP-page, using a PHP-webservice from SL), and at the same time give an intro on what Silverlight can do, focussing on the - in my opinion - 4 keywords everyone should know & understand when developing Silverlight: DataContext, DataBinding, INotifyPropertyChanged and IValueConverter. 

 

So, if you happen to be in the neighbourhood, come check us out and/or join us at the bar for a drink after the session! ;-)

 

PS, if you're coming to the Amsterdam session, make sure you take a few extra days to stroll around the city - it's not Barcelona, but it's a really nice and relaxing city with a few great places to visit; one of my favourite cities in Europe, actually.

Silverlight, .NET, RIA »

[18 May 2009 | 0 Comments]

One day, two posts! :-)  A member of the Silverlight .NET forum asked how he could go about making a Silverlight combobox editable.  Well, it's actually easier than you might think, so for all of you who want this kind of behaviour: here's how you do it! :-)  The same technique can also be used to make an editable listbox, and usual, sourcecode is included at the end of this post.

 

I designed a dummy data-object for binding to the combobox.  This is a small class which has a Description-propery, an ID and an InEdit-property (to  and it implements the INotifyPropertyChanged-interface, so it can notify the UI when its value changes.

   1: public class Dummy : INotifyPropertyChanged


   2:     {


   3:         public int ID { get; set; }


   4:  


   5:         private bool pInEdit;


   6:         public bool InEdit


   7:         {


   8:             get


   9:             {


  10:                 return pInEdit;


  11:             }


  12:             set


  13:             {


  14:                 pInEdit = value;


  15:                 NotifyPropertyChanged("InEdit");


  16:             }


  17:         }


  18:  


  19:         private string pDescription;


  20:         public string Description


  21:         {


  22:             get


  23:             {


  24:                 return pDescription;


  25:             }


  26:             set


  27:             {


  28:                 pDescription = value;


  29:                 NotifyPropertyChanged("Description");


  30:             }


  31:         }


  32:  


  33:         #region INotifyPropertyChanged Members


  34:  


  35:         public event PropertyChangedEventHandler PropertyChanged;


  36:  


  37:         public void NotifyPropertyChanged(string propertyName)


  38:         {


  39:             if (PropertyChanged != null)


  40:             {


  41:                 PropertyChanged(this, new PropertyChangedEventArgs(propertyName));


  42:             }


  43:         }


  44:  


  45:         #endregion


  46:     }



Next, we need to build the datatemplate of our combobox.  Essentially, we'll have two "views": a normal view, and an editable view.  We'll use a button to switch between these views.




   1: <ComboBox.ItemTemplate>


   2:     <DataTemplate>


   3:         <Grid>


   4:             <Grid.ColumnDefinitions>


   5:                 <ColumnDefinition Width="200"></ColumnDefinition>


   6:                 <ColumnDefinition Width="Auto"></ColumnDefinition>


   7:             </Grid.ColumnDefinitions>


   8:         


   9:  


  10:             <TextBlock Text="{Binding Description, Mode=TwoWay}" 


  11:                        HorizontalAlignment="Left" VerticalAlignment="Center"


  12:                        IsHitTestVisible="False" 


  13:                        Visibility="{Binding InEdit, Converter={StaticResource BoolToVisibilityConverter}, ConverterParameter=contra}"/>


  14:  


  15:             <TextBox Text="{Binding Description, Mode=TwoWay}" 


  16:                     Visibility="{Binding InEdit, Converter={StaticResource BoolToVisibilityConverter}, ConverterParameter=pro}"


  17:                      HorizontalAlignment="Left" VerticalAlignment="Center"/>


  18:  


  19:             <Button Width="60" x:Name="btnEdit" Click="btnEditConfirm_Click" Content="Edit" Grid.Column="1" 


  20:                     Visibility="{Binding InEdit, Converter={StaticResource BoolToVisibilityConverter}, ConverterParameter=contra}" />


  21:  


  22:             <Button Width="60" x:Name="btnConfirm" Click="btnEditConfirm_Click" Content="Confirm" Grid.Column="1"


  23:                     Visibility="{Binding InEdit, Converter={StaticResource BoolToVisibilityConverter}}"/>


  24:  


  25:         </Grid>


  26:     </DataTemplate>


  27: </ComboBox.ItemTemplate>



To make sure the correct view is shown, I use a convertor to convert the InEdit-value of my object to a Visibility-property.  When InEdit is true, the textbox & confirm-button will be shown, when it's false you'll only see a textblock and an edit button.  For reference, here's what the convertor looks like:




   1: public class BoolToVisibilityConverter: IValueConverter


   2:     {


   3:  


   4:         #region IValueConverter Members


   5:  


   6:         /// <summary>


   7:         /// Convert method from bool to visibility


   8:         /// </summary>


   9:         /// <param name="value">the boolean/visibility value value</param>


  10:         /// <param name="targetType"></param>


  11:         /// <param name="parameter">mappingmode = pro or contra.  Pro will map true to visible, contra


  12:         /// will map true to collapsed</param>


  13:         /// <param name="culture"></param>


  14:         /// <returns></returns>


  15:         public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)


  16:         {


  17:             bool normalDirection = true;


  18:  


  19:             if (parameter != null)


  20:             {


  21:                 if (parameter.ToString().Trim().ToLower() == "contra")


  22:                    normalDirection = false;


  23:             }


  24:  


  25:             if (value is bool)


  26:             {


  27:                 if ((bool)value)


  28:                 {


  29:                     return normalDirection ? Visibility.Visible : Visibility.Collapsed;


  30:                 }


  31:                 else


  32:                 {


  33:                     return normalDirection ? Visibility.Collapsed : Visibility.Visible;


  34:                 }


  35:             }


  36:             else


  37:             {


  38:                 return Visibility.Visible;


  39:             }


  40:         }


  41:  


  42:         public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)


  43:         {


  44:             bool normalDirection = true;


  45:  


  46:             if (parameter.ToString().Trim().ToLower() == "contra")


  47:                 normalDirection = false;


  48:  


  49:             if (value is Visibility)


  50:             {


  51:                 if ((Visibility)value == Visibility.Visible)


  52:                 {


  53:                     return normalDirection ? true : false;


  54:                 }


  55:                 else


  56:                 {


  57:                     return normalDirection ? false : true;


  58:                 }


  59:             }


  60:             else


  61:             {


  62:                 return true;


  63:             }


  64:         }


  65:  


  66:         #endregion


  67:     }



All we need to do now is handle the click-event of the edit & confirm button.  Thanks to the rich, two-way-databinding, all we need to do in these handlers is change the edit-mode: we use the DataContext of the sender to access the underlying object, and change the edit-mode-property.  We do not need to write our changes to the underlying collection nor commit them manually in any way, nor update the UI when a value is changed - Silverlights' databinding & notifypropertychanged-interface handles this for us. 




   1: private void btnEditConfirm_Click(object sender, RoutedEventArgs e)


   2:         {


   3:             Dummy tmpDummy = (Dummy)(((Button)sender).DataContext);


   4:             tmpDummy.InEdit = !tmpDummy.InEdit;


   5:         }



... and that's it, really. :-)  As said, the same technique can also be used to make your listbox editable (or any itemscontrol for that matter). 


As promised: sourcecode.  Enjoy!

Silverlight, .NET »

[18 May 2009 | 0 Comments]

A few weeks ago, a client asked me to come in to have a look at their Silverlight-application, since they were facing some problems with the asynchronous calls to services.  In particular: how do you go about blocking your UI when such a call is being made?  Mind you, I don't mean the type of "blocking" that hangs the UI, I mean the type that blocks the user from continuing or entering invalid info :-)

 

As I wrote a while ago: when you face problems like this, DO NOT try to attempt to make the service call behave as if it were synchronous.  Why?  Well, in short, it never rrrreeallly works, and it kind of defeats the purpose of using async calls to avoid an application that feels like it's hanging :-)

 

So, what can you do?  What if you have, for example, a button on your application which should not execute it's handler unless a few conditions are true, and what if one of those conditions is validated through a service?  Say you have a textbox, and depending on the value inputted in that textbox, the button should be clickable or not.  But: it takes some time to return from the async call checking the value in the textbox, so a fast user just might be able to click your button, even though the value in the textbox validates to false, meaning the button shouldn't be clickable.  In a non-async world, you could simply put your validation rules behind the button click, but in the async SL-world, this isn't an option anymore - if one of the validation rules requires a service call, you're stuck.

 

Don't fear though :-)  A few really simple rules apply to make sure your async calls won't pose problems when concerning user input, validation, etc.  This post will outline (some of) 'em, and provide you with a downloadable example project at the end of this post.

 

  1. the first one: change the way you handle your validation: instead of assuming something is valid until proven otherwise, assume it's invalid until proven otherwise.  Eg, if a button should only be clickable if every input field is valid, disable it by default, and only enable it after every field has been validated to true.  You might want to add handlers for validation to the lostfocus-event of your input fields, for example. 
  2. a second rule: do not execute async server side validation on the click of the button which defines wether or not the user can continue with the application.  Validate when you can, when it's needed, not at the last possible moment: otherwise, you might run into the problem where you want to execute code depending on what value is returned from your async call, but you have no way of telling WHEN it will return.  Therefore, I like to validate my fields on, for example, their lostfocus-event.
  3. third one: when validating or doing a server-side call, show this to your user.  Show a loading-icon or progress indicator, so the user won't start yelling at his computer screen, because the value he inputted in the textbox is valid, yet the button to continue is still greyed out.
  4. fourth one: disabling input, clicks, et cetera can be done in various ways: removing handlers, disabling a visual or setting the IsHitTestVisible-property to true could all be considered.
  5. fifth one, not a rule, rather a suggestion: to avoid hammering, you might want to consider to "block" your application from starting too much service calls when validating.  You can do this by overlaying your application with a stretched canvas while the service call is being made (and consequently remove the overlay when the call returns).  This, however, should be handled with care, 'cause using it too much might give the impression of a non-responsive app.

 

A small example project using a few of these techniques can be found here.  Hope this helps some of you out! :-)

Silverlight, WCF »

[7 May 2009 | 0 Comments]

Ever ran into the problem, when talking via WCF to a service, all your service calls fail because the servicehost-address in the generated WSDL is wrong?  In that case, this post is for you! :-)

Think of a network setup like this:

  • you've got a Silverlight-app, speaking with a bunch of services through WCF, over https.
  • however, your app doesn't talk directly to your servicehost.  It talks to a proxy.  And that proxy forwards to an internal load balancer.  And that load balancer in turn forwards to different web servers containing the servicehost installations.

This is the setup I was dealing with @ a certain company.  The app worked correctly in dev & test, where no proxy/load balancer was used.  However, when rolling it out to the production environment, everything started to go horribly wrong... every service call failed.

 

After taking a look at the WSDL of one of the services, it seemed that the problem was related to the network setup: the address in the WSDL wasn't the external address anymore, it was the address of (one of the) the internal web server(s) (yes, even behind the load balancer) where the servicehost was installed.  Needless to say, this was reason all the calls failed, seeing the internal address was off course inaccessible from outside.

 

Pretty annoying problem.  I started looking around a bit, and found out more people seemed to have this problem.  I've read various posts describing possible solutions with custom bindings (not that easy when using Silverlight, since not everything WCF-related is available), and the general sentiment portrayed in the posts seemed to be that this was a shortcoming of WCF.  Another post described a new setting in 3.5 SP1, baseAddressPrefixFilter, that was supposed to solve this problem. However, that didn’t do the trick. In the end, we could off course have opted to just write a custom factory – that would definitely solve this problem; but that just didn’t feel right – surely, there must be a better way to solve this problem? After all, the network setup described isn’t that uncommon in Enterprise scenarios.

 

After a lot of searching & trial and error, it was one of my collegues (our WCF specialist) who put me on the right track: he figured this wasn’t a WCF problem – after all, WCF gets it’s addresses from IIS bindings, so he thought the problem was IIS-related, not WCF-related. And after looking into this, turns out he was right! Using appcmd.exe, we set the bindings in IIS on our website behind the loadbalancer to bind to the external address we wanted to see in the WSDL. After doing this, when WCF gets to the load balancer, this last one knows through the bindings what address to return, and thus the generated WSDL contains the correct (external) address for service locations!

 

So, quick tip for everyone: if you’re using a network setup as described above, and you get a WSDL that contains the wrong hosts/service op locations, first have a look at your IIS configuration/bindings, before diving into (or blaming…) the lesser-known depths of WCF! :-)