tags:

views:

167

answers:

3

What I'm attempting to do is wrap a control in a border without changing it's default appearance, and also without having to create custom controls.

I'd like to do the equivalent of this:

<Border BorderBrush="Red" BorderThickness="3">
  <Button>Hello!</Button>
</Border>

Just to any control, without actually having to wrap everything in a Border. I attempted to do this by modifying the Template in a style with the following:

<ControlTemplate TargetType="{x:Type Button}">
  <Border BorderBrush="Red" BorderThickness="3">
    <ContentPresenter />
  </Border>
</ControlTemplate>

This successfully adds a border, but also wipes out any other style on the Button. I'd like it to still look like a button, just with an extra border around it.

Any thoughts?

+1  A: 

Styles can inherit (using the BasedOn property), but you're dealing with the template so you'd need to grab a copy of the current button template and edit your own copy of that. Options for doing this are:

Rob Fonseca-Ensor
That's something I'm trying to avoid having to do, as the feature would effectively require me to completely recreate the template of every control.
James Gregory
Any time that you "skin" an application, you unfortunately do have to recreate every single control :(just to check: is your real-world requirement that every single "control" gets wrapped in a red border? Is this for debugging purposes?You could probably write some code that iterates over your logical tree and adds an Adorner (http://msdn.microsoft.com/en-us/library/ms743737.aspx) to each item
Rob Fonseca-Ensor
+2  A: 

Is it for validation? One good option is to draw the border on the Adorner layer.

LBugnion
I didn't know about Adorners, this could be just what I need.
James Gregory
+1!James, even though I suggested Adorners in my comment first, you should mark this one as your "answer" so that it helps other people with the same questions.
Rob Fonseca-Ensor
I ended up using an attached property to identify which elements needed the highlighting, then the Adorner layer for the highlighting itself. Good tip, thanks.
James Gregory
A: 

My assumptions:

  1. I can't mess with the default control templates
  2. All I want to do is wrap a control in a border
  3. That control can be any type of control in any type of situation

My solution is to use an attached dependency property. Upon setting the property you get the parent from the Logical Tree. We then swap out the child with a child wrapped in a border.

Naturally you can extend this further for different parents.

solution at GitHub is at http://github.com/RookieOne/WrapControlInBorder

Here is a small code snippet:

            var parent = LogicalTreeHelper.GetParent(elementToWrap);

        var panel = parent as Panel;
        if (panel != null)
        {
            panel.Children.Remove(elementToWrap);
            var border = Wrap(elementToWrap);
            panel.Children.Add(border);
            return;
        }

        var contentParent = parent as ContentControl;
        if (contentParent != null)
        {
            contentParent.Content = null;
            var border = Wrap(elementToWrap);
            contentParent.Content = border;
            return;
        }
JB