Changing Theme on the fly Runtime

9 posts, 0 answers
  1. FJ
    FJ avatar
    12 posts
    Member since:
    May 2007

    Posted 10 Jun 2011 Link to this post

    Is there a way to change a theme of the application runtime on the fly?
  2. Ivan Petrov
    Admin
    Ivan Petrov avatar
    701 posts

    Posted 15 Jun 2011 Link to this post

    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.
  3. UI for WinForms is Visual Studio 2017 Ready
  4. Jason Parrish
    Jason Parrish avatar
    87 posts
    Member since:
    Sep 2009

    Posted 19 Jul 2011 Link to this post

    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.
  5. Ivan Petrov
    Admin
    Ivan Petrov avatar
    701 posts

    Posted 21 Jul 2011 Link to this post

    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!

  6. Jason Parrish
    Jason Parrish avatar
    87 posts
    Member since:
    Sep 2009

    Posted 21 Jul 2011 Link to this post

    I did not realize that.  Thank you!
  7. Garry
    Garry avatar
    205 posts
    Member since:
    Nov 2010

    Posted 13 Sep 2011 Link to this post

    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)
  8. Teodor
    Admin
    Teodor avatar
    501 posts

    Posted 16 Sep 2011 Link to this post

    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 >>

  9. Garry
    Garry avatar
    205 posts
    Member since:
    Nov 2010

    Posted 19 Sep 2011 Link to this post

    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();
            }
  10. Teodor
    Admin
    Teodor avatar
    501 posts

    Posted 21 Sep 2011 Link to this post

    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 >>

Back to Top
UI for WinForms is Visual Studio 2017 Ready