Skip to main content

Microsoft Silverlight

Answered Question Dynamic loading of stylesRSS Feed

(0)

WTS_Pete
WTS_Pete

Member

Member

1 points

9 Posts

Dynamic loading of styles

 I apologize in advance if this has been beat like a dead horse...

I'm new to SL (currently coding in SL 2 Beta 2).  We are developing an application that needs to be able to be branded for each client.  Essentially what I'm trying to do is create a file similar to App.xaml where I can define properties for controls (font, font size, color, background gradients, etc).  Each client would get a version of this file custom to them when the app is deployed (I don't need to tie any skinning/branding to users, just per site this is hosted).  I've been doing a lot of searching and it appears that setting a style for a control more than once will error out.  That's fine, I only want to set it once at initialization but I don't want to have to compile a different version of the XAP for each client.  Also in my searching I've seen examples of folks using DynamicResource in WPF but apparently this was not available in Silverlight 1 or 2 Beta 1.  Is this still true in SL 2 Beta 2?

 

sladapter
sladapter

All-Star

All-Star

17439 points

3,172 Posts

Re: Dynamic loading of styles

Yes, you can do this. You can leave the Style definition or Template in a xaml file outside of your .Xap and dynamically load them then use XamlReader.Load function to turn the xaml string to Style or Template:

Say you have a Xaml Style string like this:

 string xaml = "<Style x:Key="DropdownButtonStyle" TargetType="Button" xmlns='http://schemas.microsoft.com/client/2007'
              xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'
>
 ..

</Style>"

One thing you have to do is putting the namespace in your style definition so XamlReader can load it:

 Style st = XamlReader.Load(temp) as Style;

 myButton.Style = st;  // set your button style:

This shows you how to load xaml string into Style.

So you can putting the xaml in a file outside your ,Xap file. Use WebClient.DownloadString to download the file string to your Silverlight. Then use XamlReader to load it into style. 

You can also zip up all your style files for your app into one zip file. Just download the zip file, then you can read each xaml file from that zip file. If you want to learn how to do this, read this blog: http://www.galasoft-lb.ch/mydotnet/articles/article-2008032301.html

 

 

 

sladapter
Software Engineer
Aprimo, Inc

Please remember to mark the replies as answers if they answered your question

WTS_Pete
WTS_Pete

Member

Member

1 points

9 Posts

Re: Dynamic loading of styles

Playing around with this, it seems like it'll work although a bit clunky (I have a lot of controls that'll need to be set).  Is there not a way to do a similar concept directly in the xaml?   Something along the lines of Style="{DynamicResource "BrandAFileName.xaml:CoolButtonStyle}"?

sladapter
sladapter

All-Star

All-Star

17439 points

3,172 Posts

Re: Dynamic loading of styles

 I know what you mean. It's still not totally like you define the style in Application.Resources or UserControl.Resources.

I don't know if I can add the style to (or replace the style in) the Application.Resources directory then still use Style="{StaticResource MyButtonStyle}" or not. I've never tried it.

Because using Style="{StaticResource MyButtonStyle}" without MyButtonStyle defined might cause build error. So I'm thinking if we can replace it with dynamically loaded style that should solve your problem.  But I don't know if it would work.

 


 

sladapter
Software Engineer
Aprimo, Inc

Please remember to mark the replies as answers if they answered your question

WTS_Pete
WTS_Pete

Member

Member

1 points

9 Posts

Re: Dynamic loading of styles

What would be nice is if you included a template file in the solution so at compile time it'll compile correctly but when the package is initialized out on the web server it reads from the separate text file.  That way each site could have it's own style.  Thanks again for the suggestion, I'm going to be working through it today.

lee_sl
lee_sl

Contributor

Contributor

2992 points

585 Posts

Re: Re: Dynamic loading of styles

This post might help http://leeontech.wordpress.com/2008/07/21/dynamic-styles/

----------------------------------------------
Available for consulting in Dallas, TX
http://leeontech.wordpress.com/

sladapter
sladapter

All-Star

All-Star

17439 points

3,172 Posts

Re: Re: Dynamic loading of styles

 Thanks lee !  So clear Application.Resources and the load the new Style (with the same name as the original one) in it would work.

 

 

sladapter
Software Engineer
Aprimo, Inc

Please remember to mark the replies as answers if they answered your question

WTS_Pete
WTS_Pete

Member

Member

1 points

9 Posts

Re: Re: Dynamic loading of styles

Unless I'm missing something the styles are still defined at compile time though. 

lee_sl
lee_sl

Contributor

Contributor

2992 points

585 Posts

Re: Re: Dynamic loading of styles

The style names are set in the controls. but the content of the styles which are defined in the App.xaml are replaced completey at runtime from the external files

----------------------------------------------
Available for consulting in Dallas, TX
http://leeontech.wordpress.com/

WTS_Pete
WTS_Pete

Member

Member

1 points

9 Posts

Re: Re: Dynamic loading of styles

I've been playing around with this today (thanks for providing the source code).  Digging into it appears that you are loading the styles/etc from a file that's still within the xap though.  For example, Flat.xaml is built into the DynamicStyles xap.  When you load the themes in your code, you use the Application.GetResourceStream which according to MSDN essentially grabs an embedded resource data file.  I'm trying to figure out is once I deploy the DynamicStyles xap, can I change say fontsize from 10 to 12 in the Flat.xaml and have that change be reflected w/o creating a new xap?  Looking at the output files of this project, none of the xaml files are part of the deployment (which I thought was normal, everything is bundled up in the xap).

 

It think what I'm looking for is essentially the equivalent of CSS file for SL.

sladapter
sladapter

All-Star

All-Star

17439 points

3,172 Posts

Re: Re: Dynamic loading of styles

Take a look at SetTheme function:

  private void SetTheme(string s)
        {
            App.Current.Resources.Clear();   // Clear the Current Resoueces which may contains default Styles
            List<Theme> themeSettings = new List<Theme>();          
            themeSettings = IsolatedStorageSettings.ApplicationSettingsSleep as List<Theme>;
          
            foreach (Theme t in themeSettings)
                App.Current.Resources.Add(t.Key, XamlReader.Load(t.Value)); // Re-Load the new style string that you read from your External xaml file
        }

Now you should be able to load the custom style for each customer dynamically. The only thing you need to do is you have a default set of styles defined in the App.Xaml. Then you can have another set of style outside your Xap which is your custom style. Each style should have the same key as that in the default set. Each style should be in their own file.


 

 

 

 

 

sladapter
Software Engineer
Aprimo, Inc

Please remember to mark the replies as answers if they answered your question

WTS_Pete
WTS_Pete

Member

Member

1 points

9 Posts

Re: Re: Dynamic loading of styles

I've seen this but the IsolatedStorageSettings.ApplicationSettings is populated via the GetThemes function which uses the Application.GetResourcesStream function to load the xaml files.  I believe this function will only load a file that is part of the xap, I can't use this to load a random file on the web server that contains the customer specific settings.

 

EDIT:  I just realized that I didn't see your whole post, I'll be looking into this some more.  Thanks again for your help. 

sladapter
sladapter

All-Star

All-Star

17439 points

3,172 Posts

Answered Question

Re: Re: Dynamic loading of styles

 

I did not download the demo code Lee provided. But I think you could use  Application.GetResourcesStream to read the each style files out of a Zip file (not the .Xap):

First you need to use a WebClient.OpenRead function to load the zip file to Silverlight:

            WebClient wc = new WebClient();           
            wc.OpenReadCompleted += new OpenReadCompletedEventHandler(wc_OpenReadCompleted);
            wc.OpenReadAsync(new Uri(App.Current.Host.Source, "../Styles/YourStyle.zip"));

void wc_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
        {
            if (e.Error == null)
            {
               StreamResourceInfo  _zipInfo = new StreamResourceInfo(e.Result, null);  // this contains your whole Zip file stream                                   

               // the following line only read a file out of the zip by providing the filepath under the zip:

                StreamResourceInfo manifestInfo = Application.GetResourceStream(_zipInfo, new Uri("YourStyleFilePath", UriKind.Relative));

                StreamReader reader = new StreamReader(manifestInfo.Stream);   // read file out of zip

                 ...

           }

 

sladapter
Software Engineer
Aprimo, Inc

Please remember to mark the replies as answers if they answered your question

WTS_Pete
WTS_Pete

Member

Member

1 points

9 Posts

Re: Re: Dynamic loading of styles

I'm able to read a text file via web services which is a very similar concept to your example (basically my web service replaces the WebClient object).  I was hoping to figure out a CSS like solution where there's very little code involved but it doesn't appear to be quite that elegant.

slyi
slyi

Participant

Participant

824 points

254 Posts

Re: Re: Dynamic loading of styles

I love Lee's sample. You could update on and wrap Lee DynamicStyles sample as a custom type, that you reference in xaml similar to how CSS is referenced, or dynamiclly add the control to the page's children in the code-behind.

eg:

<UserControl ... xmlns:LoadCSS="clr-namespace:DynamicStyles;assembly=DynamicStyles" />

<LoadCSS:DynamicStyles ThemeSrc="./GreenTheme.xaml" /> and then it will be applied to your current page controls

dstrohschein
dstrohsc...

Member

Member

2 points

12 Posts

Re: Re: Dynamic loading of styles

 Sorry to bump such an old post, but there is something in Lee's post that is confusing - where is this Theme class??? Has it been replaced in Silverlight 2 RTM by the Style class?

 

I've done what WTS pete said - created a wcf webservice that serves up the style xaml, but I can't figure out how to add it to the Application Resources collection. Can someone lend me an idea?

 

Thank you!

D

  • Unanswered Question
  • Answered Question
  • Announcement
Microsoft Communities