Transactions inside stored procedures
More a short rant today than anything else. If you are writing a DAL most of it can be generated and be completely boilerplate. Everything looks the same, acts the same, is called the same way.very beautiful.
There's always exceptions, however. Sometimes you just NEED to do something more complicated. Inserting into multiple tables at once, possibly across different databases.
The project I'm working on has a very consistent way of putting database operations in transactions. I've been troubleshooting a number of problems in the app where the app will crash after trying to save some records. The proc seemed to be working, it was returning a new id and everything was happy. Why couldn't the app find these records?
Because the stored procedures fall under the exceptions to the rule above and the developer of them thought it would be best to do transaction handling inside the stored procedure.
Two problems, one the transactions across the linked server didn't work because of configuration issues. Secondly, the stored proc did a try . catch . rollback without calling RAISERROR.
I certainly think that transactions inside the stored procedure can clean up some of the client code, and help in situations when the stored procedure can be called in many different places and always needs to be transactional. Just keep in mind that unless we let the calling client know something went wrong it's just as bad as swallowing exceptions in C# or VB. Fail fast and hard, as always.
Frame-based animation in WPF
I recently was working on the ubiquitous photo/slideshow app in WPF. This is something I've been tinkering with off and on for last 6 months. The original intention was to create a photo slideshow application for my upcoming wedding. Being the nerd, a static video slideshow just wasn't going to cut it.
Along the way I learned quite a bit about keeping performance up and memory usage low while working with tons of images. It's finally in a position where it's almost done and I wanted to add a few tweaks. The photos zoom in and randomly arrange like they were dropped on a table. Once there, they show one by one.
I wanted to add a little random "drift" while the image was showing to make it more interesting to the eye. I started originally by creating random storyboards and listening to the Storyboard.Completed event. When the event fired I created a new storyboard to animate my photo's Canvas.Left and Top properties. This worked, but there was an annoying lag between the stop and start of the animations.
I wanted to move to a frame-based animation rather than WPF's built-in time-based animation style. I could have used a timer to update my properties, but I wanted to work more within the constraints of WPF. I found articles for Silverlight that indicate an empty storyboard with no duration will fire it's completed event on the next frame, there you can update your properties and restart the storyboard to update your properties every frame. Although this may work in Silverlight, I could not get it to work in WPF. Though as I look back, I didn't try setting the Duration to "0:0:0". I wonder if that would work?
Regardless, the technique I ended up using was listening to CompositionTarget.Rendering event it code-behind. The event fires before your UI renders each frame, allowing you to hook in and do frame based animation.
For more information, you can go here:
WPF ListBox Virtualization
Virtualization in WPF is amazing when you get it, annoying when you lose it. I'm working on a form where the user can dynamically filter and sort a ListBox. I'm using a DataTemplate to give a nice card-like view to each object, which makes it take up a lot of space on the screen. To fix this I used the WrapPanel as the ListBox's ItemsPanel.
WrapPanel is not virtualized, I can't find one that is and don't have any time to write one myself. So I came up with a work around to give the user a fixed number of column view using the standard panel for a ListBox. This got me virtualization back. Then I wanted to smoothly scroll so I turned ScrollViewer.CanContentScroll to false. Smooth scrolling, no virtualization. Because this box may have thousands of records in it, performance is much more important than smooth scrolling.
The moral of the story is, if you're working on something in WPF and performance is important and you might have a large dataset coming in. Double check your changes to controls to make sure you're maintaining virtualization. If anybody has a good list of what disables virtualization (grouping, custom panels, smooth scrolling), I'd like to see it.
So long Linux, remember the good times…
Last night I was fighting with repairing my MythTV box, the final remaining linux PC in my house. My video card went down and trying to replacing it the nVidia that was in there with the ATI replacement I picked up turned out to be too frustrating. Steps I went through
- Backup/Restore of KnoppMyth
- #2 caused a bad xorg.conf to be used, and install crashed
- Un-tarred the backup, replaced bad xorg.conf with a failsafe xorg.conf, re-tarred
- Repeat #2
- Video card works, KnoppMyth installation crashes
- Powered through, MythTV up and running, can't talk to backend
- Reconfigure backend, can see recordings, can't watch them
- Networking doesn't work
- TV-Out doesn't work
- Give Up
- Try to pull recordings onto portable hard drive (NTFS formatted, ha, good try)
- Download Knoppix w/ NTFS write support
- Run LiveCD
- Copy files to portable hard drive
Remaining steps
- Wipe linux
- Install Windows
- Install GB-PVR
Before I started working at Magenic none of my computers booted into Windows by default. My laptop ran VectorLinux (based off Slackware) and my main PC ran Fedora, Ubuntu, etc based on what I wanted to try that week.
The MythTV box was running rock-solid for years, and I loved it. It was the last bastion of my free-spirited geekiness in my increasingly Microsoft focused world. Now, it has but hours left to live. Maybe I'll put Ubuntu on my laptop for old time's sake at some point. Who knows?
Speaking of, Windows 7 RC is out now to MSDN. THAT is going on my laptop immediately tonight. I think I've been fully assimilated. Even Winston eventually saw the light and learned to love Big Brother.
Hosting WPF in WinForms
I've done a lot of WPF and Silverlight, but always as standalone apps. In one project, we actually embedded Silverlight inside a WPF application using a browser control.
I've been firmly convinced that XAML is the way of the future for some time now. But recently I've gotten to see a very real, tangible benefit of hosting WPF inside a windows form application.
A lot of time businesses will want some fancy visualization or way to view their data. In Windows Forms if you want anything "cool" out of the box you've got one of these options: paying for a 3rd party set of controls, finding a half-baked control online at CodePlex or CodeProject, or writing it yourself.
Most of the time the project budget and plan don't include time or money for options 1 and 3. Option 2 is Russian roulette. Sometimes you get some really cool stuff, sometimes the control you find is garbage. In WPF, it becomes almost trivial to do the sort of complex control customization that was such a pain in WinForms. At the same time, most business probably don't want to start off by rewriting their existing app in WPF.
Using the ElementHost control and some custom WPF UserControls you can embed some very cool UI functionality with minimal effort and impact to your existing application. My WPF UserControls don't look like "WPF". At least not all the LOB demos you see where there are fancy transitions and gradients slapped in everywhere. But it's blowing away the end users. The integration is seamless, it looks like WinForms, but simply using some stylish DataTemplates and the WPF TreeView we've improved the customers user experience ten-fold. We're using it 3 critical places of the app where the user needed some better visualization of the data that was coming in. With WPF we could do that much faster and better with minimal impact to the rest of the application.
Code Generation with T4
I was first exposed to T4 in January/February of 2008 when I was ramping up for a project that used the Guidance Automation packages. Even though that fell through, it was still worthwhile for getting exposure to a cool little utility like this.
T4 stands for Text Template Transformation Tool and is a built-in feature for Visual Studio 2008 and as an add-on for 2005. It's an engine that can be used for generating code from any data source you want.
Add a template
In any project in VS, right click and Add -> New Item., select a text file and rename it so it has the extension .tt. This keys Visual Studio into the fact that it's dealing with a T4 file.
Now would also be a good time to install the Clarius add-on for T4. http://www.visualt4.com/
This tool gives you a bit more design time support than you normally get with T4 out of the box. Note to the faint of heart: Unless your willing to shell out for the not-free editions your about to step back in time to a place before Intellisense, AutoComplete, Syntax highlighting and other things we're all accustomed to.
The best way to think about T4 is back to web scripting languages like PHP, ASP, etc. You have your template, and you have blocks of code for control flow for logic. Let's take a look at a simple template
[code lang="xml"]
<#@ template language="C#" debug="true" hostspecific="true" #>
<#@ output extension="txt" #>
<#
for(int i=0; i < 10; i++)
{
#>
I'm a template on line <#= i #>
<#
}
#>
[/code]
Which tells us the control flow is done in C# and the output is a text file. When you save the file the template engine will run. You can also run the engine by right clicking and choosing "Run Custom Tool".
You can see our output is now nested under our item in Solution Explorer.
There are two tags to be aware of here <# #> and <#= #>, the first allows for control flow code to be inserted and the second one is for outputting values.
That's enough for a start, I'll be back in another post about going a little more in depth.
Nice Kindle 2 Case
I don't plan on product endorsements often on here, but thought I'd share this. Magenic gave all of us Kindle 2's for the holidays this year. I've been hunting for a case since I got mine and wasn't impressed with a lot of the stuff I was seeing on Amazon. The quality wasn't there or it was just too expensive.
I was in Staples today and spotted this: http://www.amazon.com/exec/obidos/ASIN/B0007VPG6U/growinglifestyle/ref=nosim It's a Swiss zip folio that has a perfect area for a kindle and a couple other pockets. Only $30 too.
Repeating Tablix Headers In SSRS 2008
So I've been trying to figure out haw to repeat headers in a Tablix. I don't do a lot of SSRS stuff and the report I've got is moderately complex, it does a bit of an involved grouping situation with a few sub reports for details and then a Tablix to repeat individuals under each details section.
The Tablix has Repeat Column/Row Headers properties in the property pane but they are useless. During my searches I saw something about these properties being for when the report is too wide, not too long.
Anyways, at the bottom of your report designer there should be the grouping info pane. Click on the black arrow in the upper-right corner of the pane to enable "Advance Mode" Doing this shows static group items in your grouping pane for things like header rows. Find the static item that corresponds to your header row and check the property pane. There will be a "RepeatOnNewPage" property, set it to true and headers should repeat, at least they did for me.
Hint: If you can't figure out which static grouping could be your row header, watch the report designer as you click on the different groups, it will highlight the one you just selected in the designer.
Blog Refresh
So this used to be my personal blog. After a while that moved so my fiancee and I could blog together, this site has been languishing for quite a while. I've kept meaning to repurpose it as a tech blog, and now I finally got around to it.
I've upgraded to WordPress 2.7 and am working on getting this mirrored at Magenic's blog server. The first thing I'll probably be talking about is my trials in writing IM functionality into a kiosk using the UCC SDK.
Writing an IM client for Office Communications Server
So I've been working on adding in IM functionality for the kiosk software I wrote and maintain at Magenic. At first I planned on using the Office Communicator Automation API. It all worked in my proof of concept, except for one thing.
I couldn't figure out how to determine when I was receiving messages. I could start conversations, detect when they'd been started with me, but not when I actually got a message.
Not too mention it felt kinda dirty because you're really just automating the Office Communicator App, so you have windows popping up all over the place. In my case they would have been all behind the kiosk app so I wasn't too concerned, but it still felt unclean.
My research led me to the Unified Communications Client API, which sounds like it's what I wanted from the start.
Moral of the story, if you want to do more then simple presence and conversation initiation in your application, use the UCC API.
About the UCC API:
http://msdn.microsoft.com/en-us/library/bb878684.aspx