8 Answers, 1 is accepted
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
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);
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!
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)
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 >>
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();
}
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 >>