Saturday, January 12, 2008

A REAL update to the Bag-o-Tricks

The last update to the bag-o-tricks was pretty lame, I'll admit.

As I discussed a bit ago, a lot of people code to "get it done yesterday". It's clear, looking through a bunch of the code, that I had this mentality about a lot of the samples. Moreover, it's clear that the masters of code quality, maintainability, and best-practices were often ignored.

Here's an attempt to put my money where my mouth is.

The Goods

Binaries and Source [zip, 4.3MB]. Developed with Visual C# Express 2008.

The Details

  • Set - New!
    • The XBap I posted last week is now part of the bag-o-tricks.
    • Did some clever project linking to allow building XBap without duplicating files.
  • Interactive 3D - New!
    • Added the 3D demos I discussed a while ago
    • A lot of clean-up to make the code more suitable for general use
  • AnimatingTilePanel
    • Ability to animate in newly added items
    • Made dampening make sense: bigger number = more dampening
    • Add Variation property to make item movement make more organic, if desired
    • Added validation to the public properties
    • Moved frame tick register/de-register to new CompositionTargetRenderingListener
    • Perf: Stopped ‘ticking’ when nothing is changing
    • Stopped using clock time between ticks to affect animation: complexity with little benefit
    • Made ItemHeight/Width attached properties that can be added to a host ItemsControl.
    • Demo: moved to DemoCollection -> now you can see how changes to the source collection are reflected
  • Graph
    • Removed a completely silly use a Dictionary. Clever perf optimization that made the code bloated, confusing, and probably slower.
    • Renamed CoefficientOfDampening -> Dampening
    • Rename FrameRate -> Attraction
    • Removed unneeded HideAnimationManager -> thank you anonymous methods.
    • Demo: A bunch of clean-up in the Node data files. Should never have used DispaterObject.
    • Demo: Moved to dispatcher timer for churning the graph nodes: a lot cleaner and more efficient than a separate Thread.
  • Zap
    • Removed shameful implementation of IPropertyChanged on top of a DependencyObject
    • Eliminated gratuitous subclassing of DependencyObject by ZapCommandItem
    • Removed FirstPreviousNextLastCommand (and associated enum) -> thank you ActionICommand
    • Fixed some pretty glaring bugs in not-so-edge cases
    • Demo: moved to DemoCollection
  • ActionICommand - New!
    • Commands often expose the functionality of existing methods. So why can’t exposing a command be as simple as wrapping the existing method? Exactly.
  • WrapperElement - New!
    • A while ago, I discussed not subclassing Panel unless you’re making a Panel. Well, sometimes all you want to do is compose a single element without exposing it's state to the world. WrapperElement makes the process of wrapping a child element trivial.
  • CompositionTargetRenderingListener - New!
    • A class that can be used to manage listening to the static CompositionTarget.Rendering event. I use this pattern so much, it made sense to make a separate class.
  • Demo: DemoCollection - New!
    • Writing controls that handle INotifyCollectionChange can be tough. Wouldn’t it be nice to have a class that makes testing (and then showing off) your list-bound control easy? I thought so.
  • General
    • Removed a lot of unused parameters and privates. Thanks, FxCop.
    • Demo: Moved the introduction page to FlowDocument. Why I didn’t do this a year ago, I’ll never know.

As always, the SVN location has been updated. Patches are always welcome (No one has taken me up on this yet. Would love to try it out.)

Enjoy and happy hacking!

6 comments:

ligAZ said...

I was just going to comment that the source did not build and you commit the minor fix. Great. Thanks for the updates.

Atul said...

Kevin, I have been refering to the bag of tricks a lot and needless to say it is very helpful. I wanted to use the zap scroller to host a couple of user controls. That is fine, but the default is to show buttons numbered as 1,2,3 etc for navigation. I wanted to change that to custom Text to identify which user control it is. I have been trying to get this going, but not successful. Can you give some pointers on how to achieve this?

PKS said...

The update to the Bag-O Tricks is great. I have experienced the pain that many other developers have experienced in that there is no DateTimePicker control in WPF. So your control goes a long way to bridge that gap. However, there is no way to edit the time and therefore it is really only a time picker control. Also, it would be nice to see a Vista like DateTimePicker control. At this point I suppose I would have to write it myself if I am going to get it.

Thomas Matelich said...

Just getting into WPF, first trick from the bag I was going to use is Reveal. I'm curious if you recommend people copy your code into their source base or just reference the bag.

Stf said...

Congratulations for your blog and your Bag-o-tricks !!

I'm testing some of your controls, there are great !

So i have a problem with transition presenter who is a part of a custom control. I leave a comment here because blogger doesn't accept "code" :
http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=2929349&SiteID=1

Thanks by advance

sprdave said...

If I set the value of monthCalendar.SelectedDate, and I set his MaxSelectionCount to 1 then other dates can't be selected.

to reproduce:

1. add a x:Class called DateControlsPage to DateControlsPage.xaml

2. make the partial class file for DateControlsPage.

2. paste this constructor in the class file:
public DateControlsPage()
{
InitializeComponent();
this.monthCalendar.MaxSelectionCount = 1;
this.monthCalendar.SelectedDate = DateTime.Now;
}
3. Fire it up and click on days in monthCalendar.