🚀 Welcome to MDriven Learn –  MDriven is now on Discord!  Don’t miss the latest Release Notes.
Styling WPF Applications and ViewModels
This page was created by Alexandra on 2017-11-09. Last edited by Wikiadmin on 2026-07-29.

You can style a WPF application generated from a declarative ViewModel by placing named WPF resources in a XAML ResourceDictionary and referring to their names from ViewModel columns.

What this page covers

This page describes styling for the WPF runtime that renders ViewModels. It covers:

  • Application and window resources, such as backgrounds and the main menu.
  • Styles selected by a ViewModelColumn StyleRef.
  • Binding format strings selected by a ViewModelColumn StyleRef.
  • DataGrid styles for an individual column and for a whole grid.

A ViewModel keeps business logic and UI intent separate. Your ResourceDictionary supplies the WPF presentation: fonts, colors, margins, templates, and other WPF style settings. This lets a WPF designer change the appearance without changing the ViewModel logic.

Create and load a style dictionary

A WPF ResourceDictionary is a XAML file that contains reusable resources, including Style, Brush, and String resources. Create the dictionary with a WPF design tool, a text editor, or another XAML editor.

  1. Create a XAML ResourceDictionary containing the resources you need.
  2. Put the dictionary in the ECO Config folder.
  3. Start the WPF runtime.
  4. Select the dictionary from the runtime style menu.

When you select a style, the runtime loads that dictionary and merges it with the application resources. Resource keys are therefore the contract between the ViewModel-driven WPF UI and your XAML.

Style at the right scope

Use the smallest scope that expresses your intent. For example, use an application resource for a consistent menu appearance, a column style for an important value in one grid, and a format string when only the displayed value format needs to change.

Scope Use it for Example resource key
Application or window Shared window surfaces and main-menu appearance WECPOFWinBackgroundBrush
ViewModelColumn control The controls generated for one column with a specified StyleRef Style1.TextBox
ViewModelColumn binding Text formatting for values in a column with a specified StyleRef FormatDate.StringFormat
Individual DataGrid column A distinct header or cell appearance for one grid column StyleOnColumn.HeaderStyle.DataGridTextColumn
Whole DataGrid Default headers, rows, or cells for all columns in a grid StyleOnColumn.RowStyle.DataGrid

Application and window resources

The runtime recognizes named resources for common application surfaces. Define only the resources you want to override.

Resource key Applies to
WECPOFWinBackgroundBrush The background of one window.
WECPOFWinContentBackgroundBrush The content area of one window.
WECPOFWindowEnvironmentBackgroundBrush The containing, or master, window.
WECPOFWINHeaderStyle The window header.
WECPOFMenuStyle The main menu.
WECPOFMenuItemStyle Menu items.

For example, the following resources give the window, its content area, and its containing window separate backgrounds. The header, menu, and menu items receive their own styles.

<!-- Background of a single window -->
<LinearGradientBrush x:Key="WECPOFWinBackgroundBrush"
                     StartPoint="0,0" EndPoint="0,1">
  <GradientStop Color="#eae" Offset="0.0" />
  <GradientStop Color="#777" Offset="1.0" />
</LinearGradientBrush>

<!-- Background of the content area of a single window -->
<LinearGradientBrush x:Key="WECPOFWinContentBackgroundBrush"
                     StartPoint="0,0" EndPoint="0,1">
  <GradientStop Color="#aea" Offset="0.0" />
  <GradientStop Color="#777" Offset="1.0" />
</LinearGradientBrush>

<!-- Background of the containing (master) window -->
<SolidColorBrush x:Key="WECPOFWindowEnvironmentBackgroundBrush"
                 Color="Coral" />

<!-- Style used for the window header -->
<Style x:Key="WECPOFWINHeaderStyle" TargetType="{x:Type TextBlock}">
  <Setter Property="Foreground" Value="Snow" />
  <Setter Property="Margin" Value="2,0,2,0" />
  <Setter Property="FontSize" Value="20" />
  <Setter Property="FontWeight" Value="ExtraBold" />
</Style>

<!-- Style used for the main menu -->
<Style x:Key="WECPOFMenuStyle" TargetType="{x:Type Menu}">
  <Setter Property="Background" Value="{StaticResource MenuBackground}" />
</Style>

<!-- Style used for menu items -->
<Style x:Key="WECPOFMenuItemStyle" TargetType="{x:Type MenuItem}">
  <Setter Property="Background" Value="Black" />
  <Setter Property="Foreground" Value="White" />
</Style>

The WECPOFMenuStyle example refers to a resource named MenuBackground. Define that resource in the same dictionary, or replace the reference with a value or resource that exists in your dictionary.

Style controls generated for a ViewModelColumn

Set a ViewModelColumn's StyleRef to select styles for controls generated from that column. A column can generate more than one WPF control. For example, the runtime can use a TextBlock for display and a TextBox for editing.

For a StyleRef named Style1, define styles with this naming convention:

STYLENAME.COMPONENTTYPE

The component type is the WPF control type name. The following example applies a large font to both the display and edit controls generated for a column whose StyleRef is Style1.

<!-- Display part of a ViewModelColumn with StyleRef Style1 -->
<Style x:Key="Style1.TextBlock" TargetType="{x:Type TextBlock}">
  <Setter Property="FontSize" Value="36" />
</Style>

<!-- Edit part of a ViewModelColumn with StyleRef Style1 -->
<Style x:Key="Style1.TextBox" TargetType="{x:Type TextBox}">
  <Setter Property="FontSize" Value="36" />
</Style>

Use the same StyleRef on columns that should share an appearance. Use a different StyleRef when one column needs a distinct treatment. For example, give a status column a StyleRef of Status and define Status.TextBlock without changing the editing style of unrelated columns.

Format values with StringFormat resources

A WPF binding can use a StringFormat to control how it displays a value. This is useful for values such as dates, percentages, and numeric values where the underlying value must remain unchanged.

To provide a format for a ViewModelColumn:

  1. Set the column's StyleRef to a style name, such as FormatDate.
  2. Add a string resource whose key is STYLENAME.StringFormat.
  3. Select the style dictionary in the runtime and verify the rendered value.

For example:

<!-- Numeric format for a column with StyleRef StyleNumber2Dec -->
<sys:String x:Key="StyleNumber2Dec.StringFormat">{0:n}</sys:String>

<!-- Date format for a column with StyleRef FormatDate -->
<sys:String x:Key="FormatDate.StringFormat">ddd d MMM</sys:String>

In this example, a column with StyleRef FormatDate displays a date such as Mon 7 Jun. A column with StyleRef StyleNumber2Dec uses the numeric format defined by its resource.

Define a default format by type

You can also define a format that applies to unstyled values of a simple type. Use the type name as the resource-key prefix. For example, this resource supplies a default display format for DateTime values:

<sys:String x:Key="DateTime.StringFormat">yyyy-MM-dd HH:mm</sys:String>

This type-based convention can be used for simple types such as double, float, and bool. It does not apply to string.

Style DataGrid columns precisely

A DataGrid supports styling at both grid and column level. Use a column-level style when one column must stand out. Use a DataGrid-level style when all headers, rows, or cells should have the same default appearance.

For a ViewModelColumn with StyleRef StyleOnColumn, use these resource-key patterns:

Resource key pattern Applies to
STYLENAME.HeaderStyle.DataGridTextColumn The header of that DataGrid text column.
STYLENAME.CellStyle.DataGridTextColumn The cells of that DataGrid text column.
STYLENAME.ColumnHeaderStyle.DataGrid Default column headers in the DataGrid.
STYLENAME.RowStyle.DataGrid Rows in the DataGrid.
STYLENAME.CellStyle.DataGrid Default cells in the DataGrid.

The following example makes one text-column header green, its cells yellow, and also defines default grid styles. The XML namespace prefixes such as prim, tk, and tkPrimitives must resolve to the corresponding DataGrid types in your dictionary.

<!-- Header of a DataGrid text column with StyleRef StyleOnColumn -->
<Style x:Key="StyleOnColumn.HeaderStyle.DataGridTextColumn"
       TargetType="{x:Type prim:DataGridColumnHeader}">
  <Setter Property="Height" Value="30" />
  <Setter Property="Background" Value="Green" />
  <Setter Property="Foreground" Value="Black" />
  <Setter Property="FontSize" Value="28" />
</Style>

<!-- Cells of that DataGrid text column -->
<Style x:Key="StyleOnColumn.CellStyle.DataGridTextColumn"
       TargetType="{x:Type tk:DataGridCell}">
  <Setter Property="Height" Value="30" />
  <Setter Property="Background" Value="Yellow" />
  <Setter Property="Foreground" Value="Black" />
  <Setter Property="FontSize" Value="18" />
</Style>

<!-- Default style for all DataGrid column headers -->
<Style x:Key="StyleOnColumn.ColumnHeaderStyle.DataGrid"
       TargetType="{x:Type tkPrimitives:DataGridColumnHeader}">
  <Setter Property="Height" Value="20" />
  <Setter Property="Background" Value="Yellow" />
  <Setter Property="Foreground" Value="Green" />
  <Setter Property="FontSize" Value="16" />
</Style>

<!-- Default style for DataGrid rows -->
<Style x:Key="StyleOnColumn.RowStyle.DataGrid"
       TargetType="{x:Type tk:DataGridRow}">
  <Setter Property="Height" Value="20" />
  <Setter Property="Foreground" Value="Green" />
  <Setter Property="FontSize" Value="16" />
</Style>

<!-- Default style for DataGrid cells -->
<Style x:Key="StyleOnColumn.CellStyle.DataGrid"
       TargetType="{x:Type tk:DataGridCell}">
  <Setter Property="Height" Value="20" />
  <Setter Property="Background" Value="Transparent" />
  <Setter Property="Foreground" Value="Blue" />
  <Setter Property="FontSize" Value="12" />
</Style>

Column-level styles let you distinguish the header from the cells. In the example, the selected column gets a 30-pixel green header and 30-pixel yellow cells, while the grid defaults remain available for the rest of the grid.

Keep styling separate from behavior

Use StyleRef and formatting resources to change presentation, not business rules. Keep data selection, validation, enablement, and other business behavior in the ViewModel. This separation allows you to reuse the ViewModel with another UI and lets designers work on WPF resources without changing application logic. See Documentation:ViewModel for Business and Training:The declarative ViewModel.

For styling buttons through ViewModel columns and expressions, see Documentation:Formatting and Styling Buttons. For a custom WPF control instead of a generated control, see HowTos:Custom Controls in ViewModel Aided Views.

See also