wpfcontroltemplate

WPF control template control nesting vs Grid


I'm writing custom control templates for WPF and using default control templates as starter.

When content presenter needs to have some background or foreground or outer border, it is often combined with Border control where color properties are set. I found two approaches used in default templates (published on MSDN):

<ControlTemplate TargetType="{x:Type ControlType}">
    <Grid>
        <Border Background="{TemplateBinding Background}"/>
        <ContentPresenter/>
    </Grid>
</ControlTemplate>

This would place some background behind content presenter. However, I can get rid of Grid and place content presenter inside border:

<ControlTemplate TargetType="{x:Type ControlType}">
    <Border Background="{TemplateBinding Background}">
        <ContentPresenter/>
    </Border>
</ControlTemplate>

Same behavior, minus Grid control. I tend to use 2nd approach just because I get rid of extra control (especially Grid which is computationally somewhat expensive). Are they equivalent? Or I'm missing something and 2nd approach has some drawbacks?


Solution

  • They are not equivalent.

    For example, the only part of a border which will be detected when hit testing is the borderlines themselves unless the border has a background (transparent is acceptable here), or hit testable content.

    If we added a trigger to Border to react to IsMouseOver when true then if the ContentPresenter is outside of the Border it will not trigger regardless of the ContentPresenter content. If the ContentPresenter is inside of the Border then providing the ContentPresenter content is both filling the region where the mouse cursor is hovering over, and is hit testable, then it will trigger. This scenario assumes we are not setting a background.

    This is the only difference that springs to mind, and it's what I would consider a minor one. I assume there are more, though I doubt anyone will/has done a deep dive into them.

    Furthermore this assumes we modify the Border to add said trigger. If we are talking about any differences without modification of the original code, then I can't give you a concrete answer here - I'd suspect there to be none, though.

    I have assumed we are not modifying any of the Border properties. Though, if we were to do this, then adding a BorderThickness which is greater than 0 would be a stand out difference as the content in the non nested version would have the potential to overlap the borderline.