Выделите или нарисуйте любой элемент UIElement в слое adorner - PullRequest
2 голосов
/ 24 января 2011

Я хотел бы иметь возможность каким-то образом обрисовать в общих чертах или выделить любой конкретный UIElement (или, возможно, даже Visual) в слое рекламного элемента.Adorner не является проблемой как таковой.Меня больше беспокоит создание контура UIElement.

. Я стремлюсь к аналогичному эффекту, который обеспечивает OuterGlowBitmapEffect.Я хочу следовать внешнему контуру UIElement.Я перепробовал много подходов к исследованию свойства Clip (почти всегда нулевого) и некоторых других методов, но с треском провалился.

Теперь я думаю, что это должно быть легко, просто я что-то упустилКроме того, на этот раз Google не был моим другом.

РЕДАКТИРОВАТЬ: NET 3.5 является обязательным требованием

Ответы [ 2 ]

4 голосов
/ 25 января 2011

Вы можете использовать OpacityMask с VisualBrush с его Visual, установленным для элемента, контур которого вы хотите.Вот пример, где у нас есть Rectangle на переднем плане и TabControl на заднем плане.Поскольку элемент управления вкладками не является прямоугольным, мы можем увидеть, работает ли этот метод:

<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>

Результат выглядит следующим образом:

Visual Outline of a Control

Только элемент управления вкладкамии заголовок его вкладки подсвечиваются.

1 голос
/ 25 января 2011

Один из способов - переопределить OnRender UIElement, как показано в примере MSDN SimpleCircleAdorner .

  // 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);
  }
}

Если вы хотите обеспечить надежное решение вне типичного прямоугольника или скругленного прямоугольника, вам придется использовать геометрию пути , которая позволит вам построить путь, состоящий из сегментов, таких как BezierSegment, LineSegment или ArcSegment, создавая соответствующий путь вокруг UIElement.

Если с другой стороны достаточно прямоугольника или скругленного прямоугольника, вы можете использовать DrawingContext.DrawRectangle и DrawingContext.DrawRoundedRectangle соответственно в пределах OnRender переопределения.

...