Different colors for different parts of the UI for Windows 8 theme

9 posts, 0 answers
  1. Jordan
    Jordan avatar
    12 posts
    Member since:
    Jul 2012

    Posted 15 Sep 2014 Link to this post

    We have a requirement that different parts of the UI should be able to have a different color scheme. The Windows8 theme is nice because we only need to set a few colors, but Windows8Palette is a singleton that affects the entire application. Given that -- what's the best way to achieve this affect?

    This thread (http://www.telerik.com/forums/using-multiple-windows8-themes) suggests that using implicit styles and loading them into the resource dictionary of the parts of the UI that we want to (http://www.telerik.com/help/wpf/styling-apperance-implicit-styles-overview.html) might work.

    We would have to make a copy of Windows 8 theme, then, and instead of binding to Windows8Palette, we'd have to bind to something else. I suppose that's just a global text search&replace on the theme files, but it doesn't seem optimal to me.

    Does anyone have any ideas/suggestions?
    Thanks!

    (It almost seems like the Windows 8 theme needs to support a dictionary of palettes, keyed by some string. And the Windows8Palette singleton can use some well-known value in the resource dictionary -- CurrentPalette for example -- to choose the actual colors to use)
  2. Vanya Pavlova
    Admin
    Vanya Pavlova avatar
    2019 posts

    Posted 16 Sep 2014 Link to this post

    Hi Jordan,


    Thank you for contacting us. 

    As you already know Telerik controls in Windows8 theme use resources, that are linked to a one major singleton. The same is valid for Windows8Touch theme, as well. 

    You are absolutely right, that this singleton object will affect the entire look and feel of all controls used in the application.  

    Looking at the information provided, you need to use some additional logic that will affect only specific part of the user interface. Using Windows8 theme this could not be easily achieved, because this theme does not expose theme pallette, as well. In fact, this theme is not designed to be extended in the way you need.  

    The closest possible option we may offer is to try out different color variations of Office2013 and VisualStudio2013 themes. 

    Both of them, provide different color variations and the resources used in this theme affect specific parts of the components. 

    Office2013 theme exposes three color variations-White, LightGray, DarkGray
    VisualStudio2013 theme also exposes three color variations-Light, Blue, Dark.

    These themes are a bit different from Windows8, because they add additional customization of specific parts in single theme.

    Once you switch these variations you could see that the difference from the default one is default background, color of headers, hover and selection effects etc. The control template is common for all of them, however with a single line of code you may affect the details you need using these variations. 

    If you want to change or to extend the detailed parts of these variations you may always edit the implicit styles of those components via XAML. There you could manually change the brush resources to point to the elements you need. Afterwards these changes will be reflected immediately in the defined UI. 

    May you verify how this suggestion corresponds to your needs? 

    Regards,
    Vanya Pavlova
    Telerik
     
    Check out Telerik Analytics, the service which allows developers to discover app usage patterns, analyze user data, log exceptions, solve problems and profile application performance at run time. Watch the videos and start improving your app based on facts, not hunches.
     
  3. UI for WPF is Visual Studio 2017 Ready
  4. Jordan
    Jordan avatar
    12 posts
    Member since:
    Jul 2012

    Posted 18 Sep 2014 in reply to Vanya Pavlova Link to this post

    Thanks for the reply. I did have a look at the Visual Studio 2013 theme -- and it's nice that you have different presets that one can load. However, since the Palette is still a global singleton, I still don't think it'll meet my needs of different themes for different windows in the UI.

    It seems I need to do the following:
    1. Copy the control templates for all of the controls I care about.
    2. Instead of pointing the brushes to the single Palettes, point it to some local brushes
    3. Include that in the resource dictionary for my window / user control

    In fact, it seems I shouldn't use the built in Windows 8 theme DLL at all -- instead, copy the XAMLs into my project, modify them as (2) above, and for each window, set the colors and then include all of the theme xamls in the resource dictionary.

    Sound about right?
    Thanks,
    Jordan
  5. Vanya Pavlova
    Admin
    Vanya Pavlova avatar
    2019 posts

    Posted 22 Sep 2014 Link to this post

    Hi Jordan,


    Thank you for getting back to us. 

    Yes, that's the procedure you should follow. This technique is similar to the following "Switching themes at runtime". Each time you change the theme you should add and clear the resource dictionaries within the resource scope of the window, as proposed in this article. 
    Hope this helps. 


    Regards,
    Vanya Pavlova
    Telerik
     
    Check out Telerik Analytics, the service which allows developers to discover app usage patterns, analyze user data, log exceptions, solve problems and profile application performance at run time. Watch the videos and start improving your app based on facts, not hunches.
     
  6. Jordan
    Jordan avatar
    12 posts
    Member since:
    Jul 2012

    Posted 22 Sep 2014 in reply to Vanya Pavlova Link to this post

    Thanks for the replies. I'm currently prototyping a technique described by this blog:
    http://www.thomaslevesque.com/2011/10/01/wpf-creating-parameterized-styles-with-attached-properties/

    Essentially, I'm going to create static attached, inherited properties for all of the colors and font settings in the theme. Then I just need to replace:

    <Setter Property="FontSize" Value="{telerik1:Windows8Resource ResourceKey=FontSize}"/>

    with something like:
    <Setter Property="FontSize" Value="{Binding Path=(Foo:DynamicPalette.FontSize), RelativeSource={RelativeSource Self}}"/>

    where DynamicPalette is a static class containing the static attached properties I mention above. I need to investigate the best way to modify the theme files, maybe with my own markup extension?

    Then, in my xaml, i can customize the theme at any level in the UI with something like:

    <Grid Foo:DynamicPalette.FontSize="8">...</Grid>
  7. Vanya Pavlova
    Admin
    Vanya Pavlova avatar
    2019 posts

    Posted 22 Sep 2014 Link to this post

    Hello Jordan,


    Thank you for sharing this information with us. 

    The approach proposed in the referred blog post is interesting, indeed.
    If you choose this way you could make mass replace of the style setters to change the predefined Windows8 values.

    However, you have to still look up for inline font size values within the templates, that are outside of the style setters. 
     
    If you have any additional questions do not hesitate to contact us again. 


    Regards,
    Vanya Pavlova
    Telerik
     
    Check out Telerik Analytics, the service which allows developers to discover app usage patterns, analyze user data, log exceptions, solve problems and profile application performance at run time. Watch the videos and start improving your app based on facts, not hunches.
     
  8. Jordan
    Jordan avatar
    12 posts
    Member since:
    Jul 2012

    Posted 22 Sep 2014 in reply to Vanya Pavlova Link to this post

    I think I have it to a point where it should work. I've only modified RadButtonStyle, but I cannot think of a reason why I cannot do a global search-and-replace on all of the theme files. I do have a sample project, it seems I am only allow to post images. I'll send you the example project privately and you can post it on this forum thread if you wish.

    DynamicsPalette.cs is the static class with all of the property definitions, along the lines of this:

    public static class DynamicPalette
    {
        public static readonly DependencyProperty FontSizeProperty = RegisterDouble("FontSize", DefaultFontSize);
    public static double GetFontSize(DependencyObject obj)
    {
    return (double)obj.GetValue(FontSizeProperty);
    }

    public static void SetFontSize(DependencyObject obj, double value)
    {
    obj.SetValue(FontSizeProperty, value);
    }

    public static DependencyProperty RegisterDouble(string propertyName, double value)
    {
    return DependencyProperty.RegisterAttached(propertyName, typeof(double), typeof(DynamicPalette),
    new FrameworkPropertyMetadata(value, FrameworkPropertyMetadataOptions.Inherits));
    }

    DynamicPaletteExtension.cs just makes the xaml a bit nicer:

    namespace ThemeExample
    {
    [MarkupExtensionReturnType(typeof(BindingExpression))]
    public class DynamicPaletteExtension : MarkupExtension
    {
    [ConstructorArgument(("property"))]
    public string Property { get; set; }

    public DynamicPaletteExtension(string property)
    {
    Property = property;
    }

    public override object ProvideValue(IServiceProvider serviceProvider)
    {
    var binding = new Binding
    {
    RelativeSource = new RelativeSource(RelativeSourceMode.Self),
    Path = new PropertyPath("(ThemeExample:DynamicPalette." + Property + ")")
    };
    return binding;
    }
    }
    }

    The setters in the themes now look like this:

    <Setter Property="FontSize" Value="{ThemeExample:DynamicPalette FontSize}"/>

    and you can set values for the properties with something like this:

    <Window.Resources>
         <SolidColorBrush x:Key="MainBrush" Color="Green" />
         <SolidColorBrush x:Key="MarkerBrush" Color="Red" />
    </Window.Resources>
    <Grid ThemeExample:DynamicPalette.FontSize="8"
              ThemeExample:DynamicPalette.MainBrush="{StaticResource MainBrush}"
              ThemeExample:DynamicPalette.MarkerBrush="{StaticResource MarkerBrush}">
    <Grid.RowDefinitions>
    <RowDefinition Height="Auto" />
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
    <ColumnDefinition Width="Auto" />
    </Grid.ColumnDefinitions>
    <telerik:RadButton x:Name="MyButton" Margin="10" Content="Hello World!" Click="RadButton_Click" />
    </Grid>

    or this:

    var subWindow = new MainWindow();
    subWindow.MyButton.SetValue(DynamicPalette.FontSizeProperty, (double)12);
    subWindow.MyButton.SetValue(DynamicPalette.MainBrushProperty, new SolidColorBrush(Colors.White));
    subWindow.MyButton.SetValue(DynamicPalette.StrongBrushProperty, new SolidColorBrush(Colors.White));
    subWindow.Show();

    The modified theme files should all just be loaded once in App.xaml, something like this:

    <Application.Resources>
    <ResourceDictionary>
    <ResourceDictionary.MergedDictionaries>
    <ResourceDictionary Source="System.Windows.xaml" />
    <ResourceDictionary Source="Telerik.Windows.Controls.xaml" />
    <ResourceDictionary Source="Telerik.Windows.Controls.Input.xaml" />
    </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
    </Application.Resources>







  9. Jordan
    Jordan avatar
    12 posts
    Member since:
    Jul 2012

    Posted 22 Sep 2014 in reply to Jordan Link to this post

    I wonder if the following is still needed in the theme xaml files?

    <ResourceDictionary.MergedDictionaries>
    <telerik:Windows8ResourceDictionary/>
    </ResourceDictionary.MergedDictionaries>
    <telerik:Windows8Colors x:Key="Windows8Colors"/>
  10. Vanya Pavlova
    Admin
    Vanya Pavlova avatar
    2019 posts

    Posted 23 Sep 2014 Link to this post

    Hi Jordan,


    Thank you for getting back to us.

    Windows8ResourceDictionary holds the resources from the Windows8Palette

    I recommend you to keep it in order to have a direct access to the resources used in this theme. 


    Regards,
    Vanya Pavlova
    Telerik
     
    Check out Telerik Analytics, the service which allows developers to discover app usage patterns, analyze user data, log exceptions, solve problems and profile application performance at run time. Watch the videos and start improving your app based on facts, not hunches.
     
Back to Top
UI for WPF is Visual Studio 2017 Ready