Common Pitfalls in Silverlight Development
Silverlight applications that render correctly in Expression Blend's designer frequently misbehave the moment they run inside a real browser plug-in host. The three recurring failure classes are broken data bindings that fail silently, UI updates attempted from the wrong thread, and storage or packaging limits that are only discovered in production. Learning to recognize these patterns early turns a multi-hour debugging session into a five-minute fix.
Cricket analogy: A batsman who looks perfect in the nets against throwdowns can still nick behind against genuine pace in a Test match, just as a Silverlight UI that looks fine in the designer can fail under real runtime conditions like an actual browser host.
XAML and Data Binding Pitfalls
The single most common Silverlight bug is a binding that updates the model but never updates the UI, or vice versa. This almost always traces back to a view-model property that does not raise INotifyPropertyChanged, or a Binding whose Mode is left at its default (OneWay for most properties) when TwoWay was actually required for a TextBox or Slider. Because Silverlight's binding engine fails silently by default, these mistakes produce no exception at all — only a control that stubbornly displays stale data.
Cricket analogy: A scoreboard operator who forgets to update the total after a boundary leaves fans staring at a wrong score, just as a view-model that skips PropertyChanged leaves the TextBox showing stale data after the underlying value changes.
A second binding pitfall involves resource lookup: Silverlight only supports StaticResource, which is resolved once when the XAML is parsed, not DynamicResource as in WPF. Developers coming from WPF often assume they can swap a resource dictionary at runtime and have bound elements pick up the new value automatically — in Silverlight this requires manually reapplying styles or rebuilding the visual tree, because the resource reference was already resolved and baked in at load time.
Cricket analogy: A team sheet submitted before the toss cannot be silently swapped mid-innings even if conditions change, similar to how a StaticResource is locked in at XAML parse time and will not update if the resource dictionary changes later.
Threading Pitfalls
Silverlight enforces strict UI thread affinity: any attempt to touch a UI element from a background thread — for example, inside a callback from WebClient.DownloadStringCompleted running on a worker thread, or from a manually spawned Thread or ThreadPool task — throws an UnauthorizedAccessException. The fix is to marshal the update back to the UI thread using the element's Dispatcher, typically via Dispatcher.BeginInvoke, which queues the delegate to run safely on the thread that owns the visual tree.
Cricket analogy: Only the on-field umpire can signal a boundary; a spectator shouting from the stands has no authority to change the scoreboard, just as only the UI thread can touch controls, forcing a worker thread to marshal its update through the Dispatcher.
private void client_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
{
// This callback runs on a background thread.
if (e.Error == null)
{
string result = e.Result;
// Touching StatusText directly here throws UnauthorizedAccessException.
Dispatcher.BeginInvoke(() =>
{
StatusText.Text = "Loaded " + result.Length + " characters";
ProgressBar.Visibility = Visibility.Collapsed;
});
}
}Rule of thumb: any code running inside a WebClient completion handler, a BackgroundWorker.DoWork delegate, or a manually created Thread must never touch a UI element directly. Wrap the UI update in Dispatcher.BeginInvoke (or CheckAccess() first if you need conditional marshaling) and keep the delegate body small — do the heavy lifting on the background thread and only push the final result across.
Deployment and Isolated Storage Pitfalls
Silverlight ships as a single .xap file, which is really just a ZIP archive containing the application assembly, referenced assemblies, and a manifest. Referencing large or unnecessary assemblies bloats the XAP and slows first-load time over the network, since the whole package must download before the plug-in can start. Separately, IsolatedStorageFile gives each application a private, sandboxed storage area on the client machine, but the default quota is only 1,048,576 bytes (1 MB) per site — writing more than that without first requesting more space throws at runtime, often in production long after the app passed testing with small sample data.
Cricket analogy: A team that overloads its kit bag with gear it will never use on tour slows down every transfer between grounds, similar to a XAP bloated with unused assemblies slowing the app's initial download.
Never assume isolated storage quota can be exceeded gracefully. If your app needs more than the default 1 MB, call IsolatedStorageFile.IncreaseQuotaTo() proactively — and remember this call must originate from a user-initiated event (like a button click), or it may be silently ignored or prompt the user unexpectedly.
- Silverlight binding failures are silent by default — always verify INotifyPropertyChanged and Binding.Mode when a control shows stale data.
- Silverlight supports only StaticResource, which resolves once at XAML parse time; it will not track later changes to a resource dictionary.
- UI elements can only be touched from the UI thread; background thread code must marshal updates through Dispatcher.BeginInvoke.
- WebClient callbacks, BackgroundWorker.DoWork, and manually created threads all run off the UI thread and require Dispatcher marshaling.
- The .xap file is a ZIP archive; unnecessary assembly references directly bloat download size and slow first load.
- IsolatedStorageFile defaults to a 1 MB quota per site; exceeding it without calling IncreaseQuotaTo() throws at runtime.
- IncreaseQuotaTo() must be called from a user-initiated event handler to reliably succeed.
Practice what you learned
1. Why does a Silverlight TextBox fail to reflect changes made in the underlying view-model property?
2. What happens when you use DynamicResource syntax in Silverlight XAML?
3. What exception is thrown when a background thread directly modifies a Silverlight UI element?
4. What is the default isolated storage quota per Silverlight application site?
5. From where should IsolatedStorageFile.IncreaseQuotaTo() typically be called to reliably succeed?
Was this page helpful?
You May Also Like
Silverlight Debugging
Practical techniques for diagnosing binding failures, cross-thread exceptions, and network issues in Silverlight applications using Visual Studio and browser tools.
Silverlight Quick Reference
A condensed reference covering Silverlight's core XAML syntax, binding modes, threading rules, and networking essentials for fast lookup.
Silverlight Legacy Maintenance
Practical guidance for keeping aging Silverlight line-of-business applications running safely now that the plug-in is unsupported by modern browsers.
Related Reading
Related Study Notes in Microsoft Technologies
Browse all study notesWindows 10 / UWP Development Study Notes
.NET · 30 topics
Microsoft TechnologiesWindows Batch Scripting Study Notes
Batch · 30 topics
Microsoft TechnologiesMFC (Microsoft Foundation Classes) Study Notes
C++ · 30 topics
Microsoft TechnologiesXAML Study Notes
.NET · 30 topics
Microsoft TechnologiesWPF (Windows Presentation Foundation) Study Notes
.NET · 30 topics
Microsoft TechnologiesMVVM Design Pattern Study Notes
.NET · 30 topics