Saturday, December 3, 2011

Visual Studio Live Orlando is almost here – December 5-9. Are you planning to go?


Visual Studio Live Orlando is just about here, and if you have not attended before or are a past attendee, check it out!

It’s a great opportunity to interact one-on-one with industry experts and Microsoft insiders, like Rachel Appel, Andrew Brust, Scott Cate, Billy Hollis and Rocky Lhotka on everything from .NET 4/Visual Studio 2010 and Silverlight to cloud computing, Windows Phone 7 development and HTML5. Plus, why wouldn’t you want to escape the December cold and be here in sunny Florida? Can you handle the ordered up weather below for this upcoming week at the conference?


This will be my 4th time to VSLive! and I think the knowledge and networking opportunities gained are worth the conference price 10 fold. I am asked so often how from new or junior programmers about how they can grow and advance their career. Attending a 1st class conference like this and learning from the experts is definitely a step in the right direction.

Interested in attending? There is still time, and if you are a programmer local to Central Florida come and see just how great this conference really is. Check out the special group rates offered for companies that bring 3 or more people. Register today at http://bit.ly/VSLOL11Reg.

Tuesday, November 15, 2011

What Happened To Windows Desktop Gadgets And Why Did Microsoft Abandon Them?

UPDATE (07/05/12): This link all but confirms that Desktop Gadgets will go away as I anticipated in Windows 8: Microsoft reportedly killing off desktop gadget support in Windows 8

A quick opinion entry here post bowling night (Yes I do have other hobbies besides programming!). Anyways back on topic I was quite disappointed to see a Tweet come across a few days ago stating that Windows Gadgets were being retired and the Gallery hosting them was no more. What?!?! I actually have always been a big fan of those things. I mean as a developer that sits in front of a machine with multiple screens for 8+ hours a day, I like all the information those things provide me at quick glance. After all we are in the information overload age (i.e. Smartphones, tablets, computers, etc.) and the gadgets fit right in to that role. Desktop gadgets were 1st made popular on Macs, then Yahoo came out with their "Yahoo Widgets", and finally Windows got in the game to offer support natively in the OS beginning with Windows Vista. However the gallery has been retired and support has quickly shifted away. Here is the official Microsoft Link on the status of the retired gallery and discontinued support:


Looking for gadgets?

Here is an excerpt from the above link stating it all:

"The Windows Live Gallery has been retired. In order to focus support on the much richer set of opportunities available for the newest version of Windows, Microsoft is no longer supporting development or uploading of new Gadgets."

OK I get it. Microsoft is positioning itself for Windows 8 and its new design including a focus on 'Metro Style Apps'. Windows Gadgets don't fit at all into that new design and really hinder in some ways the competing and improved look of Windows 8. You need folks to forget about these little anchored desktop apps and focus on Metro Apps in Windows 8. This could not be as strong of a directive with these 'dead weight' mid 2000 type apps lingering around (not really my thoughts, but probably the view at a meeting at Microsoft when the decision came to retire these widgets). I had already noticed a lack of developer interest and I understand this as well. It's not the sexy thing to spend time on in present day. If you were about to sit down and create a little weather app, would you make a Desktop Gadget or a Windows Phone 7 app for the marketplace? Easy enough answer. But even the minimal support was welcomed and still created a huge portfolio of selectable and free fun, productive, entertaining, and cool apps to have on the desktop. However I think the decision to retire the gallery and discontinue support is a bit premature and let me explain why. It is not often I disagree with Microsoft because I live for the technology they pump out of Redmond, but I am not on the same page with them on this decision.

There was a time from say 1993ish to 2005ish where it was almost a necessity to buy a new computer every few years to keep the hardware up with what the applications could do. Even simple tasks like having a browser open and Microsoft Word could be dauntingly slow on an older machine. So what does one do? Buy a new computer so multitasking became a possibility and didn't drive the user nuts. Also during this time period, the cutting edge industry development and the hardware were not that far apart. Using a Windows 98 box with VB5, Access, C++, etc. and building the best apps (excluding gaming) using the latest technology didn't require any special hardware. Using a standard home PC would allow one to create, build, and deploy these types of apps.

Now we have gotten to a point where I think us in the development community and those in the R&D sector moving the ball forward may not realize the disconnect that is upon us. The cutting edge technology and its expectations in my opinion will not excite a large portion of the market share. Sometime around the mid 2000's, PC hardware began to outpace the software running on it for the 1st time which helped drive costs down on PCs and allowed the consumer to breath a bit and not have to rush out to get the new OS and machine. "Hey if I can run my browser, email my family, and write Word documents, I am set!" Not everyone is 16 years old and rushing out to get the newest piece of hardware that supports the cutting edge technology, which we were all forced to do in years passed. Microsoft could rely on the fact that users would continue to buy newer, faster, smaller PCs and along with that the newest OS too. It was a nice harmony because the software and hardware naturally moved together and everyone (users and developers) had to keep up with the same pace. You didn't find too many Windows 95 users in 2003, 8 years after it came out, but you can certainly find a large portion of home PCs (and businesses too) that are still running Windows XP 10 years after release. This is because that stable, easy to use, machine doesn't warrant being replaced. In current day Microsoft can no longer expect the average user is going to buy a new piece of hardware to support the newest OS; that hand is not naturally being forced as it once was 10-15 years ago. Therefore support of what may be deemed 'legacy' technology or software (even if it is only 5 years old) has to be taken into consideration to keep the masses happy.

So what in the heck does that background have to do with Desktop Gadgets going away you ask? Well, I think for starters a lot of late migrators to Windows Vista or Windows 7 will be disappointed when they buy the computer and see one of the 'neat' features, Gadgets, is retired even before some had a chance to use them. But more prevalent than worrying about people who are behind in technology (hey you snooze you don't get to experience it like those of us that bought it on time, Ha!), is I wonder if Microsoft is going a little hard to place all their eggs in 1 basket with Windows 8. I don't think the masses will move quickly but this is not apparent by those of us in the technical community. We will all have it as soon as it is released to Beta and installed on Day 1. But that is a bad impression for the general use market share. I don't think everyone is going to abandon their PC for a tablet running Windows 8. And don't get me wrong; I don't think Microsoft is thinking this will happen either, but I do think some feel this is what "Everyone will be doing in 5 years..." I am not so convinced. I will be all over Windows 8 because of what I do and how much I like the technology, but I am not sure about Sister, Mom, Dad, Grandma, Friend 1, and Friend 2.

So I liken retiring the Windows Gadgets the start of Microsoft's reposition for its new OS, and is just the tip of the iceberg. I hope Microsoft doesn't continue to make decisions like this to slowly force people into buying Windows 8 because their nice, stable, Windows 7, Vista, or XP machine has 20% of its features retired or not supported. It's an aggressive stance and I get the feeling from the Build conference that Microsoft will be pursuing Windows 8 harder than any OS since maybe Windows 95. I just hope it does not come back to haunt Microsoft by leaving a bad taste in people's mouth by being unwillingly shuffled along faster than they care to. It's a fine line to walk.

This isn't the only instance were they suttly or explicitly phased out technology. For example, VS.NET 2010 will not support Windows CE development. Hold the horses!! I don't recommend making new CE apps at this point in time, but I have 1st hand experience working on a current 3rd party product that uses a propriatary device runnign on Windows CE. Makes total sense why Microsoft would not support CE development in VS.NET 2010: DO WP7 DEVELOPEMENT! But once again it's these decisions that I think don't agree with the masses as evident by the feedback from this Microsoft Connect entry:

No support for Windows CE and Compact Framework development in VS2010

So maybe a bit profound for the analyzation of why the Desktop Gadets went away, but I think there is a bigger picture here. And yes personally I am disappointed and don't think it would have slowed down Windows 8's new sexy features too much. You can still search the net for the individual gadgets if you are looking for a particular one, but they are already difficult to find so zip them up and save off the .gadget files on your machine. It will not matter beyond Windows 7 though because they will not be supported in Windows 8, so enjoy them on your already out-of-date Windows 7 PC (a little tongue-and-cheek there obviously). Or you can still use Yahoo Widgets which you can check out here, and they have a massive widget library:

Yahoo! Widgets

Well the nice thing about this blog is hopefully I can come back in a few years and maybe 'eat crow' showing I was all wrong. But for the time being I am disappointed to see the desktop widgets essentially discontinued, and I feel Microsoft may have missed the bulls-eye a bit on this decision.

Anyone reading this feel free to post links to websites, SkyDrive locations etc, to share .gadget files if you wish.

Wednesday, November 9, 2011

How To: Create A Thumbnail Image From A Video Using The Microsoft Expression Encoder SDK

In the modern day of the web, video players of all sorts of technology are being used from Flash, Windows Media Player, Silverlight, HTML, and many more. Commonly we will use a preview image (like seen on YouTube for example) to give a still image of what the video visually represents. You can accomplish the creation of this video thumbnail dynamically in .NET using the Expression Encoder SDK.

The idea is to load a video into a 'AudioVideoFile' object and then create a still image file based on a provided interval within the video. This gives managing video thumbnails a hands-off approach to creation saving a lot of time as opposed to someone needing to manually create this file from the Encoder product directly. Using the right naming convention, once created you could just load the thumbnail into your video player automatically without ever needing to touch the video.

To being you need to install Microsoft Expression Encoder and applicable service packs. As of this post the current version is Expression Encoder 4 SP2. The Expression Encoder 4 SDK and the documents are installed with the application. You can access the SDK from the Start menu by clicking All Programs and then clicking Microsoft Expression. The links below have the installations needed:

Microsoft Expression Encoder 4

Microsoft Expression Encoder 4 SP2

This method of creating a thumbnail is best suited for a WCF service or directly within a ASP.NET web application because of the required Encoder components. It must be installed on each server or machine where the code is ran. Therefore unless you have a limited user base, this may not work well within a WinForms or WPF application. In this case porting the functionality to a WCF service and having the remote applications call it to create the thumbnail would work best. This reduces the locations where the components need installed.

An interesting fact is you need the full version of Expression Encoder installed on the machine or server that has the code to generate the thumbnails, but you never actually need to open or use the Encoder product itself. In the past, I did have success installing a trial version of Encoder and having the code continue to run successfully with the SDK, but you will need to confirm or deny this independently. The SDK alone is not enough to allow the code to work; it relies on the Expression Encoder product being installed. For the purposes of this code here, you never actually have to open Expression Encoder.

After you have Expression Encoder, any current service packs, and the SDK installed you are ready to being. I recommend just making a little test harness in a web app or WPF app locally to see how it works. Then you can port it out to a service or in an actually application.

To being add the following references to your application from the following location (assuming you are using the Expression Encoder 4 SDK) "C:\Program Files\Microsoft Expression\Encoder 4\SDK\":

Now add the following 'Imports' or 'using' statements to your code:
Imports System.IO
Imports System.Drawing
Imports System.Drawing.Imaging
Imports Microsoft.Expression.Encoder
Next let's make a method named 'GenerateVideoThumbnailImage' that takes some input parameters about the location of the video, the size of the thumbnail to generate, and the path to save the generated thumbnail image. The code below shows using the Expression Encoder SDK to generate the thumbnail:
Private Sub CreateVideoThumnailImage(ByVal VideoPath As String,
ByVal SecondIntervalForThumbCapture As Integer,
ByVal ThumbnailWidth As Integer,
ByVal ThumbnailHeight As Integer,
ByVal ThumbnailSavePath As String)

'Create the AudioVideoFile object which stems from the Expression Encoder SDK .dlls
Dim avFile As New AudioVideoFile(VideoPath)

'Create a value equal to the length of the video
Dim FileDuration As Double = avFile.Duration.TotalSeconds
'Set thumbnail value to second interval indicated by argument passed in:
Dim ThumbnailLocation As Double = SecondIntervalForThumbCapture

'If the interval passed in is at a location longer than the video, then redefine an interval to the mid-point of the video.
If ThumbnailLocation > FileDuration Then
ThumbnailLocation = (FileDuration / 2)
End If

'Create the formatted filename to append on to the VideoFile (Format = "VideoFileName_thumb.png")
'Note: You can change this logic to be a passed in value or whatever you would like. This is not critical to generating the thumbnail image.
Dim FormattedFileName As String = Path.GetFileName(VideoPath)
'Strip off the video file extension and add an "_thumb" and the format extension (.Png will be used) to be saved to.
FormattedFileName = Path.GetFileNameWithoutExtension(FormattedFileName)
FormattedFileName += "_thumb." & ImageFormat.Png.ToString().ToLower()

'Create ThumbnailGenerator object to get thumbs from AudioVideoFile. Use the Width and Height arguments passed in to determine the size to Save.
Dim ThumbnailImageGenerator As Microsoft.Expression.Encoder.ThumbnailGenerator = avFile.CreateThumbnailGenerator(New System.Drawing.Size(ThumbnailWidth, ThumbnailHeight))
'Create the thumbnail image based on interval set above
Dim ThumbnailImage As Bitmap = ThumbnailImageGenerator.CreateThumbnail(TimeSpan.FromSeconds(ThumbnailLocation))
'Save the file to the ThumbnailSavePath argument passed in with the formatted file name (above) added:
ThumbnailImage.Save(ThumbnailSavePath & FormattedFileName, ImageFormat.Png)

'Clean up
ThumbnailImage.Dispose()
ThumbnailImageGenerator.Dispose()

End Sub
Here is a sample call to the above method that will output "MyVideo_thumb.png":
'Make a call to generate a thumbnail of the video at the '10' second interval (size will be 150x150) and save it to the same directory:
CreateVideoThumnailImage("C:\Videos\MyVideo.wmv", 10, 150, 150, "C:\Videos\")
Previously I have used the 'MediaItem' object and its 'GetThumbnail' method within the SDK to generate the thumbnail. I had success using this on Windows Server 2003 and the Encoder 2 SDK, but could *never* get it to work on Windows Server 2008 with either the Encoder 2 or Encoder 4 SDK. It works so long as the code is directly run within your application, but if you try to port it out to a service (i.e. WCF) regardless of the hosting type (IIS or Windows Service) and regardless of the user context (Administrator), the service would always throw the following exception:

"Microsoft.Expression.Encoder.InvalidMediaFileException: File type isn't supported. ---> Microsoft.Expression.Encoder.UnableToAnalyzeFileException: Exception from HRESULT: 0x80040218"

I had a lengthy MSDN post that was never resolved and can be read about here, but my strong recommendation is to port any use of the 'MediaItem' object over to using a 'AudioVideoFile' object. There seemed to be some underlying caching of credentials or some other oddity with trying to load the video file into the MediaItem constructor that I could never get to work properly. However with the code above, I can successfully implement it in a WCF service hosted by IIS or as a Windows Service. Just make sure to run the app pool hosting the IIS site or Windows Service under the LocalSystem or other Administrator account to make sure the service has the proper permissions.

Lastly, you may run into issues if you try and generate a thumbnail image from a video in which your machine does not have the codec installed. For information on this, please see one of my older posts that is listed below:

Fixing the "File type isn't supported" Error When Working With Expression Encoder SDK

Tuesday, October 25, 2011

Rooting a Motorola MB502 Charm On Android 2.1 Eclair to Store Apps On SD Card

Another post here outside the '.NET Realm' but I wanted to post some information to help users with the same or similar phone and issue. So I recently got a new unlocked Motorola Charm MB502 for $99 from NewEgg.com (here) so I don't have to be under contract for another 2 years with AT&T. This was my 1st experience with an Android based phone and I quickly found out its idiosyncrasies. However overall this is a fantastic phone for its capabilities and price so I am happy with it.

The phone has a miniscule 200mb or so internal memory and came with no MicroSD card. I starting going hog wild downloading all kinds of cool apps (for free of course) and in no time the phone memory was full. It was to the point where the phone would freeze and I couldn't even send or receive texts. So I had already planned to get a MicroSD Card so I got a Class 10 32GB PNY MicroSD card from NewEgg (this model). The card is amazing and has some crazy read/write speeds. So that's it I am all fixed right? 32GB is plenty of space. WRONG!

The Android 2.1 platform (codenamed Eclair and released January of 2010) only allows storing apps on the internal memory, and music and pictures can go on the external memory. Well that's a bit limiting, but there is a work around. Android 2.2 streamlines this quite a bit to a single command line statement, but on 2.1 it’s quite a bit more involved. However, everything I read for was a complete mess of steps and awfully written walk-throughs so I am mostly writing this post in case search engines pick it up to help out users of this phone or with a phone containing Android 2.1.

So let’s begin with the overall steps that have to take place to allow the phone to store apps downloaded to the external SD card:

1. Download the USB drivers for your phone and install them.
2. Buy a MicroSD card
3. Partition the MicroSD card into 2 parts using 'Mini Tool Partition'
4. Install the MicroSD card into the device.
5. Place the phone in 'Debug' mode when connected via USB
6. Connect the phone to the computer via the USB cable.
7. Root the phone with 'Super One Click'
8. Reboot the phone
9. Link the apps to the SD card using 'Link2SD'

It’s not that difficult to accomplish (can all be done in order in < 30 minutes depending on partitioning size on card), but the forum posts detailing these steps are incomplete. This process was compiled by about 6-8 different sources. Before getting started it is important to note, that while this is not an overly difficult procedure it is probably not for you if you do not have some savvy working with computers and mobile devices. The potential exists here to completely screw up your phone and have a mess on your hands. I am just posting this 'as-is' and have no real expertise on Android phones, so advanced follow up questions for anything related here are better directed to one of the Droid forums and not here. So let's get into each step:


1. Download the USB drivers for your phone and install them: You need to connect your phone to your computer and have it recognized. For the MB502 Charm, you can download the USB drivers at the following link -> Drivers for MB502 After installing the drivers, go ahead and connect the phone to the computer and make sure it worked.

2. Buy a MicroSD card: If you are only planning on installing apps and taking a few pictures then 8GB or 16Gb is plenty of space. However if you plan on dropping the entire MP3 library on your phone (as I did) then go for the 32GB size. As for Class? I recommend a Class 10 card because of the 10mb/s write speeds. Nice for transferring MP3 files to the phone and reducing lag time after taking a picture when being written to the device. If just doing simple apps and no music a Class 4 or 6 should suffice. I highly recommend getting a SD card adapter or something to plug in the MicroSD card via USB for partitioning outside the device in Step # 3.

3. Partition the MicroSD card into 2 parts using 'Mini Tool Partition': Download the 'Mini Tool Partition' (for Windows not the phone) utility to partition the MicroSD card from this here: Download Mini Tool Partition Once downloaded and installed, insert your SD Card adapter into a USB slot containing the MicroSD Card so it can be partitioned. The card must contain 2 partitions: 1 for the main externally written files (pictures and music), and the 2nd partition is for the downloaded apps. Before partitioning make sure to copy off an data on the card (unless it's new and has nothing on it). Open up Mini Tool Partition, right click on the drive representing the card (make sure you select the right drive!!) and say 'Delete'. Now let's make our (2) partitions. The 1st should be named 'primary' and be set as a 'Primary' partition. As for the 'File System': if you have a MB502 Charm then you have to use FAT32 for both partitions. The phone does not recognize the other format types. On other Android phones you can try ext2, ext3, or ext4. It is not a limitation of the Super One Click program, but rather the individual phone. As for size, most say 500mb to 1GB is enough for the apps since they are so small. I did 25GB for my primary, and did 5GB for the apps. You can divide the partitions how you feel is needed. Below are the properties for Partition 1:


Now create the 2nd partition; I named it 'Apps_Data'. It too must be created as a 'Primary' partition as displayed below:


Finally, when all selections have been made select 'Apply' in the upper-left hand corned to have the partitions made on the MicroSD card.

4. Install the MicroSD card into the device: Easy enough. Take the back cover off the MB502 and install the MicroSD card. It is not a requirement but I powered off my device, inserted the card, and then turned the power back on just to do the process cleanly.

5. Place the phone in 'Debug' mode when connected via USB: Consult your manual on how to do this. For the MB502 on the home screen tap the 'Menu' button (left soft key) and select 'Settings'. Scroll to and select 'Applications', select 'Development', and then turn on (check) 'USB Debugging'.

6. Connect the phone to the computer via the USB cable: I usually have my phone unlocked and on when I connect via USB. Give it a few minutes and make sure Windows (or whatever OS) recognizes the device.

7. Root the phone with 'Super One Click': In order for apps to eventually be placed on the MicroSD card, we need to have 'SuperUser' permissions for the Link2SD app. In order to gain this level of access we 'Root' the phone. Rooting the phone also allows you to uninstall any 'System' installed apps. I quickly learned one of the apps I downloaded installed a ton of junk as system apps, and I couldn't uninstall them...until I rooted the phone that is. The easiest way to do this is with an app named 'Super One Click' which runs on Windows (not the phone). Download the application from here: Download Super One Click Install the application and open it up in Windows. All you have to do is press the 'Root' button (displayed below). When asked if you want to install the app, I stated 'Yes' which allows SuperUser to work on the device. Once complete the device will be rooted. For a full list of phones which Super One Click works with, check out the following link: Compatibility List for Super Once Click



8. Reboot the phone: If the Super One Click does not prompt for a reboot after disconnecting the USB cable, then go ahead and disconnect the USB cable after the rooting process is complete, and power off and back on the phone.

9. Link the apps to the SD card using 'Link2SD': Go to the Market, and search and download 'Link2SD'. This application will allow you to manually select installed apps and move them over to the SD card. This process does not happen automatically, so make sure to move apps over to the SD card after installation. Sounds like it might be a pain, but it is really easy and takes only about 5 seconds to do. Once 'Link2SD' is installed, open it up. It is going to go through a series of steps to gain 'SuperUser' access and may ask you to reboot the phone after creating some boot scripts to be used. Follow all on-screen instructions including reboot if required. These steps are only 1 time and not required after completed successfully. I think the 1st time I tried Link2SD it didn't work so I rebooted the phone and tried again and it worked, so keep this in mind. After Link2SD finishes it configuration (including reboot), you are done! Open up the Link2SD app and scroll to any app you want to move over to the SD card and select it. Scroll down to select 'Create Link', and the press 'OK'. You will see a message about Link2SD getting 'SuperUser' access and then your app will be moved to the SD card! You can also use Link2SD to uninstall those pesky spam installed system apps if this happened to you. An app is installed on the system if you see its path start with /system/app/.... Don’t uninstall important apps, but it is useful to uninstall something that was never originally wanted.

That's it! If it didn't work, you probably want to go back through step by step and make sure everything worked properly. The Link2SD app is very picky about those partitions so make sure to get them right. If it is not working it might be because it does not recognize the type of partition you created. FAT32 is the safest bet and the only working one I found on the MB502 Charm. If you need more help, I recommend seeking out one of the Android User Forms where you can ask questions and get further help. ...or just fork out the money and buy a newer phone. :P

Thursday, October 13, 2011

Specifying Document Compatibility Modes for ASP.NET Intranet Sites using IE8

I noticed some oddities on the way an ASP.NET website I was working with was rendering on the intranet, but not through the Cassini development server in VS.NET 2010. This of course makes sense because the development server does not parse and render identical to IIS, but it was still puzzling.

After a bit of research I found that the following setting in Internet Explorer 8: Tools -> Compatibility View Settings -> ‘Display intranet sites in Compatibility View' was checked by default. This ends up having your site render in IE7 mode and was the cause of the odd rendering in my case (i.e. entire dropdowns scrolling along with the screen, HTML header tags not sizing properly, etc.).

The initial thought is just to deselect the option and allow the browser to work in IE8 standards mode. However since we are discussing 'intranet' applications, this problem would persist to all clients of the application unless a mass update was pushed out via group policy which is unlikely.

The easiest fix is to set the document compatibility mode for the site in the Master Page(s) or main page of the site to the browser standard you wish to use. The post is almost outdated as soon as it was published because it is speaking about a browser that is 2.5 years old, but as many enterprises are still on IE8 because of Windows XP, this unintended switch may not be favorable to the developer. All that must be done is add the following meta tag in the header of the webpage (the HEAD section) before all other elements except for the title element and other meta elements:
<!-- Enable IE8 Standards mode -->
<meta http-equiv="X-UA-Compatible" content="IE=8" />
After updating the site on the IIS server and bringing it back up in IE8, you will notice your site render properly even with the default IE8 settings to display 'intranet' sites in ‘Compatibility View’. This topic is actually much more involved than the specific piece of advice covered here, so look to the following if you need any further information.

Defining Document Compatibility

Friday, September 23, 2011

Begin StoryBoard Animation Within A DataTemplate In Silverlight

Animations in Silverlight are a great way to add a dynamic feel to the aesthetics of your Silverlight page or control. Within Silverlight, using a DataTemplate to define a control’s properties and look when a control will be repeatedly used or displayed is the perfect solution. However if you add an Animation to the DataTemplate, trying to set it in motion from the code behind is not as straight forward as it initially seems.

Let's say you have a simple animation and you want it to run when the 'MouseEnter' event fires. In VB.NET, the traditional thinking is to go into this event that is exposed by the created DataTemplate and call 'MyAnimationStoryboard.Begin()'. Guess what though, the app will build, run, hit the event upon having the mouse enter, but the animation will not begin. No exception is thrown, it is just nothing happens.

It turns out that the StoryBoard is only locally known to the object containing it within the DataTemplate, so we must 1st access that control's resources where the storyboard exists, and then we will be able to begin the animation.

So here is a DataTemplate with a Grid control and a StoryBoard. The code is being kept simple because the solution for this is in the code behind.
<DataTemplate x:Key="MyTemplate">
<Grid Width="100" Height="100"
Opacity="0.75"
MouseEnter="MyGrid_MouseEnter" >
<Grid.Resources>
<Storyboard x:Name="MyTemplateAnimate">
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(Shape.Fill).(GradientBrush.GradientStops)[4].(GradientStop.Offset)"
Storyboard.TargetName="path">
<EasingDoubleKeyFrame KeyTime="0:0:0.3" Value="0.296"/>
<EasingDoubleKeyFrame KeyTime="0:0:0.4" Value="0.384"/>
<EasingDoubleKeyFrame KeyTime="0:0:0.5" Value="0.475"/>
<EasingDoubleKeyFrame KeyTime="0:0:0.6" Value="0.529"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</Grid.Resources>

<Path x:Name="path" Data="M0,0L50,0L25,50L0,0L0,50L0,0">
<Path.Fill>
<LinearGradientBrush EndPoint="-0.419,0.662"
MappingMode="RelativeToBoundingBox"
StartPoint="1.051,-0.137">
<GradientStop Color="#FF18250A" Offset="1"/>
<GradientStop Color="#FF18250A"/>
<GradientStop Color="#FF345016" Offset="0.725"/>
<GradientStop Color="#FF345016" Offset="0.275"/>
<GradientStop Color="#FF779F4C" Offset="0.5"/>
</LinearGradientBrush>
</Path.Fill>
</Path>

<TextBlock x:Name="TextBlock1">
</TextBlock>
</Grid>
</DataTemplate>
The DataTemplate does expose the needed 'MouseEnter' event in the code behind but the problem is the StoryBoard is in the child 'Grid' control. Therefore we have (2) options: use the VisualTreeHelper class to find the right child control, or simple define a 'MouseEnter' event on the actual Grid control. I went for the latter option as it is the easiest.

Let's add the event we declared on the Grid in the XMAL named 'MyGrid_MouseEnter' to the code behind. We need to cast the sender which is the Grid itself, and then find the StoryBoard object within the Grid's resources. Once we have acquired and casted the exact StoryBoard, then we can call the .Begin() method.
Private Sub MyGrid_MouseEnter(sender As Object, e As System.Windows.Input.MouseEventArgs)
'Cast the sender to an object of type Grid, so we can find the StoryBoard
Dim MyTemplateGrid As Grid = DirectCast(sender, Grid)
If MyTemplateGrid IsNot Nothing Then
'Find the StoryBoard by name and then begin its animation sequence.
Dim StyBrd As Storyboard = TryCast(MyTemplateGrid.Resources("MyTemplateAnimate"), Storyboard)
StyBrd.Begin()
End If
End Sub
That's it, run the Silverlight app, and the StoryBoard within the DataTemplate will now run. If the controls in this example were not exactly what you have, the principal is you need to drill down to find the containing parent object of the StoryBoard to then get access to the storyboard. If you need, you can use the VisualTreeHelper to drill down to the proper child control. If you need a sample of using this class please refer to the following link:
http://forums.silverlight.net/t/99891.aspx

Wednesday, September 21, 2011

Exposing Multiple Binding Types For The Same Service Class In WCF

Have you ever wanted to expose multiple binding types in WCF for the same service class? Well I have but it is not directly apparent on how to accomplish this. My thought was, “I have a single service and I want it to be consumable by both net.tcp and http bindings. Not a big deal, right?” Well in the end the code needed to make this happen is not all that complex, but getting to the solution took some work as usual.

My thought process initially was to try and figure out how to make the WCF configuration allow this condition with a single service, but this method has some side effects. My 1st attempt was to create a single service with multiple endpoints and mex configurations, with each endpoint configuration having a different binding type (http and net.tcp). This actually works, but comes along with a side effect which I did not care for. The problem was when a client would consume my service (either via net.tcp or https) both endpoint configurations were added to the client. This isn't a huge deal, but I wanted the service configurations to deploy independently to prevent any confusion. Also if the client requests only the http binding endpoint, then that is all I want them to get; not the net.tcp configuration as well or vice versa.

Next I wanted to try using (2) different service configurations within the same single WCF service. However, a WCF service class can at most be exposed once in configuration by a single service configuration. If you try and configure (2) separate services differing only in endpoint binding configuration but attempt to consume the same service class for both services, you are going to get an error. "A child element named 'service' with same key already exists at the same configuration scope. Collection elements must be unique within the same configuration scope". Simply changing the 'name' property on the service configuration is not an option, because the 'name' property represents the class that implements the service contract. Arbitrarily changing the name will break the service.

The solution I came up with that solves all of these requirements is to have the single main service class that contains the implemented logic, Implement (2) additional new Interfaces that will allow distinction or uniqueness for the endpoint contract configuration. We will also add (2) new service contract classes that inherit the main service class and provide uniqueness for service class configuration. This masquerade allows making the services appear to be unique in consumption, but really point back to the same logic which was what was the original requirement.

As I mentioned before I do not want to expose multiple endpoints from a single service implementing a single contract due to the unwanted side effects, but rather have multiple services each with a single endpoint, implementing the same contract. To do this each service needs to be unique, but when attempting to make separate services each serve up the same service class implementing the contract, there is no uniqueness. The 'ServiceEndpointElement.Name Property' in configuration must point to a class within the service. Because we want (1) unique endpoint per service, we need a unique service class as well. The new classes Inherit from the primary Service class providing all the main service functionality, but yet provides a unique service class entry point for the ServiceEndpointElement.Name Property. Again, the reason we do not want a single service exposing multiple bindings, is because upon client consumption all (1...n) binding configurations for a single service are downloaded and configured even if the client only wanted say the 'net.tcp' binding. To reduce confusion, each service configured ultimately exposes the identical functionality but provides a separate service class value for the ServiceEndpointElement.Name Property.

Let's take a look at how to implement this solution. To begin, here are the (3) main service contracts:
<ServiceContract()>
Public Interface IMyWcfServiceTcp
Inherits IMyWcfService

End Interface

<ServiceContract()>
Public Interface IMyWcfServiceHttp
Inherits IMyWcfService

End Interface

<ServiceContract()>
Public Interface IMyWcfService

<OperationContract(Name:="MyMethod1")>
Sub MyMethod1()

<OperationContract(Name:="MyMethod2")>
Sub MyMethod2()

<OperationContract(Name:="MyMethod3")>
Sub MyMethod3()

End Interface
Next are the (3) classes which WCF configuration will use in the service configuration:
Public Class MyWcfServiceTcp
Inherits MyWcfService

End Class

Public Class MyWcfServiceHttp
Inherits MyWcfService

End Class

Public Class MyWcfService
Implements IMyWcfServiceTcp, IMyWcfServiceHttp

Public Sub MyMethod1() Implements IMyWcfService.MyMethod1
End Sub

Public Sub MyMethod2() Implements IMyWcfService.MyMethod2
End Sub

Public Sub MyMethod3() Implements IMyWcfService.MyMethod3
End Sub

End Class
And finally, here is the WCF service configuration:
<!--*****WCF Hosted Service Endpoints*****-->
<services>
<service behaviorConfiguration="MyWcfServiceTcpBehavior" name="MyWcfServiceTcp">
<endpoint address="" binding="netTcpBinding" bindingConfiguration="MyWcfServiceTcpEndpoint"
name="MyWcfServiceTcpEndpoint" bindingName="MyWcfServiceTcpEndpoint"
contract="IMyWcfServiceTcp" />
<endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="net.tcp://localhost:8000/MyServices/MyWcfService" />
</baseAddresses>
</host>
</service>
<service behaviorConfiguration="MyWcfServiceHttpBehavior" name="MyWcfServiceHttp">
<endpoint address="" binding="wsHttpBinding" bindingConfiguration="MyWcfServiceHttpEndpoint"
name="MyWcfServiceHttpEndpoint" bindingName="MyWcfServiceHttpEndpoint"
contract="IMyWcfServiceHttp" />
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:8001/MyServices/MyWcfService" />
</baseAddresses>
</host>
</service>
</services>
Notice how each service configuration points to its own class, and each endpoint points to its own individual contract. However we know under the covers, both services expose the identical functionality. The difference: choice of binding type, and ability to only get the single binding's configuration added to the client (not both types) upon consumption.

Take note - if having your client getting multiple binding configurations for requesting a single endpoint does not bother you then procedure is not needed. Just define a single service with multiple endpoint configurations and multiple mex endpoints and you are done. However, if exposing your service with multiple binding types and having the client only receive the single endpoints configuration is important, then this should help fulfill the requirement.