DCSIMG
Use the source, Luke...
301 Moved Permanently

Hi,

For the time being, I'm consolidating all my blogging activities here: http://blog.yanivkessler.com.

My initial plan was to maintain two blogs, however, I discovered I don't like it :)

I'm leaving this content available since I see that some of it is well traveled... and who knows, if this piece of cyberspace property will be left under my care, perhaps one day I'll get back to writing here.


Yaniv Kessler

The story of .Net 3.5 sp1 and the Evil Dispatcher.BeginInvoke()

Recently Microsoft released a service pack (sp1) for .net 3.5 and another for .net 3.0 (sp2).

The above update caused a very nasty problem which I’ve initially attributed to a lapse in attention on my part, but later, when sifting through the web I learned that many people ran into the same issue.

Basically after upgrading your .net platform from 3.5 to 3.5sp1 or from 3.0 sp1 to 3.0 sp2, Among other things, Dispatcher.BeginInvoke() received another two new overloads:

Until now we had (Supported in: 3.5, 3.0):

Dispatcher.BeginInvoke(DispatcherPriority, Delegate);

Dispatcher.BeginInvoke(DispatcherPriority, Delegate, Object);

Dispatcher.BeginInvoke(DispatcherPriority, Delegate, Object, Object[]);

New overloads (Supported in: 3.5 SP1, 3.0 SP2):

Dispatcher.BeginInvoke(Delegate, Object[]);

Dispatcher.BeginInvoke(Delegate, DisptacherPriority, Object[]);

The last two new overloads, will cause an out of date .net platform to throw a MissingMethodException! (and will not compile).

If that was all there is to it, I wouldn’t have bothered with this post, however, that wasn’t the whole deal. It turns out, that intellisense in Visual Studio stopped suggesting the older methods and only the new ones. Since the new overloads signature bears a striking resemblance to the older ones, it is easy to see how someone might overlook this small change…

Now why do I call this evil ?

Assuming you are working on a Visual Studio project with .Net 3.5 / 3.0 compatibility, by using these methods you just broke it, at least until everyone will upgrade their 3.5 / 3.0 to the respective service packs. There are no compiler warnings / errors and you  might even miss this entirely until you get a MissingMethodException on another computer during runtime! This, in my small world, qualifies as evil :)

The solution of course is to use the older methods, even though they no longer appear in the intellisense suggestions list.

I was looking for a clue as to why these new overloads were introduces, but couldn’t find anything (if someone finds something please say so). Some of the old overloads like Disptacher.BeginInvoke(DispatcherPriority, Deleget, Object, Object[]), seem abit weird, so maybe that is the reason why the new ones were introduces…

Now I have to wonder, what was passing on in the mind of the person who introduced these overloads? is this one of those miraculous bugs or is it just a quiet way to force the usage of the new overloads ?

In any case, its horrible and it cost me quite some time to figure it out. So I hope this post would save you some.

Listening to visual state changes in a custom control

Quite simple, here is the skeleton custom control code:

using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;

namespace PointNShoot
{
    public partial class FlyingThing : UserControl
    {
        public FlyingThing()
        {            
            // Required to initialize variables
            InitializeComponent();
            VisualStateGroup flyingStateGroup = (VisualStateGroup) VisualStateManager.GetVisualStateGroups(LayoutRoot)[0];
            flyingStateGroup.CurrentStateChanged += new EventHandler<VisualStateChangedEventArgs>(flyingStateGroup_CurrentStateChanged);
            flyingStateGroup.CurrentStateChanging += new EventHandler<VisualStateChangedEventArgs>(flyingStateGroup_CurrentStateChanging);
        }

        void flyingStateGroup_CurrentStateChanging(object sender, VisualStateChangedEventArgs e)
        {
            //executes when a control begins transitioning into a different state
        }

        void flyingStateGroup_CurrentStateChanged(object sender, VisualStateChangedEventArgs e)
        {
            //executes after a control transitions into a different state
        }
    }
}
XAML Snippet:
<Grid x:Name="LayoutRoot">
	<vsm:VisualStateManager.VisualStateGroups>
		<vsm:VisualStateGroup x:Name="Flying">
		</vsm:VisualStateGroup>
	</vsm:VisualStateManager.VisualStateGroups>
</Grid>

The VisualStateGroup called Flying contains the states we are interested in. Trying to attach handlers in the constructor directly to Flying will yield a NullReferenceException. Instead a reference to it must be obtained using the VisualStateManager static method GetVisualStateGroups(FrameworkElement obj).

C# const vs. static readonly modifier

Shai and myself were discussing about adding a constant cookie name to a class in an application we are working on together, when the question of what precisely is the difference between a const and static readonly modifier came up. It was decided I will check it out and post the results of this small research assignment, so here it is.

Definitions (from msdn)

static

“Use the static modifier to declare a static member, which belongs to the type itself rather than to a specific object.”

“A constant or type declaration is implicitly a static member.”

readonly

“The readonly keyword is a modifier that you can use on fields. When a field declaration includes a readonly modifier, assignments to the fields introduced by the declaration can only occur as part of the declaration or in a constructor in the same class.”

const

“The const keyword is used to modify a declaration of a field or local variable. It specifies that the value of the field or the local variable is constant, which means it cannot be modified.”

“The readonly keyword is different from the const keyword. A const field can only be initialized at the declaration of the field. A readonly field can be initialized either at the declaration or in a constructor. Therefore, readonly fields can have different values depending on the constructor used. Also, while a const field is a compile-time constant, the readonly field can be used for run-time constants, as in this line: public static readonly uint l1 = (uint)DateTime.Now.Ticks;”

Enjoy :)

Edit: As Kim thoughtfully reminded me in his comment, It is very important to remember that constant primitive data types are substituted with their values throughout the code by the compiler.

Dependant external code must be recompiled each time you change a const in your program or it can easily break. Finding such bugs could potentially take a very long while, so be very careful when changing constants in your code and document such changes clearly in any release notes.

See this Q&A for a more detailed discussion with MSIL examples of the code generated by the compiler.

Swishing text…

This post is a warm up after a long absence. I needed to quickly create a “Coming soon” page for my new company website and didn’t want it to be something static, so I’ve create a nice text animation that “swishes” into your screen.

This post isn’t entirely for beginners, you do need to have basic knowlege in C#, Silverlight and Microsoft expression blend. You can download the project file without the animation here, or the final one here.

We’ll start with a nice dark scene I made in Microsoft expression blend, it has a gradient to create depth and our text and a nice “floor” reflection:

Swish1

And here is how our elements tree looks like:

swish2

You will notice that instead the our top container we have a Rectangle called Floor, and we packed our text (TheText) and its reflection (Reflection) inside a Grid.

Before we start animating I’m going to do two things:

1. Change the skew on the X axis of TheText and of Reflection to 30 and –30 respectively:

swish4

2. Move the text outside the visible area of the User Control.

swish3

Animation

Basically our text is going to travel all the way into the middle of the control where it will “slam” into an invisible wall and shake as a result of the impact. The text tilt (or skew) helps in maintaining the illusion that the text is being forcibly pushed into the screen by a force exerted on its lower parts.

The first order of business is to move the text container towards the center of the scene, and the movement most appear fast (swishy), I’ve allotted 0.5 seconds for this movement and translated the text 290 pixels (or, device-independent units that are approximately 1/96 inch) to the right.

Now I need to animated the “slam” and the post “slam” vibrations, I’ve achieved this by animating the text position back and forth slightly and also skewing it back and forth.

One important note: the keyframe at time index 0:00.500 contains 3 property changes, one for the translation of the grid into the visible area of the control, and 2 more for a change in the text and reflection’s skew property. You’ll notice that in that keyframe I’ve completely flipped the skew, turning the text skew to –30 and the reflection to 30 (the reflection will always be opposite to the text, since its, well, a reflection ;) ). This helps make the “slam” effect more real.

I also need to modify the way the skew property is changed over time, we call this Keyframe interpolation. By default our interpolation will be a Linear interpolation which changes the property value in equal increments between keyframes 0:00.000 and 0:00.500. This is not a good behavior for us, instead I’ll modify by checking the Hold In option from the popup menu; Hold In (I think, formerly known as hold out) will not interpolate changes over time; instead, it makes an abrupt change to the new property value when the playhead (or simply, the animation) reaches the keyframe where the change occurs.

So now we have our “slam” and we need to tend to the vibrations. I’ve allotted 0.6 seconds for the post impact/slam vibrations, Within this time frame we’re gonna shake that text pretty good.

There are 6 keyframes between keyframe 0:00.500 and 0:01.100, in each of those I’ve moved (translated) the text container (grid containing the text and the reflection) between 280 to 290 pixels, like this:

Keyframe  Value
0:00.600 283
0:00.700 290
0:00.800 286
0:00.900 290
0:01.000 289
0:01.100 290

Blend will adjust your values slightly (e.g 290 may turn into 289.945) and that is perfectly alright. If we wouldn’t have skewed the test, this animation alone would have provided a nice impact/slam effect, however with the skew it looks even better (IMHO of course). This is how I animated the skew over our allotted slam time frame:

TheText Reflection
Keyframe  Value
0:00.600 20
0:00.700 -20
0:00.800 10
0:00.900 -10
0:01.000 5
0:01.100 0
Keyframe  Value
0:00.600 -20
0:00.700 20
0:00.800 -10
0:00.900 10
0:01.000 -5
0:01.100 0

Here is another look at the elements tree and the storyboard timeline:

swish7

Now we’re left with one thing to do, we need to start the animation when the control is loaded and visible:

public partial class Page : UserControl
{
    public Page()
    {			
        InitializeComponent();
        this.Loaded += new RoutedEventHandler(Page_Loaded);            
    }

    void Page_Loaded(object sender, RoutedEventArgs e)
    {
        Swish.Begin();
    }
}

That’s it, we’re done. Here is the end result:

HOWTO: Use regsvr32.exe with WIX

Update for this post: I haven't checked it out yet, but from what I gather, with WIX 3.0 new heat tool, the bug (see related links below) that forced us to come up with this solution will be gone :) Also, please take note, that the solution described is not the standard way for registering a Com Server in an MSI installation.

Last night I had to deal with this issue, in one of the projects I’m involved in. So, after sifting through some forums, msdn and wix schema reference here is the end result. Its a fairly simple thing… in retrospect! :)

Adding the custom actions:

        <CustomAction Id="RegisterAdx"
                      Directory="INSTALLDIR"
                      ExeCommand='regsvr32.exe /s "[INSTALLDIR]adxloader.dll"'
                      Return="check">
        </CustomAction>
        <CustomAction Id="UnregisterAdx"
                      Directory="INSTALLDIR"
                      ExeCommand='regsvr32.exe /s /u "[INSTALLDIR]adxloader.dll"'>
        </CustomAction>

For those of you who don’t recognize this dll, its a required library by Add-in Express, we are using it to ease our development of GhotIt plug-in(s) for Microsoft Office applications.

So, we have two simple custom actions, the first, silently registers the dll from the installation directory and the second (silently), unregister it. The first action (RegisterAdx) is also set to fail the installation if not successful, by adding the Return=”check” attribute.

Please note that in both actions the ExeCommand attribute value is decorated with an Apostrophe (‘) instead of a Quotation Mark (“). This allows us to easily decorate the file statement [INSTALLDIR]adxloader.dll inside the value’s string with quotation marks, since the install directory might include whitespaces in it.

Next, we have to tell the MSI Installer when to execute these actions, Ideally this will happen after the installation finishes copying the files and before the files are deleted during the uninstall process.

Defining the execution “sequence”:

        <InstallExecuteSequence>
            <Custom Action="RegisterAdx" After="InstallFinalize">NOT Installed</Custom>
            <Custom Action="UnregisterAdx" Before="InstallInitialize">Installed</Custom>
        </InstallExecuteSequence>

First, although these actions are defined in a “sequence”, there is no real sequence here. Action RegisterAdx will only execute after the installation is finalized and only if the product isn’t installed (NOT Installed) while action UnregisterAdx will only execute before the installation is initialized and only if the product is already installed (Installed).

Epilogue:

In my installation project, these XML elements were placed directly under the <Product> element, but different scenarios might require them to be placed elsewhere.

This is a very simple solution to a simple problem, and as such it makes a few assumptions I should point out:

  1. The target computer has the regsvr32.exe on it.
  2. Regsvr32.exe is included in the computer’s environment path (this one is not so naive… if its there its probably in the path)
  3. There is no previous installation present. (or the previous installation will not be recognized, causing the NOT Installed condition to fail)

Related links:

Welcome

My name is Yaniv Kessler and I’m a software developer and entrepreneur, My favorite programming languages are Java and C#.

I’ve opened this blog to share some the knowledge I’ve gained throughout my endeavors in the startup/programming world and I hope some of you will find this knowledge useful in some manner.

Also, I would like to thank Shai Raiten (http://blogs.microsoft.co.il/blogs/shair) for introducing me to this blog community.