July 2009
M T W T F S S
« Jun    
 12345
6789101112
13141516171819
20212223242526
2728293031  

TechFriday: Building Custom Behaviors

Okay, I missed Tech Friday, so I decided to make it Tech Weekend instead. I attended the June Mix-It-Up: Re-MIX last Thursday and was able to catch up a bit on the new technologies. I have been busy with a few other things at work and I am ashamed to say, I have been lagging behind! :|

One of the things that interested me is behaviors in Silverlight 3. If you do a bit of searching you’ll find quite a few articles on behaviors. Basically, it’s the ability to encapsulate “behaviors” that you can reuse on different UIElements that developers can write and have their designers use (with drag and drop of course) to earn brownie points. Expression Blend 3 comes with a few behaviors out of the box. They’re the ones listed in the screen shot below, apart from the first one which is the behavior I created:

image

My favorite, I would have to say is the MouseDragElementBehavior. To use it, all you have to do is drag and drop it to any element in your app to enable drag and drop capabilities. There’s just so much you can do for interactivity with that behavior alone. I remember this being one of the things I use to code time and time again with previous projects I used to tinker with.

Another behavior that I’ve always wished I could encapsulate was the “bring to front” behavior. Say you have a bunch of UI elements scattered in a pile on the screen, you sometimes want it to behave in such a way that an element you click on gets floated to the top. This is probably a behavior that you would like to use in several scenarios/apps so it makes sense to build a behavior for it, and reuse it across different projects.

WARNING: I think I’m using a different build of Blend so I won’t get into the details of where to get which assemblies. I’ll update this post once Blend 3 is out, but I think what’s more important is understanding how building a behavior would be like more or less.

Basically what I did was build a Silverlight Class Library that inherited from the Behavior generic:

public class BringToTopBehavior : Behavior<Canvas>
{
//some code here
}

When creating your own behaviors, Canvas would be the object you would like to apply your behavior to. Next thing to do is override the onAttached() method:

protected override void OnAttached()
{
    base.OnAttached();

    AssociatedObject.Loaded += new RoutedEventHandler(AssociatedObject_Loaded);

}

AssociatedObject would be the the actual instance to which the behavior is attached. What I did here is add an event handler to the Loaded event because I wanted to attach another event handler to each of the objects that gets loaded into the canvas. I can only get the children once the UI element has finished loading. My Loaded handler looks something like this:

 

void AssociatedObject_Loaded(object sender, RoutedEventArgs e)
 {

     foreach (var child in AssociatedObject.Children)
     {
         child.MouseLeftButtonUp += child_MouseLeftButtonUp;
     }
 }

What I’m doing is attaching a handler to the MouseLeftButtonUp event for each of the objects contained in the Canvas in question. This handler is defined as:

void child_MouseLeftButtonUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
    BringToTop(sender);
}

I created a few private methods to handle sorting the z-orders of the elements contained in the Canvas:

private void BringToTop(object element)
 {

     Canvas p = (Canvas)((FrameworkElement)element).Parent;
     int z = getHighestValue(p);
     for (int i = 0; i < p.Children.Count; i++)
     {
         var child = p.Children[i];
         if (element.Equals(child))
         {
             child.SetValue(Canvas.ZIndexProperty, z);
         }
     }
 }

 private int getHighestValue(Canvas p)
 {
     int highest = 0;
     foreach (var child in p.Children)
     {
         var val = (int)child.GetValue(Canvas.ZIndexProperty);
         if ( val > highest) {
             highest = val;
         }
         child.SetValue(Canvas.ZIndexProperty, val - 1);
     }
     return highest;
 }

This probably isn’t the best implementation of this behavior but it gets the job done :)

USING THE BEHAVIOR

Once you’ve finished writing your behavior you can compile the code and reference that dll into any of your existing projects and start using the behaviors. Right-click on references, click Add Reference, and navigate to the compiled dll of your custom behavior.

image

Once you’re done, you should be able to make use of this behavior through blend. In my case, I can click and drag BringToTopBehavior to my chosen Canvas and I would see the following:

image

image

Now you’ll notice, however, when I try to drag and drop the behavior to the Grid panel, it tells me that it’s not a valid drop target.

image

This is because, in my definition of my behavior, I’d specified that this behavior can be applied only to Canvases. But now, I realize the same behavior can apply to any Panel object. What I can do now is update my behavior definition to, instead of Canvas, have it apply to Panel instead:

public class BringToTopBehavior : Behavior<Panel>
  {
      //somecode
      private void BringToTop(object element)
      {

          Panel p = (Panel)((FrameworkElement)element).Parent;
          //some code
      }
      private int getHighestValue(Panel p)
      {
          //some code
      }
  }

With this change, I should be able to apply the behavior to any UIElement inheriting from Panel. I’ve zipped up and uploaded the code for this project. Feel free to download and explore here:

For more about the greatness of behaviors, check out this Mix Video: http://videos.visitmix.com/MIX09/C27M and of course the link to the behavior pack used in the demo: http://gallery.expression.microsoft.com/en-us/MIXBehaviorPack

Housekeeping..

I decided to clean up my blog over the weekend. Actually, I was considering for a while there buying yet another domain and starting all over but then I realized, there really wasn’t any point to that. I had just become lazy to maintain this one because I felt it had become a bit messy. So I decided to do a few things: 1. Upgrade my wordpress installation to 2.8 (had been on 2.5 for the longest time :| ) and 2. Delete the twitter integration.

1. Surprisingly, it wasn’t as painful as I thought it would be. This guide details everything, i think the most difficult part was step 0, which I skipped. I thought, well, if this installation messes up then I guess it’s time for a restart :p. Luckily, it didn’t. It was just a matter of copying over the new wordpress files and running the script. Definitely not as painful as I had imagined. The upgrade made me feel good, at least gave me a feeling of some sort of freshness. ;)

2. I realized that my twitter integration thingamajig was making me more lazy to blog. Plus, It made my site look like crap whenever there was silence. I realized, if my friends want to read about my twitter activities, they’d probably go to my twitter page. I delete my aggregated twitter posts. Well I guess not all of it, it was too taxing to delete them all so I just went as far back as I could and gave up. I think there are still more in the archives but at least my front page is cleaner now. :)

I have decided I should put more effort into blogging, maybe set aside some time in a week at least. I know it’s going to be good therapy for me if I do.

Tech Friday: Your Own Custom Search Providers

Not the most techie thing to do but hey, today isn’t the greatest day to be using much of my brain as most of it is concentrating on agonizing on pain. I was browsing around the blogs I monitor and found a post by Long Zheng talking about a little experiment that showed how much branding had an impact on peoples perceptions about search engines. Check out his post if you want to know more. Down the comments, I found someone saying that he wanted to make it his default browser search and saw that he created a search provider. I tried installing it but I am guessing it only works for Firefox. So I went ahead and created my own which I found was quite easy for IE8, especially with the tools that they have out there.

1. Go to http://www.microsoft.com/windows/ie/searchguide/en-en/default.mspx where they already have a list of popular search providers. They also have a custom-search-provider-generatorer if you want to create one of your own :)

image

2. Go to the search page that you would like to create a provider for and search for TEST (all caps). When the results page come, paste the URL in the text box provided and name your custom search provider

image

3. Now you can choose to install the provider straight from the page, but if you’d like to share it on your blog/web page, what you do next is click on View XML. It should take you to a page similar to the one below:

image

4. Next step is to go to File->Save As and save the page to your local drive as anything-you-want.xml and upload it to your webserver, skydrive, or anywhere visible to the internet at large.

5. Now on the page where you want to share your provider, you’ll need a link that will point to the following code "javascript:window.external.AddSearchProvider(’http://www.aimeegurl.com/blindsearch.xml’);". In my case, i have this page:

image

with the following code to the Add Blind Search link:

image 

And it’s that simple :)

I know, I owe a super tech friday next week… especially since I skipped last week! ^_^

Tech Friday: The Orientator

I was thinking of an app to build for tech Friday and I remember running in to @willyfoo the other day. He mentioned he needed an application that would read in EXIF data from photographs and rotate them based on the orientation meta tag. It was quite a good exercise cause it allowed me to play around with a few things.

 

Problem 1: EXIF what?

Although I play around with photography once in a while (I bought a camera last year and I haven’t put any serious effort into it just yet), there are a few concepts which I have yet to understand. So apparently, cameras have a way of storing meta data into the photos you take. Some cameras store what its orientation is when you take a picture. So today, I brought my camera to work and took a few photographs as test photos. I found an existing library on CodeProject that will allow you to read EXIF data from photos called ExifLib.

So now, I can extract the data. The next step was understanding what code means what. http://www.impulseadventure.com/photo/exif-orientation.html gives a graphical explanation for the values of the Orientation metadata.

Problem 2: UI

To be honest, this is something that really needs to be thought through. I am guessing traditional applications would have a UI such as this that will allow you to select a file you want to “fix”. But then I thought, what if I wanted to do a batch job? I guess I could then select a directory. And then I remembered the challenge I had when I dealt with photos when uploading to facebook where my photos aren’t always in the same directory.

image

I then remembered a tweet by @MSExpression pointing to a blog post by kirupa where he talks about how you can enable drag & drop onto WPF components. So that is settled, Drag & Drop. I built a simple UI with a ListBox where you can drag your files to and an Image component where you can preview the rotated image.

image

There might be cases when the application messes up the auto orienting and you’d rather do it yourself manually. The UI allows you to select/de-select the files you want to save changes to. I have to say, it’s not the prettiest or most intuitive way to do it but I am not creative so this will have to do.

Problem 3: Preserving EXIF Data

I had originally thought it would be as easy as

     1  Bitmap bmPhoto = new Bitmap(filePath);

    2  bmPhoto.RotateFlip(RotateFlipType.Rotate180FlipNone);

but I was wrong. First, I realized that although it would successfully rotate the image, it would also bloat up the file (as it was saved without compression) plus, it would lose all the EXIF data the photos had. I don’t think this is something that @willyfoo would have wanted ^_^. So I dug around and found this post that showed you how to resize and manipulate jpegs while preserving the metadata. I did a bit of trimming as the code had stuff to resize the image, which I didn’t want to do for this round. One issue though, is because it encodes the bitmap using some parameters that i can’t figure out just yet (am just lazy too :p) It bloats the file up by a bit.

Problem 4: Saving Changes

Because my UI shows a preview of the image that was rotated, I got some errors where “the file is being used by a process” once I loaded them up into the application and tried to rename/delete them. This post on the msdn forum showed the fix for this.

You can download the code here:

Issues:

The application is functional but there is definitely a lot of room for improvement :)

1. Design – I think this application can be a lot nicer looking if I actually spend time on it. There’s a lot the WPF platform can do to “jazz up” the look and feel of the UI. I think my biggest challenge right now is coming up with a concept that would be cool looking enough :p

2. I’m not sure what happens if I drag&drop none images into the application. This line was supposed to take care of that:

 

    1             if (e.Data.GetDataPresent(DataFormats.Bitmap))

    2             {

    3                 ///some code here

    4             }

But for some reason, files I drag&drop into the app don’t get recognized as a Bitmap. I had to use DataFormats.FileDrop instead.

3. Bloating of image. As I mentioned in problem 3, I’m not very familiar with how encoding works so the app actually bloats the image size quite a bit. I think the following lines take care of the encoding, but when I try to step down on the encParm, it makes the image size smaller than the source. I figured, bigger is better.

    1                 System.Drawing.Imaging.Encoder enc = System.Drawing.Imaging.Encoder.Quality;

    2                 System.Drawing.Imaging.EncoderParameters encParms = new EncoderParameters(1);

    3                 System.Drawing.Imaging.EncoderParameter encParm = new EncoderParameter(enc,100L);

    4                 encParms.Param[0] = encParm;

    5                 ImageCodecInfo[] codecInfo = ImageCodecInfo.GetImageEncoders();

    6                 ImageCodecInfo codecInfoJpeg = codecInfo[1];

 

That’s it for now, until next Tech Friday!

Tech Friday!

I hereby declare that Friday mornings will now be committed to leveling up my technical knowledge. For this morning, I watched a session on http://www.visitmix.com which talked about Building Microsoft Silverlight Controls in Silverlight 3. Check out Karen Corby’s session at http://videos.visitmix.com/MIX09/T16F

Some really cool features of Silverlight 3 she talks about are Theming, Validation States, and a few others. She also does a very comprehensive walkthrough on creating a custom rating control.

Get Microsoft Silverlight

 

You can also find the code and presentation from this session on her blog at http://scorbs.com/2009/03/23/mix-09-building-microsoft-silverlight-controls/

And for more details on how the Validation works, check out this Channel9 Video:  http://channel9.msdn.com/posts/mtaulty/Silverlight-3-Beta-Validation/

Next time, I’ll start my Fridays earlier so I can actually build something.

How Do I Manage Two Twitter Accounts Using Just My Browser

Twitter has definitely become more and more popular both for work and for personal stuff. I have my personal twitter account which I use as I please: update the world about my bathroom habits, complain about unfortunate events, have random conversations with people, etc. I also have another work account which I have just started, with the goal of reaching out to the product development companies in Singapore (i have yet to think about how to go about this).

Sometimes I don’t like using the desktop clients because they tend to become a bit too heavy to keep running. So I keep twitter opened in my browser. The challenge is if I find someone interesting from my personal account and I want to follow them on my work account, it’s a bit taxing to logout-login.

Solution:

I make use of IE8’s InPrivate Browsing feature. To activate you can either press <Ctrl+Shift+P> or under Safety Menu, you can click on InPrivate Browsing.

image

You should be able to login with different credentials this way. I use the same method when I need to login with different Live IDs as well. (I think i have 7 o_O)

image

How I Upload Photos to Facebook

I just have to say, I am loving Windows 7 RC. One of things I like that is an extended part of Windows 7 is the Windows Live Essentials. On a fresh install of Windows 7, go into the search bar and type in “Windows Live Essentials” or you can search for it using your favorite search engine to get to the download portal.

image

There are a few things included in the suite but what I want to talk about today is the Windows Live Photo Gallery. It’s quite similar to Vista’s Photo Gallery but much, much better. You can either build your own plugins or download ones that have been built by others. I’ll be talking about one in particular, the Live Upload to Facebook Plugin.

Scenario is this: after importing my pictures into my machine, I want to review them before uploading them to Facebook (or flickr or whatever service you want). Think of it as quality control.

The Facebook upload control makes it easy to upload photos if you already know which photos you want. My problem is that, I import my photos into folders based on events. And rarely do I want to upload all the photos I’ve taken of an event up into facebook, or flicker.

image

What I do is use Windows Live Photo Gallery to quickly view and rate my photos 5 stars for the ones I want to upload to Facebook. (or i could do something like, 3 for facebook, 5 for flickr, etc.)

image  image

Another thing the software does is (1) identify faces in the photos and (2) allow you to tag people from your messenger list (or specify the name of someone who’s not)

image

I can then go back to the gallery:

image

And either sort:

image

or filter the photos in a specific folder:

image

And now, since I have the Live Uploader plugin installed I can easily select and publish the photos into facebook:

image

I’m prompted to select the account I want to use:

image

I can then either create a new album, or select an existing album to publish the pictures to. Straight from the software, you can also control permissions for the album

image

I can also then map my tags to my contact list on facebook for automatic tagging:

image

Once it’s done publishing, my friends will be able to see my photos published in my feed. YEY!

image 

What you’ll need?

Required:

Windows Live Photo Gallery – http://download.live.com/photogallery 

Live Upload to Facebook plugin – http://www.codeplex.com/liveuploadfacebook

Optional:

Windows 7 RC – http://www.microsoft.com/Windows/Windows-7/download.aspx

Lost!

Some things I need to know about life, I learn through running.

Today I was feeling a bit cocky and thought that my usual route here at lavender just wasn’t enough, so off I went trying to discover a new route. At first I was amused at how far I’d strayed off. After a while I got so distracted that I did lose my bearings and got myself lost. Below is how my run ended up looking like :|

I guess what I learned is that if you’re going to be deviant, and want to “stir things up a bit”, you’ll still have to be responsible about maintaining common sense, and always have yourself in check. You should never lose yourself in the moment so much that you just follow where things lead you. You have to keep a straight head about making sure you know where you’re going, and you have to be humble enough to admit you’ve gone astray. At this point, you stop, think, recalibrate and go for it. Mistakes are part of everything. And as long as you know to realize it when it happens, and are able to correct yourself as much as possible, then you’ll be fine.

Home Run

Parents left today and there was a cry-fest outside our gate as they loaded their bags into the cab. I didn’t realize how much i missed my parents till they were leaving. This whole day while we were going around, I felt that familiar weight on my chest. I’ve always been amazed how negative emotions can actually manifest itself into physical pain/discomfort (and curious how positive emotions manifest themselves). At the start of the day, I already broke down into tears while we were eating breakfast, and throughout the day i had that heavy feeling. I broke down again when they were getting into the cab. I decided to run it off rather than go for the unhealthy alternatives, and this is how i did today:

I feel a bit better. I don’t feel the heaviness on my chest that much anymore.

DPE RC!

In an effort to get our asses in shape, a few of my colleagues and I have started running. Yes, I know I’m a bit late into the running craze but hey, better late than never ;)   I have to say, I think I have a long way to go to get in shape.

This is my run for today:

Cant wait for Tuesday! Maybe I will run on my own on before then though. Like I said, I have a lot of catching up to do.