Pages

-->

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.

Friday, September 16, 2011

My Initial Thoughts on Windows 8 And The Build Windows Conference

If you are a developer of any type and have interest in any type of Windows based development then you probably knew the 'Build Windows' event was taking place in Anaheim, CA this past week from Sep.13-16. I was not in attendance, but like hundreds of thousands of other developers I tapped into the site which almost with perfection streamed the keynotes and Channel 9 video via a Silverlight player. Wait! Silverlight and not a HTML5 video player!! I thought SL was dead to Microsoft (says the peanut gallery and technical blogs). Nope, and it was a nice touch to show how Silverlight works so well.

I have not had a chance to watch all of the archived video, but I had it playing in the background often this past week to try and pick up a tid bit here and there. It is obvious to me that Windows 8 is the 1st revolutionary mind bender that we have to a user’s interaction, application development, and from a OS perspective in quite some time. Phrases and words like 'Metro Apps', 'Fast and Fluid', 'Touch First', and 'WinRT' were used time and time again. Windows 8 takes a 'Touch First' approach and is no surprise to me at all. With the onslaught of tablet and touch technology we have seen in the last 4-5 years and especially from front runner Apple with the iPad, iPhone, and iTouch products, it is apparent to me that Microsoft is firing back on the offensive to get in and hopefully dominate the market share in this new technology age.

Think about it - the way the Build conference and mainstream technology presents technology today, you would feel that the mouse, keyboard, desktop and laptop PC might be dead! Not necessarily, but the days of the classic 'Start' button OS, static desktop, mouse and keyboard environment may be numbered. We have the mobile and tablet world to thank for this (in a good way I think).

Windows 8 appears to have taken a lot of the good features from Windows Phone 7 and incorporated them into the OS. If you have seen or used a Windows Phone 7 device, then you will be comfortable with viewing Windows 8. This style of application development deemed 'Metro Apps' are the applications that run on the forefront of Windows 8. This appears to be Microsoft's approach to help make any type of developer have the potential to be marketable by selling apps in the ‘Windows Marketplace’. I heard numerous times from presenters about how Microsoft wants the developer to make money and come up with the new 'Angry Birds'. They are pushing us to be Windows Developers of Metro style apps on Windows 8 probably for a few reasons: they hope we will get excited about coming up with an app to sell and make money, and in the meantime we have the hook in deep to Microsoft technologies. I don't really have any issue with this at all. Microsoft is a business and they are positioning themselves to be profitable and current or even better 'leading' the industry and right now touch, tablets, smart phones, mobile, and cloud development and applications reign supreme. The only thing I am thinking about is don't forget the professional developer doing Enterprise Development.

Don't get me wrong, Metro apps look cool and will probably be a great success. Metro apps were mentioned to not be a 'one-size-fits-all' solution, but yet still seemed to be touted as the future of application development on Windows. Mainstream large applications seemed to be mentioned or represented as a footnote to Metro apps. Well I have to say not everything reasonable in software development can be crammed into a social networking twitter app, a silly (but clever) Angry Birds game, or a grocery shopping list app-let. Some presentations nowadays makes it seem like the only apps used are Twitter, Facebook, Email, and the Internet and everything else is a second class citizen. I may have to modify this post in a few years, but I don't think automating complex business rules can be simplified into the touch of a finger and a Metro style app. I know Microsoft knows this, and so did all of the other developers that were in attendance. However I want to make sure that Microsoft continues to push hard as they have been in the last 10 years with technologies in .NET to create solutions for large Enterprise applications that solve complex business solutions. A Facebook and Twitter stream combo Metro app and a cloud syncing picture app are not going to drive the business. But they will excite 16 year old kids that will buy a Windows 8 tablet and buy lots of little stuff like this from the Marketplace. Microsoft is smart for recognizing this and positioning themselves to make money. They guys like me that develop in .NET for a living off a license purchased every few years is probably only enough $ to keep the lights on in Redmond. Therefore I say I understand everything Microsoft is doing and the direction they are going, I just hope they continue to be just as strong with .NET moving forward as they have been in the past.

There were some strong .NET presentations given on Channel 9 and by people like Scott Guthrie which got me really excited about moving forward. These are the pioneers of the .NET Framework and continue to move it forward at Microsoft. I look forward to the Async Framework in .NET 4.5 and they also mentioned some language specific enhancements like VB.NET getting Iterators like C# has had since .NET 3.5. I don't want the flavor of this post to make it sound like Microsoft is trying to box us into being Windows developers only making Metro apps, but it was hard not to think like this at times based on the content I watched. The Channel 9 content kept me breathing easy and feeling like the 10 million of us that are profession developers out of 100 million estimated developers worldwide (Steve Ballmer's numbers) still have a strong presence in Microsoft. However I do not blame Microsoft trying to cater and market stronger to the 90 million non-professional developers that will be making Metro style apps trying to come up with the next dynamic weather app or Angry Birds game. It is the smart thing to do from a business perspective as opposed to standing up on stage going on and on about the Async framework or other .NET enhancement that is catering to the 10 million professional developers.

To sum up the conference from my viewpoint (and again, I was not there so I didn't get the full content), I am excited for Visual Studio 11, .NET Framework 4.5, Windows 8, and touch first technology. Although I still get the feeling that everything they said at the conference makes sense, but it does not make sense for everybody. Grasp that? Regardless I look forward to Windows 8 and the future.

For developers interested in the new WinRT APIs in Windows 8, have a look at the following article which describes it best I have seen thus far:

WinRT demystified

Wednesday, September 14, 2011

Finding Duplicate Rows Using TSQL

Ok so here is a tired old post that has been blogged about since the internet’s inception, right? Well sort of... I am not going to yammer on here too much about a topic that is covered exhaustively on technical blogs like mine, nor do I claim to be a 'SQL Guru' of any sorts, but I noticed a lot of the sites offering help on this topic always did so for a very basic and simple example. Well I too am going to use a simple example but expand on its usefulness to hopefully help out a few wondering the search engines in need of help. Your typical 'find duplicate rows in a table by ID' example is shown below:

SELECT ID
FROM Books
GROUP BY ID
HAVING COUNT(ID) > 1
Another example using a varchar column:

SELECT Title
FROM Books
GROUP BY Title
HAVING COUNT(Title) > 1
Ok the above is great for small tables, to manually track down records, or maybe as part of a larger query or subquery. However odds are you are going to need additional columns of data and probably the actual duplicate rows themselves. Well initial thought might be to expand the simple example query above to include the additional fields, but you will quickly find out that the query will yield no results. This is because the query above groups on the columns in question having a count greater than 1. Well if you add additional columns to the query that do not contain duplicates, then this condition is no longer 'True' and thus no results are returned.

The fix is to Join in another copy of the same table. One table's purpose is to focus on the duplicate rows, and the second table's purpose is to focus on the additional columns needed in the results. When joining on the same table an Alias must be given to distinguish between the two. Here is the expanded example from above, that will return all of the *actual* duplicate rows, and any additional information that was sought:

SELECT bAll.ID, bAll.PublishDate, bAll.Title, bAll.Price
FROM Books bAll
INNER JOIN (SELECT Title
FROM Books
GROUP BY Title
HAVING COUNT(Title) > 1) bDups
ON bAll.Title = bDups.Title
ORDER BY bAll.Title
Lastly, here is a template of the above query that you might want to keep handy as sort of a 'fill-in-the-blanks' template (remove brackets - they are just placeholders and not required syntax) for your own 'finding duplicate rows' needs:

SELECT [AliasAllTable].[Field1], [AliasAllTable].[Field2], [AliasAllTable].[Field3]
FROM [MainTable] [AliasMainTable]
INNER JOIN (SELECT [DuplicateFieldName]
FROM [MainTable]
GROUP BY [DuplicateFieldName]
HAVING COUNT([DuplicateFieldName]) > 1) [AliasDuplicateTable]
ON [AliasAllTable].[DuplicateFieldName] = [AliasDuplicateTable].[DuplicateFieldName]
ORDER BY [AliasAllTable].[DuplicateFieldName]
I welcome any SQL experts to comment on streamlined ways to accomplish the identical task; I can certainly update the post with additional information. However with the plethora of examples available, too many seemed to be of the basic flavor example and I wanted to introduce the additional functionality that is probably often sought after.

Sunday, September 11, 2011

9/11 - 10 Years Later

Traditionally I do not write about anything on my blog outside the realm of programming, but the 10th Anniversary of the tragedy that occurred on September 11th, 2001 is certainly worth mentioning and reflecting upon.

To most of us concerned with reading this blog, we are of an age where we probably remember exactly what we were doing and where we were 10 years ago today. At the time I was living in Charlotte, NC where I was in my last semester at U.N.C. Charlotte and preparing for a large job fair on campus. It was also exactly 1 month after my wedding which was celebrated in Puerto Rico with my wife's and my family on August 11, 2001, and also in which we also just celebrated our 10 year wedding Anniversary last month. It was a new and transitioning period in my life. At the time I was vying for my 1st job and it was right after the ".com bust" and programming jobs were few and far between. We had companies like Alltel come to campus and have 200 people show up to a brief announcement, for only 2 open positions. I was dressed to the nines and headed to Kinkos to make copies of my resume for the job fair. My wife called me and with a bit of confusion told me, "Some hotels in New York City had been blown up...", but I wasn't really sure what she was talking about. When I arrived at Kinkos I knew something even bigger was occurring when I read a sign on the door that said: "We are closing at noon due to the recent events." I went back to my apartment and turned on the TV as was everyone else. The rest is a sad part in our nations history.

I read the tributes made in our local paper today and it was shocking and eye-opening to once again see the names of all of the people that lost their lives on 9/11. It was a bit jaw dropping when looking at what was about a 5 point font used to fit all of the names in on roughly 3 pages. I remember it was about 3,000 people, but seeing it in print was a reminder of what happened on that tragic day. Of course this does not include all of the men and women of our military who have made the ultimate sacrifice since in the wars abroad.

Once such individual that continues to serve and is in Afghanistan as of this writing is my brother-in-law Captain Brain Huysman who is the Company Commander of Weapons Company: 1st Battalion, 5th Marines (http://www.i-mef.usmc.mil/external/1stmardiv/5thmarregt/1-5/subunits/subunits.jsp). On this day and every day I salute you Brian and all that serve in our military that continue to protect our nation. Thank you.

So on this 10th Anniversary, I reflect on something that changed our nation forever and I too will "Never Forget."

Tuesday, September 6, 2011

September MSDN Webcast Training For Newbie ASP.NET Developers

If you are just getting into .NET and specifically ASP.NET, then the following (2) MSDN Webcasts would be worth attending. They are free, so search and check the site often for other topics that interest you as well. The (2) below are level 200 webcasts that are geared for new ASP.NET developers.

MSDN Webcast: ASP.NET 4.0 Soup to Nuts (Part 1): Introduction to ASP.NET (Level 200)

MSDN Webcast: ASP.NET 4.0 Soup to Nuts (Part 2): Website Basics (Level 200)