1: using System;
2: using System.Net;
3: using System.Windows;
4: using System.Windows.Markup;
5: using System.Collections.Generic;
6: using System.Linq;
7: namespace RuntimeStyles
8: {
9: public class StyleLoader
10: {
11: public event EventHandler AllStylesLoaded;
12: private List<ResourceDictionary> _allReadyLoaded;
13: private ResourceDictionary _toMergeWith;
14:
15: public void LoadStyles(ResourceDictionary toMergeWith, Uri xamlUri, params Uri[] xamlUris)
16: {
17: if (_allReadyLoaded != null)
18: {
19: throw new InvalidOperationException("You have to wait before" +
20: " the previous call has finished!");
21: }
22: _allReadyLoaded = new List<ResourceDictionary>(xamlUris.Length);
23: _toMergeWith = toMergeWith;
24:
25: DownloadStyle(xamlUri);
26: foreach (Uri downloadUri in xamlUris)
27: {
28: DownloadStyle(downloadUri);
29: }
30: }
31:
32: public void LoadStyles(Uri xamlUri, params Uri[] xamlUris)
33: {
34: LoadStyles(Application.Current.Resources,xamlUri, xamlUris);
35: }
36:
37: private void DownloadStyle(Uri downloadUri)
38: {
39: WebClient wc = new WebClient();
40: wc.DownloadStringCompleted += ParseAndAddStyles;
41: wc.DownloadStringAsync(downloadUri);
42: }
43:
44: private void ParseAndAddStyles(object sender, DownloadStringCompletedEventArgs e)
45: {
46: if (e.Error == null)
47: {
48: ResourceDictionary loaded = null;
49: try
50: {
51: loaded = XamlReader.Load(e.Result) as ResourceDictionary;
52: }
53: catch
54: {
55: CleanUp();
56: throw;
57: }
58: if (loaded != null)
59: {
60: if (_allReadyLoaded.Count == _allReadyLoaded.Capacity)
61: {
62: //This was the last call to complete
63: _toMergeWith.MergedDictionaries.Add(loaded);
64: foreach (ResourceDictionary dic in _allReadyLoaded)
65: {
66: _toMergeWith.MergedDictionaries.Add(dic);
67: }
68: CleanUp();
69: OnAllStylesLoaded(new EventArgs());
70: }
71: else
72: {
73: _allReadyLoaded.Add(loaded);
74: }
75: }
76: else
77: {
78: CleanUp();
79: throw new InvalidOperationException("The loaded xaml was not a resource dictionary!");
80: }
81: }
82: else
83: {
84: CleanUp();
85: throw e.Error;
86: }
87: }
88:
89: private void CleanUp()
90: {
91: _toMergeWith = null;
92: _allReadyLoaded = null;
93: }
94:
95: protected virtual void OnAllStylesLoaded(EventArgs args)
96: {
97: EventHandler temp = AllStylesLoaded;
98: if (temp != null)
99: {
100: temp(this, new EventArgs());
101: }
102: }
103:
104: }
105: }