100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace
.NET

Silverlight Common Pitfalls

A field guide to the mistakes developers repeatedly make when building Silverlight applications, covering data binding, threading, and deployment traps.

Practical SilverlightIntermediate9 min readJul 10, 2026
Analogies

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.

csharp
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

Was this page helpful?

Topics covered

#NET#SilverlightStudyNotes#MicrosoftTechnologies#SilverlightCommonPitfalls#Silverlight#Common#Pitfalls#Development#StudyNotes#SkillVeris