This is what the current implementation is doing:
In OnMouseWheel it calls the following method:
this.ZoomAboutViewportPoint(((double) e.Delta) / 100.0, e.GetPosition(this));
It's implementation is:
private void ZoomAboutViewportPoint(double zoomLevelIncrement, Point zoomTargetInViewport)
{
base.ZoomAndRotateOrigin = new Point?(zoomTargetInViewport);
base.ViewBeingSetByUserInput = true;
base.SetView((double) (base.TargetZoomLevel + zoomLevelIncrement), base.TargetHeading);
base.ViewBeingSetByUserInput = false;
}
Obviously you cant set base.ViewBeingSetByUserInput and base.ZoomAndRotateOrigin directly as they are internal.
You can however just use SetView accordingly with the viewport coordinates, but will still loose the nice animation part.
Alternatively you can set the aforementioned values via reflection, but that is a brittle hack and prone to break if the control changes.
--- UPDATE
As described above: If you hook up to the MouseWheel Event here is the code to make it work via the reflection call of the private method:
void BingMap_MouseWheel(object sender, MouseWheelEventArgs e)
{
e.Handled = true;
System.Reflection.MethodInfo dynMethod = this.BingMap.GetType().GetMethod("ZoomAboutViewportPoint", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
dynMethod.Invoke(this.BingMap, new object[] { (((double)e.Delta) / 400d), e.GetPosition(this.BingMap) });
}
This brings it down to a quarter of the speed and makes it usable with the least amount of code. But again this is a hack!