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

Colorizing controls independently

6 Answers 79 Views
General Discussions
This is a migrated thread and some comments may be shown as answers.
Theodore
Top achievements
Rank 1
Theodore asked on 11 Apr 2015, 02:01 PM

Hello,

 I am evaluating your control suit for WPF and I find it extremely tedious and tiresome to colorize a control. I have to reimplement the control template just for a simple color change. Not only this is extremely counter-productive, it can lead to errors when the template is updated on a future UI for WPF version.

Let's take the simple case of a DropDownButton control. I want to have 2 dropdownbutton controls. I have settled on the theme, say Office2013 theme. I want the e.g. selected background on the first control to be red and on the second control green.

How can I do this easily if I don't have a simple property to set?  You don't even expose the theme colors as *attached* properties, like in the code I am posting below (no complete code included for brevity) in order to make our lives easier.

 

   <Style x:Key="RadDropDownButtonOffice2013ColorizableStyle" TargetType="telerik:RadDropDownButton">

        <Setter Property="BorderThickness" Value="1" />
        <Setter Property="FontFamily" Value="Calibri" />
        <Setter Property="MinHeight" Value="26" />
        <Setter Property="Padding" Value="6 2" />
        <Setter Property="FontSize" Value="15" />
        <Setter Property="BorderBrush" Value="{Binding RelativeSource={RelativeSource Self}, Path=(t:Office2013Brushes.HighDarkBrush)}" />
        <Setter Property="Background" Value="{Binding RelativeSource={RelativeSource Self}, Path=(t:Office2013Brushes.BasicBrush)}" />
        <Setter Property="Foreground" Value="{Binding RelativeSource={RelativeSource Self}, Path=(t:Office2013Brushes.InvertedBrush)}" />
        <Setter Property="CornerRadius" Value="0" />
        <Setter Property="IsOpen" Value="false" />
        <Setter Property="HorizontalContentAlignment" Value="Center" />
        <Setter Property="VerticalContentAlignment" Value="Center" />
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="telerik:RadDropDownButton">
                    <Grid SnapsToDevicePixels="True">
                        <VisualStateManager.VisualStateGroups>
                            <VisualStateGroup x:Name="CommonStates">
                                <VisualState x:Name="Normal" />
                                <VisualState x:Name="MouseOver">
                                    <Storyboard>
                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="Path" Storyboard.TargetProperty="Fill">
                                            <DiscreteObjectKeyFrame KeyTime="0" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(t:Office2013Brushes.InvertedBrush)}" />
                                        </ObjectAnimationUsingKeyFrames>
                                        <DoubleAnimation Duration="00:00:00.25" Storyboard.TargetName="OuterMouseOverBorder" Storyboard.TargetProperty="(UIElement.Opacity)" To="1" />
                                    </Storyboard>
                                </VisualState>

...... etc.................

 

and a static class to define the attached properties as shown below:

 

namespace Telerik
{
    public static class Office2013Brushes
    {
        #region Attached property BasicBrush
        //Define and register attached property
        public static readonly DependencyProperty BasicBrushProperty = DependencyProperty.RegisterAttached(
            "BasicBrush",
            typeof(Brush),
            typeof(Office2013Brushes),
            new FrameworkPropertyMetadata(new SolidColorBrush(Office2013Palette.Palette.BasicColor), FrameworkPropertyMetadataOptions.Inherits)
        );

        //Get/Set methods
        public static Brush GetBasicBrush(DependencyObject obj)
        {
            return (Brush)obj.GetValue(BasicBrushProperty);
        }
        public static void SetBasicBrush(DependencyObject obj, Brush value)
        {
            obj.SetValue(BasicBrushProperty, value);
        }
        #endregion

        #region Attached property MainBrush
        //Define and register attached property
        public static readonly DependencyProperty MainBrushProperty = DependencyProperty.RegisterAttached(
            "MainBrush",
            typeof(Brush),
            typeof(Office2013Brushes),
            new FrameworkPropertyMetadata(new SolidColorBrush(Office2013Palette.Palette.MainColor), FrameworkPropertyMetadataOptions.Inherits)
        );

        //Get/Set methods
        public static Brush GetMainBrush(DependencyObject obj)
        {
            return (Brush)obj.GetValue(MainBrushProperty);
        }
        public static void SetMainBrush(DependencyObject obj, Brush value)
        {
            obj.SetValue(MainBrushProperty, value);
        }
        #endregion

........ etc..

 The above code works fine: I can set the colors of the controls independently if I want to, or leave it to the default theme color. But, as it's easily understood, it is counter-productive for the developer to rewrite all the templates with the above logic.

The question is:

a) why you haven't created your controls to be "independently colorizable" (using attached properties or any other method you see fit) 

b) if you are planning to implement some pattern to make "colorization" easier.

 

Best regards,

Theodore

6 Answers, 1 is accepted

Sort by
0
Vanya Pavlova
Telerik team
answered on 13 Apr 2015, 10:27 AM
Hello Theodore,


Several years ago, we received invaluable customer feedback about our themes. Many clients wanted to customize our controls with a few lines of code for a particular theme. Modifications per control basis require a pile of XAML mark-up. We could not change the existent theme suite, because this would result in a breaking change that we want to avoid. We thought about various ways to extend theme customization pretty easy. 

Initally, our developers implemented a palette used by Windows8 theme that use resources which are linked to a one major singleton that contains the colors used in those themes. Windows8Touch, Office2013 and VisualStudio2013 themes follow the same manner.  Our clients definitely liked this approach and we follow the tradition. 

For those who want to customize a bit some controls, we strongly recommend to use simple property sets where it is possible. NoXAML binaries and implicit styles definitely additionally enhance the process. 

We would be greateful if you share your thoughts about how to make the customization of our controls easier in the way you expect. 



Regards,
Vanya Pavlova
Telerik
 

See What's Next in App Development. Register for TelerikNEXT.

 
0
Theodore
Top achievements
Rank 1
answered on 13 Apr 2015, 11:53 AM

Hello Vanya,

in the code I posted above, you don't have to change the singleton class you use for colorization. 

The implementation of the styles that I am proposing EXTENDS the functionality of your styles, does not change it. If the user wants to specify e.g. his MainBrush for a specific control, he can do so by assigning the MainBrush ATTACHED property. If not, the default theme brush color is used, as you can see in the static class attached property definition. 

By following this logic, you can give the option to your users to colorize independently their controls without sacrificing on compatibility.

Please let me know If you want the full code that demostrates this logic.

0
Vanya Pavlova
Telerik team
answered on 13 Apr 2015, 11:58 AM
Hello Theodore,


I will forward your request to the development team for further consideration and will get back to you as soon as we have a position on that matter. 

Have a great day. 


Regards,
Vanya Pavlova
Telerik
 

See What's Next in App Development. Register for TelerikNEXT.

 
0
Petya
Telerik team
answered on 04 May 2015, 04:02 PM
Hello Theodore,

We discussed the topic internally and while we find your idea very interesting and flexible, there are some concerns that prevent us from adopting it. 

One of the main points that were discussed is that such notion would cause performance drop and memory consumption increase simply because if a control uses a certain amount of brushes, that more properties would be set. In an application that utilizes many of the control from the suite this could lead to undesired issues.

Another concern we have is for the cases where the same AccentBrush property is used for two elements. If you want to colorize those two differently, it wouldn't be possible.

Again, thank you very much for your feedback. We will keep it in mind and will continue looking for ways to make our customer's lives easier.

Regards,
Petya
Telerik
 

See What's Next in App Development. Register for TelerikNEXT.

 
0
Theodore
Top achievements
Rank 1
answered on 04 May 2015, 04:20 PM

Hello Petya,

thank you for taking the time to evaluate my suggestion. My comments on your reply are as follows:

a) For the performance issue:  The properties are attached, therefore are STATIC. That means no extra memory consumption for every control instantiation. If the user chooses NOT to use a custom color brush, he/she can leave it leave to default and not suffer any memory penalty. Otherwise, that is the cost for having awesome colorizable controls.

b) In case where e.g. AccentBrush is used in more than one element:  In case where you use the same brush in more than one part of the control template, then THAT IS OK, because that's how the theme is laid out. Still, that brush would become colorizable.

 

Please find a way to fix the situation described in my original question, because it is EXTREMELY time-consuming, counter-productive and frustrating. You can reply here if you have any news.

 

Best regards,

Theodore

 

0
Petya
Telerik team
answered on 05 May 2015, 04:12 PM
Hello Theodore,

I certainly understand your point and as I mentioned, we will continue looking for ways to improve the components in the suite. For the time being we are not considering this particular solution, though.

In regard to the performance issue I mentioned, all those properties would still need to be set initially for the mechanism to work, so the performance hit will occur regardless if  the users choose to adopt this approach or not. 

Your feedback has been noted, but at this point I couldn't say when and what solution precisely might be introduced.

Regards,
Petya
Telerik
 

See What's Next in App Development. Register for TelerikNEXT.

 
Tags
General Discussions
Asked by
Theodore
Top achievements
Rank 1
Answers by
Vanya Pavlova
Telerik team
Theodore
Top achievements
Rank 1
Petya
Telerik team
Share this question
or