As stated here:
Silverlight stores all numeric values internally as single-precision values. This means that if a property value is set to a higher precision value, such as a double, the property value that is later retrieved may not be the same, due to truncation or rounding.
In most cases this is probably fine. For dimensions though, this is a pain point.
Why? I ran into this problem when I created a scrolling container with a long content div:
<div style="overflow: scroll; height: 400px;">
<div style="height: 40000px;">
...
</div>
</div>
Seems pretty simple right?
What I did was naively handle the scroll event on the outer div and position an element at the top of the visible portion of the inner div. This works fine for ScrollTop values of 0 through 32K. Where it falls over is when the ScrollTop overflows the Single at 32K + 1, at which point, the value returned by Silverlight becomes -32K.
Took me a few days to track down the documentation noted above, so at first I assumed this was a bug. Apparently not, we'll just have to use a workaround.
The simple workaround is to have JS copy the value to an attribute and read that from the Silverlight control:
onscroll="this.setAttribute('scrollTop', this.scrollTop)"
Note: Looks like the above code to set the scrollTop attribute isn't necessary. Apparently Silverlight will give you the string representation of the scrollTop property when you request the scrollTop attribute.
then instead of:
int scrollTop = scroller.GetProperty<int>("scrollTop");
we use:
int scrollTop = Convert.ToInt32(scroller.GetAttribute("scrollTop"));
Pretty clean and shouldn't be too much overhead.
I also tried exposing the property as [Scriptable] and registering the control for scripting:
WebApplication.Current.RegisterScriptableObject("myControl", this);
Which allows the event handler to instead look like:
onscroll="document.getElementById('SilverlightControl').Content.myControl.ScrollTop = this.scrollTop;"
Unfortunately, this suffers the same limitations as accessing the DOM property the other way.
Rant: One of the reasons this really pisses me off is that, as you can see above, the call to GetProperty<> must take an int type parameter. Why, internally, is the value being cast to an Int32 if it is limited to Int16? I realize this is only Alpha stuff here but come on.