2

I would like to be able to somehow outline or highlight any particular UIElement (or perhaps even Visual) in an adorner layer. Adorner is not a problem per se. I am more concerned about creating an outline of a UIElement.

I am aiming at a similar effect that OuterGlowBitmapEffect provides. I want to follow the outer contour of an UIElement. I have tried many approaches with examining Clip property (almost always null) and some other methods but I failed miserably.

Now I am thinking this must surely be easy it is just that I am missing something. In addition, Google was not my friend this time as well.

EDIT: NET 3.5 is a requirement

Dave Clemmer
  • 3,741
  • 12
  • 49
  • 72
wpfwannabe
  • 14,587
  • 16
  • 78
  • 129
  • Can you provide a sample of how you want the highlighting to look? Have you tried `DropShadowEffect`? – Fredrik Hedblad Jan 24 '11 at 20:58
  • See my comment to Aaron. I want to highlight the outline of the `Visual`. What I was thinking is getting a `Path` geometry of the outline and use that filled with a solid color and with animated opacity. The basis is somehow getting to the outline of *any* `Visual`. I haven't tried `DropShadowEffect`. I'd be more interested in a something that produces sort of *overlay* effect, not a shadow. – wpfwannabe Jan 24 '11 at 21:56

2 Answers2

4

You can use an OpacityMask with a VisualBrush with its Visual set to the element you want the outline of. Here's an example where we have a Rectangle in the foreground and a TabControl in the background. Since the tab control is not rectangular, we can see if the technique works:

<Grid Background="Gray">
    <TabControl Name="element">
        <TabItem Header="Tab1">
            <TextBlock Text="Hello, world!" FontSize="40" FontWeight="Bold"/>
        </TabItem>
    </TabControl>
    <Rectangle Fill="Yellow" Opacity="0.5">
        <Rectangle.OpacityMask>
            <VisualBrush Visual="{Binding ElementName=element}"/>
        </Rectangle.OpacityMask>
    </Rectangle>
</Grid>

The result looks like this:

Visual Outline of a Control

Only the tab control and its tab header are highlighted.

Rick Sladkey
  • 33,988
  • 6
  • 71
  • 95
  • I have encountered the `OpacityMask` in conjunction with `ViusalBrush` before but I have never seen a full working example. Your screenshot seems to indicate this might actually do the trick for me. Thanks a lot! – wpfwannabe Jan 25 '11 at 12:39
1

One way is to override the OnRender of the UIElement as seen in the MSDN SimpleCircleAdorner example.

  // A common way to implement an adorner's rendering behavior is to override the OnRender
  // method, which is called by the layout system as part of a rendering pass.
  protected override void OnRender(DrawingContext drawingContext)
  {
    Rect adornedElementRect = new Rect(this.AdornedElement.DesiredSize);

    // Some arbitrary drawing implements.
    SolidColorBrush renderBrush = new SolidColorBrush(Colors.Green);
    renderBrush.Opacity = 0.2;
    Pen renderPen = new Pen(new SolidColorBrush(Colors.Navy), 1.5);
    double renderRadius = 5.0;

    // Draw a circle at each corner.
    drawingContext.DrawEllipse(renderBrush, renderPen, adornedElementRect.TopLeft, renderRadius, renderRadius);
    drawingContext.DrawEllipse(renderBrush, renderPen, adornedElementRect.TopRight, renderRadius, renderRadius);
    drawingContext.DrawEllipse(renderBrush, renderPen, adornedElementRect.BottomLeft, renderRadius, renderRadius);
    drawingContext.DrawEllipse(renderBrush, renderPen, adornedElementRect.BottomRight, renderRadius, renderRadius);
  }
}

If you want to provide a robust solution outside a typical rectangle or rounded rectangle you will have to make use of path geometries which will allow you to build out a path composed of segments such as a BezierSegment, a LineSegment, or an ArcSegment thus creating an appropriate path around the UIElement.

If on the other hand a rectangle or rounded rectangle would suffice you can make use of the DrawingContext.DrawRectangle and DrawingContext.DrawRoundedRectangle respectively within the OnRender override.

Aaron McIver
  • 24,527
  • 5
  • 59
  • 88
  • +1, Thanks so much for the proposed solution. Unfortunately, what I am looking for is following the outline of the `UIElement` (or `Visual`) not just simple (rounded) rectangles. I was thinking of getting the path you are talking about, but in a programmatic manner. I want this approach to work on *any* UIElement, not some set of predefined shapes. – wpfwannabe Jan 24 '11 at 21:51