Silverlight Toolkit »

[22 Dec 2008 | 0 Comments]

I've noticed a few posts on the Silverlight.NET forums concerning the customization of the X/Y-axis labels of the Silverlight Toolkit's Chart control: trying to get the text to wrap, trying to get the labels to display vertically instead of horizontally, ... 

Well, this is easy to do (working with the December release atm), but finding the right property to set can be quite a challenge. ;-)  So here you go: an Axis has an AxisLabelStyle-property, which you can bind to a style.  In this style, you can set all the properties you want, which will be applied to each and every label on your X- and/or Y-axis.

Eg, this piece of code will make sure the labels on my horizontal Axis (in this case, containing a DateTime) are rotated a bit, have a set width, and I also apply some formatting to the date:

   1: <Style x:Name="HorizontalLabelStyle" TargetType="Charting:AxisLabel">


   2:             <Setter Property="RenderTransform">


   3:                 <Setter.Value>


   4:                     <RotateTransform Angle="300"></RotateTransform>


   5:                 </Setter.Value>


   6:             </Setter>


   7:             <Setter Property="RenderTransformOrigin" Value="0.5,0.5"></Setter>


   8:             <Setter Property="StringFormat" Value="{}{0:dd/MM}"/>


   9:             <Setter Property="Width" Value="65"/>


  10: </Style>




In my chart, I set the AxisLabelStyle to this defined style:





   1: <Charting:Chart x:Name="chtChart">


   2:                    <Charting:Chart.Axes>


   3:                        <Charting:DateTimeAxis AxisLabelStyle="{StaticResource HorizontalLabelStyle}" 


   4:                            Orientation="Horizontal">


   5:                        </Charting:DateTimeAxis>


   6:                    </Charting:Chart.Axes>


   7: </Charting:Chart>




And that's it.  Further customization can off course be done, depending on your specific needs.  Happy charting! ;-)

Silverlight »

[14 Dec 2008 | 1 Comments]

Ever felt the need to have something like a web.config-file, with settings you can change when they need to be changed without requiring a rebuild (eg: number of results in a grid, endpoints of certain services, certain ID's, ...)?  I know I have.

But by default, this isn't so easy in Silverlight.  Point is, Silverlight runs on the client, so changing a config-file on the server would have no effect on the way the application runs.  You  could, off course, just add an XML-file with some settings to your XAP-file - this file & corresponding settings would be available on the client, 'cause it's included in the XAP.  But you won't be able to change these settings on the fly (ie, once the client has downloaded your XAP, the settings will stay as they are), and more importantly: changing your settings would require a rebuild & re-rollout of your XAP-application.

Wouldn't it be nice if we could just access settings from the web.config of the web application hosting the Silverlight-control, which we can easily change when we need to (eg, change in requirements or rollout to a different environment), without rebuilding & on the fly? 

Well, with a little bit of work, we can do just that! :-)

1) create a web service in the webapp hosting your SL-app, which will read an entry from the web.config file and pass it back to the caller.  I've called mine "ConfigurationReader", and it's a simple ASMX-service.

   1: [WebMethod] 


   2: public string GetApplicationSetting(string ApplicationSetting) 


   3: {     


   4:     return ConfigurationManager.AppSettings.Get(ApplicationSetting); 


   5: }




2) add a service reference to this webservice to your SL-app.



3) as the ConfigurationReader-service can change location (it won't always be in the same location as it was when we added the reference!), it's necessary to pass this location to the  Silverlight-app somehow.  And to take it 1 step further, I'd like to make sure I can easily change this location, so I make it a key in the web.config. 



How?  On your aspx-page, you'll see there's an asp:Silverlight-control, hosting your SL-app.  This  control has a certain property, "InitParameters".  This is a very easy way to pass information from your aspx-page to your SL-app.  So, in the codebehind of the aspx-page, we set the InitParameters equal to the key in the web.config containing the location of the ConfigurationReader-service





   1: protected void Page_Load(object sender, EventArgs e) {     


   2: // get the correct URL of the configservice and pass it to the SL-app by using InitParameters     


   3: Xaml1.InitParameters = "ConfigurationReaderURL=" + ConfigurationManager.AppSettings.Get("ConfigurationReaderURL"); }




4) Now the location gets passed to the SL-app via InitParams.  To access these InitParams, write the following code in the Application_Startup of your SL-app (in App.XAML)




   1: private void Application_Startup(object sender, StartupEventArgs e) {     


   2: // get the service URL     


   3: Helper.ConfigurationReaderServiceURL = e.InitParams["ConfigurationReaderURL"];     


   4: this.RootVisual = new Page(); }




You'll see I keep the location stored in "Helper.ConfigurationReaderServiceURL", a simple static property.


5) One more thing and we're done: we need to change the way we call the ConfigurationReader-service from the SL-app, so it will call it from the right location.  You should also add a handler to handle the completed-event of the async call to our service and do the stuff you need to do with the setting you  just got from the web.config-file.




   1: // initialize service reference with correct URL, add handler to completed event and call the service 


   2: BasicHttpBinding binding = new BasicHttpBinding(); 


   3: EndpointAddress endpoint = new EndpointAddress(Helper.ConfigurationReaderServiceURL); 


   4: ConfigReaderServiceReference.ConfigurationReaderSoapClient client = new ConfigReader.ConfigReaderServiceReference.ConfigurationReaderSoapClient(binding, endpoint); 


   5: client.GetApplicationSettingCompleted += new EventHandler<ConfigReader.ConfigReaderServiceReference.GetApplicationSettingCompletedEventArgs>(client_GetApplicationSettingCompleted); 


   6: client.GetApplicationSettingAsync("Setting1");




And that's it!  Now you have a system in place with which you can easily use application  settings you can get when you want and/or change on the fly (try it by changing a setting in your web.config after the SL-app has been loaded, for example), without having to rebuild your SL-app or anything!



I've included full sourcecode for this for those who are interested.  Enjoy!

Silverlight »

[12 Dec 2008 | 2 Comments]

Last Wednesday, Microsoft got the chance to host a presentation on Silverlight at Devoxx, a big 4-day Belgian Java-event in Antwerp.  Yes, you read that correctly: a Java-event! :-)  Microsofts' Katrien De Graeve invited Ivan Porto Carrero and me to present a part of the talk to the audience - I would, off course, like to thank Katrien & Microsoft for this opportunity! 

Katrien talked about Silverlight in general, Ivan about Silverlight & Dynamic Languages, and I talked about a Silverlight port of the Parleys.com-application we did at work. 

We had a fun time, and we hope the people who saw us are now informed on what Silverlight is and what it can do - and maybe we even convinced one or two Java-developers? ;-) 

For those of you who weren't there (after all, I suppose most of the people reading this blog are MS-developers), the talk will be available at Parleys.com shortly, and you can download the presentation here.

Silverlight »

[10 Dec 2008 | 2 Comments]

From time to time, it's handy to have a popup available in most applications (often a dialog popup, so the underlying controls aren't accessible anymore), even in Silverlight-apps.  But just letting it appear out of nowhere doesn't look too nice; it's ok for most apps, but for a Silverlight app (which is, after all, about creating a rich experience, including some nice animations) I'd typically expect something more.  A nice animation, for example.  So I decided to make one. :-)

In lack of inspiration for a good name, let's just call it a "Scale-out-from-Sender"-popup, meaning the popup will start on the center of the button you click and scale out to the destination you want it to appear.

A picture says more than a thousand words, and a running app says more than a description of an app, so you can view this effect in action here.

 

Now: how do we get this done?

 

First of all, I wanted to create the animation dynamically, in code, so I could re-use it on any object - a user control in this case, but I could just as easily apply the generated animation to any other control.  I wrote an animation class to get this done, containing 2 public methods: CreateTranslateAndScaleIn and CreateTranslateAndScaleOut, both accepting 5 parameters: the object to be animated (in this case, the usercontrol which will "pop up"), and the X & Y-coördinates of origin and destination.  Origin would typically be the middle point of the button we clicked to show the popup, while destination would be the lower-left corner of the place where we want the popup to appear. 

The storyboard itself consists of a combination of DoubleAnimationUsingKeyFrame-animations: 2 scale-animations (scaleX and scaleY from nothing to 1), 2 translation-animations (to get the control from origin to destination) and an opacity-animation (to make it look nice ;-)).  I create these animations in code, add them to a storyboard, set the storyboards' target and pass the storyboard back to the calling procedure. 

CreateTranslateAndScaleIn will create the Storyboard to get the control from the sender location to the destination, CreateTranslateAndScaleout will create one to animate it back from destination to sender. 

 

Once we've got this in place, the rest is quite easy.  On the Page.XAML, I created 5 buttons on different places on the page to show the effect from different angles.  I also created the control I want to "pop up", myPopup.XAML.  This is a pretty standard control, its constructor accepts the needed coördinates and in the constructor the storyboard is created and started.  As a "background" to the control, I added a stretched rectangle, to achieve a "dialog box" effect - by doing this, the underlying controls aren't available anymore untill the popup is closed.  This also means the Storyboard is created not on the complete control, but on the Border-elements which defines the popup (we off course do not want to animate the "background").

One thing to keep in mind: if you want the animation to look right, put the RenderTransformOrigin of the element you want to pop to 0,0 (left-lower-corner), 'cause that's what the destination coördinates translate to.

The popup control also contains a "close"-button.  When this is clicked, the scale-out Storyboard is created and started, and a handler is added to its Completed-event to remove the control after the Storyboard has been completed.

 

... and that's about it! :-)

I could off course refine this a little more, eg by calculating the destination when I generate the animation instead of in the constructor, by getting the width/height from the control instead of having them hard-coded, etc; but this gives you a general idea of how this kind of effect is achieved.

All in all, not that hard to do, and quite a nice effect to have!  Enjoy playing with it, source code can be downloaded here.

Silverlight, RIA »

[5 Dec 2008 | 0 Comments]

Up until a few weeks ago, I thought of Silverlight (and other RIA-techs) as a great technology, which could easily keep on existing next to the HTML-pages we're used to.  Newssites like CNN, blogs like Wordpress or Blogger, ...  I didn't think these would be replaced by RIA's anytime soon. 

At this moment, I think I might have been wrong.  I've seen a blog-system, completely developed in Silverlight.  I've been using Mesh a lot, which is actually already bridging the gap between online & offline apps.  When you look at the feature which lets you drag 'n drop between your desktop and the browser window, it's like looking into the future... bounderies really are starting to fade.

And most of all: I'm finding less and less reasons why I would advise companies to start a new HTML-based site instead of a RIA-tech site - the advantages RIA-tech offers are tremendous.

Internet applications are becoming more and more interactive, more functional, more like regular applications - the fact that we've seen a steady rise of AJAX Frameworks, applications like Facebook, Netlog, ... can be seen as proof of that.

However: AJAX just doesn't cut it anymore.  It's a great technology, and it's pushed websites and the way we surf the web forward by a few big steps, but in the end it's just a workaround for the problems HTML-pages pose: a stateless model, which looks and feels different on the various kinds of browsers.

The gap between online and offline applications is starting to fade, and as far as I'm concerned, HTML (with or without AJAX, in all flavours - regular (D)HTML, ASPX, PHP, JPS, ...)  is on the way out.  It's been a nice ride, but the internet is evolving into something new - a richer internet, an internet which doesn't even feel like the internet anymore.  It won't die out in a few months or a few years, but it will. 

And it will be replaced by techs like Flex, Java FX and Silverlight.