Silverlight »

[24 Apr 2009 | 1 Comments]

A new release of my Silverlight Drag and Drop Manager has been released on CodePlex.  If you've been using the previous release, I strongly recommend updating to this version. 

This release contains a few bugfixes after community input, some general changes, better memory management and one breaking change.

  • Breaking change: the Drag and Drop manager has to know the main container in which it resides to make sure it can position the DragSources correctly when dragging (correct position, and on top of the other controls). Instead of requiring this to be passed to every DragSource/DropTarget, and instead of requiring the code to traverse the Visual Tree (which is processor intensive), I opted to require this main container to be set ONCE. You'd typically do this in the constructor of your Page, and you'd typically set this to be the main container of your complete application, eg: DragDropManager.InitialValues.ContainingLayoutPanel = LayoutRoot;
  • Bugfix: DragSources now correctly display on top of other controls (DropTargets) when hovering. In the previous release, this wouldn't always be the case, depending on where your elements were in the Visual Tree.
  • Bugfix: the Content-property of a DropTarget now correctly reflects the DragSource it contains. In the previous release, the DropTarget would visually contain the correct DragSource after dragging, but the Content-property wouldn't correctly reflect this - now it does.
  • Change: DependencyProperties are now uses instead of regular Properties (where it makes sense). This means you can now Databind, Animate, … the DragSource/DropTarget-properties
  • Change: DragSource and DropTarget now implement the IDisposable-pattern, to clean up resources & handlers.

 

All this, a running example, source code, documentation and more: Silverlight Drag and Drop Manager @ CodePlex.  Enjoy! :-)

Drag and Drop Manager, CodePlex, Silverlight »

[26 Feb 2009 | 5 Comments]

A few weeks ago, I started thinking about designing custom controls for Silverlight, controls I could re-use in various projects.  Instead of just playing around, I figured I might as well make something I could put to use.  Seeing I didn’t find a true, free drag ‘n drop control, I decided to make one myself.

That little project evolved into a drag and drop manager for Silverlight.  There’s still room for improvement, but I’m quite happy with where the project is at at the moment.  And because other people might be able to use a control like this, I decided to make a Codeplex project, so everyone can get this control for free, including sourcecode! :-) 

For those of you who don’t want to read the rest, here’s the link to Drag and Drop Manager @ Codeplex.  And of course, an online sample!

 

The Silverlight Drag And Drop Manager consists of 2 controls (and their corresponding event argument classes): *DragSource* & *DropTarget*.  The first one makes any control draggable: just add the control (and if you wish, a ghost for that control) as the Content-property of the DragSource. 

The DropTarget defines a place in your application where you can drop your DragSources.  Every DragSource has a list of DropTargets on which it can be dropped, thus defining the possible DropTargets for a DragSource.  On the other hand, every DropTarget has a Content-property, which can contain anything that's a DragSource (assuming the correct rights).

Typically, you'd create a list of DropTargets & a list of DragSources on screen if you want to be able to drag those DragSources into your DropTargets.  If you want to have two lists, and want to be able to drag the DragSources back to their original position, you 'd create a list of empty DropTargets, and a list of DropTargets with DragSources as their Content.

Both controls can be added to your Silverlight-app using CodeBehind or using XAML notation.  They both expose different events you can bind handlers to, if needed, eg: DragSourceDropped-event, DropTargetEntered event, et cetera.

Next to that, both controls are *highly configurable*, so lots of possible scenarios are available.  Have a look at the sample application to see a few of them in action! 

 

Full sourcecode, documentation, online sample & binary: Drag and Drop Manager.

Comments are welcome, discussions, feature requests, bug reports, …  can be reported @ Codeplex.

Enjoy! :-)

Silverlight, WCF »

[3 Feb 2009 | 0 Comments]

When talking about security for service calls, there are actually a few things to consider.  First of all, how do you make sure the data sent over the wire is encrypted?  That's your first level of security: always make sure the data that's being sent over the wire is encrypted.  After all, unless we're working in an intranet environment, anyone could potentially look at the packets that are being sent. 

Luckily, securing this is easy to do: use SSL/https.  As far as SL/WCF is concerned, this comes down to setting your security mode to "Transport" in your binding.  That's really all there is to it.

On to the next level, what this is all about: securing your calls (for reference, I've made a Visual Studio solution documenting different ways of doing this - you can download that at the bottom of this post).  Lots of projects have some kind of requirement stating only certain people can call certain service operations - for example, you might only want people with a valid username/pw-combination to be able to call your operations, instead of letting everyone call them.  Seeing your servicehost will probably be publicly available (again, unless you're working in an intranet-environment),  anyone could potentially write a client to communicate with your services.  This obviously poses some serious risks.

So, on to username authentication on your service operations.  The idea is that you will require every service call to provide you with a username/pw-combination.  In the service operation, this combination will be validated and  the call will only continue if the combination is valid.  Thus blocking off everyone who hasn't got a valid  combination from using your services! Since we're using SSL/https to encrypt our message, we can safely send the username/pw over the wire.  A comparable method already exists out of the box with WsHttpBinding, but in  Silverlight, we're limited to basicHttpBinding, so we can't use that one.

This project shows different ways of implementing this:

  • No authentication.  This is a regular service call, everyone will be able to call the service, no username/pw is passed or sent over the wire, no authentication is done.  This is, obviously, not secure, and shouldn't be done outside of a controlled environment.
  • Authentication through method parameters. Username/pw are provided via parameters to the service method. Authentication is done in the service method.  This will work, but it isn't exactly a beautiful solution: all your service method signatures will have to have 2 additional parameters: username & pw.
  • Authentication through message headers. Instead of passing the username/pw to the method via parameters, they are passed by adding them to the message header of the message which is sent over the wire. Once in the service method, they are extracted and authentication is done.  This is already a lot better than the previous method: no additional parameters are required.
  • Authentication through message headers by implementing an operation behavior. Same as the previous method, but instead of writing code in every method to check username/pw, we write this code once in a custom operation behavior. Every method decorated with this attribute will automatically perform username/pw authentication. This is the preferred way to implement username/pw authentication.

Conclusion: nice code, not too much clutter, encrypted messages & safe calls! :-)
For those of you who want to read more about this (and then some), I got A LOT of help from the reference made by David Betz - give it a read if you find the time.

As usual, full source code is included.  You can download that here.  Enjoy!

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.