Skip to main content Skip to footer

ComponentOne WPF Easy Styling: An Alternative to Microsoft Blend

One of the key values of ComponentOne WPF Edition is its easy styling. We’ve made it easy for developers to make simple visual appearance changes without having to deal with separate designer tools like Microsoft Blend and without having to customize control templates.

You have several approaches to styling WPF controls using ComponentOne.

  1. Start by Simply Setting Brush Properties
  2. Optimize Styling with Implicit Style Support
  3. Apply One of Our Completely Designed Themes
  4. Customize a Designed Theme

You have all of these time-saving options to consider before needing to customize a control template. In this topic, we will guide you through each aspect and dive deeper into how we design our style APIs.

Ready to see all ComponentOne has to offer? Download our Free 30-day trial today!

Start by Simply Setting Brush Properties

Out of the box, ComponentOne WPF controls have a fluent style for .NET 6+ applications. This clean style provides a great look for any modern desktop application. It also acts as the perfect starting point for style customization.

We went beyond what the standard controls could do when it comes to simply setting brush properties on a control. Standard controls typically provide a Background brush, a Foreground brush, and that’s it. For simple controls, that may be enough, but for rich controls, you need a rich API of styling brushes. We designed our controls to have numerous brush properties exposed for every part of the control. We then grouped these properties into encapsulated Style objects for easy learning.

For example, you can quickly style FlexGrid’s column headers and alternating row colors by just setting a few brush properties, and the brush colors are propagated through the XAML layers.

Microsoft Blend Alternative

<c1:FlexGrid x:Name="grid" 
             ColumnHeaderFontWeight="Bold"
             ColumnHeaderBackground="#fffbdc6a"
             AlternatingRowBackground="#fffffbce"/>

Optimize Styling with Implicit Style Support

For the simplest styling, you can get by just setting a few brush properties here and there. But if your application is large or you have multiple instances of repeating controls, you should optimize your styling by taking advantage of WPF’s implicit style management.

Our WPF controls follow the same implicit style management as the standard .NET controls. An implicit Style has no key, so it applies to all instances of the target type. This means you can define common Styles and reuse them across your application. For example, you can create an implicit Style that makes all your FlexGrid’s orangey.

Microsoft Blend Alternative

Styles can include any property so that we can include heading and gridline settings in our theme, and the brushes support complex features such as patterns and gradients.

<Window.Resources>
 <Style TargetType="c1:FlexGrid" >
    <Setter Property="HeadersVisibility" Value="All"/>
    <Setter Property="ColumnHeaderFontWeight" Value="Bold" />
    <Setter Property="GridLinesVisibility" Value="Vertical" />
    <Setter Property="ColumnHeaderBackground">
        <Setter.Value>
            <LinearGradientBrush StartPoint="0,0" EndPoint="0,1" >
                <GradientStop Color="#fffbdc6a" Offset="0"/>
                <GradientStop Color="#fffbc711" Offset="0.5"/>
                <GradientStop Color="#ffdfb72d" Offset="1"/>
            </LinearGradientBrush>
        </Setter.Value>
    </Setter>
    <Setter Property="ColumnHeaderForeground" Value="#ff444444" />
    <Setter Property="RowHeaderBackground" >
        <Setter.Value>
            <LinearGradientBrush StartPoint="0,0" EndPoint="1,0" >
                <GradientStop Color="#fffbdc6a" Offset="0"/>
                <GradientStop Color="#fffbc711" Offset="0.5"/>
                <GradientStop Color="#ffdfb72d" Offset="1"/>
            </LinearGradientBrush>
        </Setter.Value>
    </Setter>
    <Setter Property="RowHeaderForeground" Value="#ff444444" />
    <Setter Property="AlternatingRowBackground" Value="#fffffbce" />
    <Setter Property="Foreground" Value="#ff000000" />
    <Setter Property="GridLinesBrush" Value="#ffc9caca" />
 </Style>
</Window.Resources>

Implicit styling makes it easy to customize any standard or ComponentOne WPF control’s appearance without learning another approach for creating themes. Where you define the implicit style impacts the scope. Defining it within a Window’s resources will apply to all FlexGrid’s in that Window. If you place it in the App.xaml file’s resources, it will apply everywhere across the application.

With an abundance of brush and other appearance-related properties, including text, borders, and gridlines, you may not need anything else to completely style your application.

Apply One of Our Completely Designed Themes

Alternative to the solutions described above, a built-in theme allows you to style the entire application in one fell swoop. With ComponentOne WPF Edition, we provide 20+ professional themes that provide a great way to quickly apply a specific look to an entire control or entire application with just one line of code.

Microsoft Blend Alternative

We’ve written about the themes in more detail before, so check out How to Add WPF Themes to Style Your Desktop Applications.

Customize a Designed Theme

We’ve simplified theme customization for our WPF controls by supporting simple theme customization for our new .NET 6+ material theme.

We designed our material theme following best practices defined by Material.io. By customizing our WPF material theme, you can choose a light or dark background and add a pop of accent color to match your application or company branding. Our WPF material theme even supports standard .NET controls.

Microsoft Blend Alternative

We've also written about customizing the material theme here: How to Create a Custom WPF Material Theme.

Why Easy Styling Is Important

The four sections above have detailed the full scale of the easy style and customization in our WPF controls. The rest of this blog will dive deeper into the background behind these decisions and the guiding principles we used when designing our controls.

---

XAML is a very powerful and flexible markup language that allows us to do incredible things. But this incredible flexibility can sometimes lead to chaos because the cost of flexibility is complex. While complexity can sometimes be a good thing, the complication is never. With that in mind, we implemented a range of style-supported features to help developers keep the complication out of their complex user interfaces.

Whether you are working in WPF, UWP, WinUI, or any other XAML-based platforms, you likely have experienced the need to make a simple visual appearance change to a control. Say, for instance, that you wanted to change the color of just the header portion of the scheduler’s day slot. The easiest way to solve this is for the control to have an exposed brush such as “DaySlotHeaderBackground”.

But that’s not all. Some complex controls with specific styles utilize gradients in their default appearance, so it’s not so easy to just set the background. You would want the background brush to cascade through the layers. This was especially true for our older WPF and Silverlight controls, as seen in the C1Scheduler control below:

Microsoft Blend Alternative

Every control is composed of multiple elements layered on top of one another. Think of a control containing multiple layers like the following diagram.

Microsoft Blend Alternative

It would not be practical to have an exposed Brush property for each layer. If you need complete control over each layer, you need to customize the XAML template.

For ComponentOne, we do provide complete XAML control templates as part of the installation. The pain point is that XAML templates contain hundreds of lines of markup, they’re easy to break, and the debugging capabilities are not the same as C# or VB compilers. Suppose you find yourself working with over 600 lines of XAML just to change a background color that quickly becomes problematic from a maintenance standpoint. Spaghetti XAML is more like it!

We do not recommend that you customize control templates in XAML. Maintaining a template for a standard control that Microsoft only updates every couple of years is one thing. For us at GrapeCity, this is a bigger issue because we release updates for our controls up to three times a year. With each release, we add features and functionality that users demand. These enhancements don’t break backward compatibility regarding programmatic API. However, every new bell and whistle requires changes to the template to define that bell or whistle’s appearance. Basically, changes to XAML templates are unavoidable in a custom control. So a solution to this problem was very important to ease the usability of our controls. The end result of our easy styling features makes everyone’s lives easier.

Principles and Goals

A lot of thought and consideration went into the implementation of our WPF controls. For each control, we wanted to find the perfect balance between an organized, clean API and one that could be easily styled without getting into control templates. That is a challenging task because each control part can have many appearance-related attributes aside from just a background color. In addition to making things easier for developers, another key goal was to empower developers to be less reliant on graphic designers.

So we set the following four principles for appearance customization scenarios.

  • Simple changes should be simple
  • Detailed changes should be simple enough
  • Cascade appearance properties were logical
  • The option for full redesign should always be available

Simple changes should be simple

We think small appearance changes should be done by anyone without needing a tool. For example, the Background property should be honored by all controls in a smart way. We leveraged this kind of simple change principle so you can quickly and easily style complex controls like our FlexGrid, where the background is not just applied to the area behind the rows.

Microsoft Blend Alternative

Detailed changes should be simple enough

Since we develop a lot of complex controls that have a lot of working parts, we wanted to make sure that detailed changes to each part would be simple. But there had to be balance. It’s not practical to expose everything as properties to make them easily changeable. It goes against the look-less principle of WPF and other XAML-based platforms, and it would also result in a very messy public API. Consider a property like MouseOverHeaderBorderBrush that changes the appearance of the header’s border when the mouse hovers over the control. It’s very niche! In most common scenarios, that property would not be worth having.

We weighed the usefulness along with a bit of design knowledge and common sense to determine the appropriate properties to expose for each control. We organized it a bit further and provided Style properties for the different parts of the control and brushes for the more outstanding parts. Using this combination, we give the flexibility to style every part of the control using the Style properties while keeping the API simple for developers using brushes properties.

For example, our FlexGrid control exposes the following Style properties that contain the relevant brushes for each part of the control (background, foreground, etc.):

  • AlternatingRowStyle
  • ColumnHeaderStyle
  • ErrorStyle
  • GroupRowStyle
  • NewRowStyle
  • PopupStyle
  • RowHeaderStyle
  • RowStyle
  • SelectionStyle
  • TopLeftHeaderStyle

Here’s an example of how you can set one of these styles in line. Of course, you can also apply this within a reusable Style resource, as demonstrated earlier with implicit styling.

<c1:FlexGrid x:Name="grid">
    <c1:FlexGrid.ColumnHeaderStyle>
        <Style TargetType="c1:GridColumnHeaderCell">
            <Setter Property="Background" Value="#fffbdc6a" />
            <Setter Property="Foreground" Value="#ff094475" />
            <Setter Property="FontWeight" Value="Bold" />
        </Style>
    </c1:FlexGrid.ColumnHeaderStyle>
</c1:FlexGrid>

XAML Tip: Foreground typically applies to all text.

Microsoft Blend Alternative

It’s not an abusive amount of properties, but it’s enough to make detailed changes in a simple way. Some appearance-related properties are not encapsulated within a Style property as well - it really just depends on how complex the control part is. For example, with FlexGrid, the MouseOverBrush applies a transparent color over the row and did not need over-engineered.

Cascade appearance properties when logical

Another key point of making styling easier is carrying a style setting throughout a control's children. The properties in some controls should propagate from the outer controls to the inner ones. For example, you don’t want to set the Background in the C1Menu control and then again in every C1MenuItem element. You want to set it once and let inner controls adopt the same style.

The option for full redesign should always be available

Providing an easy alternative to generating templates and styles seems to be great, but there will always be some disadvantages and limitations. For example, exposing a Brush property for an object lets you easily change its color. However, it does not handle setting a different pattern or shape for that object. Therefore, the option for full redesign should still be available for less common cases. That means everything should not only support a simple Brush property, but its template should also be completely styleable. We’ve made sure to keep all ComponentOne controls standardized so they also work completely like standard controls.

Introducing Microsoft Blend for Visual Studio

When the first XAML platforms were born, Microsoft introduced a separate IDE for styling markup files called Expression Blend. Since 2012, Blend has since been incorporated into Visual Studio as a separate SDK. This introduces a challenge for developers who are not familiar with Blend and do not have the time to download and learn a new approach. You could hire a graphic designer, which adds to the budget and communication costs.

With ComponentOne's easy styling, the most practical use cases are brought to you in Visual Studio in the most intuitive manner possible. In most situations, you want to make simple styling changes, so the process should be as simple as you would expect.

Consider the time it takes to set a few properties in the above examples compared to customizing a giant control template.

Conclusion

Easy styling is a key feature found in all ComponentOne WPF, UWP, and other XAML controls (such as WinUI and MAUI). Whether you’re a developer or even a designer, you can benefit from using ComponentOne controls. These are the key takeaways:

  • Styling is simple and intuitive. It’s not difficult to set several Brush properties on a control; it’s second nature if you are familiar with Visual Studio. You can even create an implicit style resource that applies these simple Brush properties to all instances of a control for even more efficient designing
  • Detailed changes are possible and easy because complex controls have more available brushes in addition to the usual Background and Foreground properties. In most standard controls, these are the only two brushes you can set, and they will not handle all states and parts of the control in all cases
  • The option for full re-design is still there, as our themes and implicit styling don’t interfere with the standard approach of modifying control templates. ComponentOne aims to be a quick solution to simple, common design needs
  • Theme controls without needing the Blend SDK, or if you still decide to use Blend, then styling the controls is still easier than other third-party controls and even standard ones

Ready to see all ComponentOne has to offer? Download our Free 30-day trial today!

comments powered by Disqus