This is a migrated thread and some comments may be shown as answers.

Changing Theme on the fly Runtime

8 Answers 970 Views
Themes and Visual Style Builder
This is a migrated thread and some comments may be shown as answers.
FJ
Top achievements
Rank 1
FJ asked on 10 Jun 2011, 02:44 PM
Is there a way to change a theme of the application runtime on the fly?

8 Answers, 1 is accepted

Sort by
0
Ivan Petrov
Telerik team
answered on 15 Jun 2011, 10:53 AM
Hi fj,

Thank you for writing.

You can certainly change the theme at run time. There are two things you need to do:
1. Load a theme in the memory.
2. Apply the theme.

The best way to do this is to have a method that loads the desired theme in the memory and apply it. Consider the following code snippet:

private void ChangeApplicationTheme(string themeName)
{
  switch (themeName)
  {
    case "Office2010Black":
      new Office2010BlackTheme();
      break;
    case "Office2010Blue":
      new Office2010BlueTheme();
      break;
    case "Office2010SIlver":
      new Office2010SilverTheme();
      break;
  }
 
  ThemeResolutionService.ApplicationThemeName = themeName;
}

You should not worry for loading the same theme twice. Loading one theme twice in an application will not result in doubling the amount of memory being used, this is why the best approach is to load the themes on demand.

I hope this will help you. If you have further questions I would be glad to help.

 

Best wishes,
Ivan Petrov
the Telerik team
Q1’11 SP1 of RadControls for WinForms is available for download; also available is the Q2'11 Roadmap for Telerik Windows Forms controls.
0
Jason Parrish
Top achievements
Rank 1
answered on 19 Jul 2011, 04:52 PM
What are the text equivalents to each name since they do not appear to match the class name?  It would be better if the Theme dll would return a property with the proper string equivalent.
0
Ivan Petrov
Telerik team
answered on 21 Jul 2011, 01:24 PM
Hi Jason,

Thank you for writing.

All theme class names end with "Theme". The theme name you can use to set the ThemeResolutionService.ApplicationThemeName for example is the class name without the "Theme" ending. So for example if the theme class name is "DesertTheme", the theme name is "Desert". You can use the following code snippet to get the theme name using the theme class:

Office2010BlackTheme theme = new Office2010BlackTheme();
string themeName = theme.GetType().Name.Replace("Theme", String.Empty);
This does not seem to be the most convenient way of getting the theme name and we will consider implementing a better way for this task in the future.

I have updated your Telerik points for the good suggestion.

If you have further questions, feel free to ask.

Regards,
Ivan Petrov
the Telerik team

Register for the Q2 2011 What's New Webinar Week. Mark your calendar for the week starting July 18th and book your seat for a walk through of all the exciting stuff we will ship with the new release!

0
Jason Parrish
Top achievements
Rank 1
answered on 21 Jul 2011, 03:01 PM
I did not realize that.  Thank you!
0
Garry
Top achievements
Rank 1
answered on 13 Sep 2011, 03:12 PM
Ivan,
OK so here is a sort of follow up question to the one Jason asked. I am trying to set a theme at runtime using a combobox or another list control, kind of like you guys do in your demos, but when I change the Theme I get an error and can't quite figure out what I am missing. The combobox theme itself changes, but none of the other controls bound to the SelectedTheme property do. Any ideas or is there a sample of how you guys do your themeing mechanisim in your demos?

Thanks,
Garry

Public Themes Class
/// <summary>
   /// This class is used to return the available themes and the maintain the selected theme
   /// </summary>
   public class Themes : INotifyPropertyChanged
   {
       private string _selectedTheme = "Windows7";
 
       /// <summary>
       /// Holds the users selected theme value
       /// </summary>
       public Theme SelectedTheme
       {
           get { return ThemeManager.StandardThemes[_selectedTheme]; }           
           set
           {
               if (ThemeManager.StandardThemes.ContainsKey(value.ToString()))
               {
                   _selectedTheme = value.ToString();
                   NotifyPropertyChanged("SelectedTheme");                                  
               }
               else
               {
                   return;
               }               
           }
       }
 
       /// <summary>
       /// Listing of the available themes by name
       /// </summary>
       public ReadOnlyCollection<string> Names
       {
           get { return ThemeManager.StandardThemeNames; }
       }
 
       // Declare the PropertyChanged event
       public event PropertyChangedEventHandler PropertyChanged;
 
       // NotifyPropertyChanged will raise the PropertyChanged event passing the
       // source property that is being updated.
       public void NotifyPropertyChanged(string propertyName)
       {
           if (PropertyChanged != null)
           {
               PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
           }
       
 
   }

XAML Bindings For ComboBox
<telerik:RadComboBox x:Name="cmbThemes" ItemsSource="{Binding Source={StaticResource themeCollection}, Path=Names}"
                                         SelectedValue="{Binding Source={StaticResource themeCollection}, Path=SelectedTheme,Mode=TwoWay}"
                                         telerik:StyleManager.Theme="{Binding Source={StaticResource themeCollection}, Path=SelectedTheme}"/>

Error Message
Value cannot be null.
Parameter name: element

StackTrace
at MS.Internal.XcpImports.ItemsControl_GetItemsOwner(DependencyObject element)
   at System.Windows.Controls.ItemsControl.ItemsControlFromItemContainer(DependencyObject container)
   at Telerik.Windows.Controls.ItemsControl.ItemsControlFromItemContainer(DependencyObject container)
   at Telerik.Windows.Controls.ListBoxItem.get_ParentSelector()
   at Telerik.Windows.Controls.RadComboBoxItem.get_ParentComboBox()
   at Telerik.Windows.Controls.RadComboBoxItem.BringIntoView()
   at Telerik.Windows.Controls.RadComboBox.ScrollIntoView(Object item)
   at Telerik.Windows.Controls.RadComboBox.NavigateToItem(Object item)
   at Telerik.Windows.Controls.RadComboBox.OnSelectionChanged(SelectionChangedEventArgs e)
   at Telerik.Windows.Controls.RadComboBox.SelectItemDelayedSelectionChanged(Object item)
   at Telerik.Windows.Controls.RadComboBox.NotifyComboBoxItemMouseUp(RadComboBoxItem comboBoxItem)
   at Telerik.Windows.Controls.RadComboBoxItem.OnMouseLeftButtonUp(MouseButtonEventArgs e)
   at System.Windows.Controls.Control.OnMouseLeftButtonUp(Control ctrl, EventArgs e)
   at MS.Internal.JoltHelper.FireEvent(IntPtr unmanagedObj, IntPtr unmanagedObjArgs, Int32 argsTypeIndex, Int32 actualArgsTypeIndex, String eventName, UInt32 flags)
0
Teodor
Telerik team
answered on 16 Sep 2011, 05:23 PM
Hi Garry,

The theming mechanism in the demos is implemented via setting the currently selected theme to StyleManager.ApplicationTheme and reloading of the view. Thus all controls with a default theme are applied the application theme. This mechanism can be found implemented in the attachment in this forum post as well.

In your particular case (working with the StyleManager.Theme property), the controls' UI might need to be reapplied in order to be shown refreshed with the new theme. Here is a way to do that:

var template = someControl.Template;
someControl.Template = null;
someControl.Template = template;


Hope this helps! Let us know in case you need further assistance.

Kind regards,
Teodor
the Telerik team

Explore the entire Telerik portfolio by downloading the Ultimate Collection trial package. Get it now >>

0
Garry
Top achievements
Rank 1
answered on 20 Sep 2011, 04:12 AM
Teodor,
Thank you for your reply and for the link to the sample, however neither quite fixes my issue. In both the example and in your response they both seem to set the theme in the code behind of the UserControl. I am trying to accomplish the same functionality using a viewmodel and databinding.

So I can't see how to accomplish the sample code below in that scenario. I also can't grab the control form my viewmodel to reset its template. Or am I wrong here and just not thinking about these solutions properly?

Thanks,
Garry
private void vistaTheme_Click(object sender, RoutedEventArgs e)
        {
            var content = new MainPage();
         
            StyleManager.ApplicationTheme = new VistaTheme();
            this.pagePresenter.Content = content;
 
        }
 
        private void SummerTheme_Click(object sender, RoutedEventArgs e)
        {
            var page = new MainPage();
            StyleManager.ApplicationTheme = new SummerTheme();
 
            this.pagePresenter.Content = new MainPage();
        }
 
        private void ExpressionDark_Click(object sender, RoutedEventArgs e)
        {
            var page = new MainPage();
            StyleManager.ApplicationTheme = new Expression_DarkTheme();
 
            this.pagePresenter.Content = new MainPage();
        }
0
Teodor
Telerik team
answered on 21 Sep 2011, 10:55 AM
Hello Garry,

Thank you for the reply.

You may try creating an attached property that will change the theme of the element to which it is attached. The usage will be something like:

<telerik:RadButton local:ThemeSelector.CurrentTheme={Binding SelectedTheme} />

On the changed callback of the attached property, you could change the Theme of the element (and if needed reapply the template). Thus you may switch themes through databinding.

Hope this guides you to an acceptable solution. Let us know in case you need further assistance.

Greetings,
Teodor
the Telerik team

Explore the entire Telerik portfolio by downloading the Ultimate Collection trial package. Get it now >>

Tags
Themes and Visual Style Builder
Asked by
FJ
Top achievements
Rank 1
Answers by
Ivan Petrov
Telerik team
Jason Parrish
Top achievements
Rank 1
Garry
Top achievements
Rank 1
Teodor
Telerik team
Share this question
or