Subclassing and restyling DataGrid?

Jan 8, 2009 at 9:09 AM
I am working on subclassing the V1 DataGrid to add some functionality that should be provided throughout the application, which is going well so far. However, I also need to slightly alter the visual appearance of the control. Specifically in this case, I want to change the control template for a selected but not-in-edit-mode cell. In order to do that, I added a "Resource" file named themes\general.xaml (as per "Programming WPF", 2nd edition page 675 "default styles") and then added the following code to the end of my subclass' static constructor:

namespace MyNameSpace
    public class DataGrid : Microsoft.Windows.Controls.DataGrid
        static DataGrid()
                new FrameworkPropertyMetadata(typeof(MyNameSpace.DataGrid)));

However, when I took my changes out of the base control's control template, depending on whether I override the DefaultStyleKeyProperty in the constructor, I end up with either a control with no visual appearance, or one that simply inherits the visual appearance of the base control (which is to be expected with no override). Here is the content of my project's themes\generic.xaml; this particular combination of code results in no visual appearance of the DataGrid. Am I missing some obvious step?

<?xml version="1.0" encoding="utf-8" ?>
<ResourceDictionary xmlns=""
    <Style x:Key="{x:Type local:DataGrid}" TargetType="{x:Type local:DataGrid}" BasedOn="{x:Type dg:DataGrid}" />
    <Style x:Key="{x:Type local:DataGridCell}" TargetType="{x:Type dg:DataGridCell}" BasedOn="{x:Type dg:DataGridCell}">
            <Trigger Property="IsSelected" Value="True">
                <Setter Property="BorderThickness" Value="3.5" />

Many thanks in advance for any insights you may be able to provide.
Jan 9, 2009 at 12:25 PM
I managed to somewhat work around this issue by changing the CellStyle property in the instance constructor of my subclassed DataGrid. (I'm including an example below.) However, I would still like to do this in XAML if possible, to keep a clear separation between logic and UI. Is that doable and if so, what would be a recommended approach?

        public DataGrid() : base()
            Trigger trigger = new Trigger()
                Property = DataGridCell.IsSelectedProperty,
                Value = true
            trigger.Setters.Add(new Setter()
                Property = DataGridCell.BackgroundProperty,
                Value = System.Windows.Media.Brushes.Yellow // make it obvious
            this.CellStyle = new Style(typeof(DataGridCell));
Jan 10, 2009 at 2:02 PM
For what you've shown here, I believe you should remove "DefaultStyleKeyProperty.OverrideMetadata...", and add following setter to your style, outside Style.Triggers:
<Setter Property="OverridesDefaultStyle" Value="True" />
That should do the trick.

If you are determined to use static constructor containing "DefaultStyleKeyProperty.OverrideMetadata..." you must provide the entire ControlTemplate for your control.
In this case you want only to override BorderThickness, property that can be set for any control without using ControlTemplate.

Let me know if this was of any use to you.


Darko Antanasijevic