Доступ к AdornerPanel из AdornerLayout или Adorner или украшенного элемента управления? - PullRequest
3 голосов
/ 09 января 2012

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

Это создание оформления (проблема не в этом коде):

public void AddLabelDecoration()
{
    AdornerLayer adornerLayer = AdornerLayer.GetAdornerLayer(this);

    TextBlock textBlockMarkTooltipContent = new TextBlock();
    textBlockMarkTooltipContent.Text = "Test Label Adorner";

    _labelAdornerMarkTooltipContentAdorner = new Adorner(this)
    {
        Child = textBlockMarkTooltipContent 
    };

    adornerLayer.Add(_labelAdornerMarkTooltipContentAdorner);
}

Чего я не могу добиться, так это позиционирования Украшения над украшенным контролем. Я хотел бы использовать этот пример кода MSDN , который использует AdornerPanel для позиционирования ...

Однако я не выяснил, как получить доступ к объекту AdornerPanel, чтобы применить этот пример кода MSDN ... ни из моего украшенного элемента управления, ни из AdornedLayout, ни из Adorner ...

Признаюсь, я не совсем понимаю иерархию классов WPF между AdornerPanel и AdornerLayout.

Любая помощь приветствуется.

Ответы [ 2 ]

3 голосов
/ 09 января 2012
public void AddLabelDecoration()
{
    AdornerLayer adornerLayer = AdornerLayer.GetAdornerLayer(this);

    TextBlock textBlockMarkTooltipContent = new TextBlock();
    textBlockMarkTooltipContent.Text = "Test Label Adorner";

    AdornerPanel labelAdornerAdornerPanel = new AdornerPanel();

    // add your TextBlock to AdornerPanel
    labelAdornerAdornerPanel.Children.Add(textBlockMarkTooltipContent);

    // set placements on AdornerPanel
    AdornerPlacementCollection placement = new AdornerPlacementCollection();
    placement.PositionRelativeToAdornerHeight(-1, 0);
    placement.PositionRelativeToAdornerWidth(1, 0);
    AdornerPanel.SetPlacements(labelAdornerAdornerPanel, placement);

    // create Adorner with AdornerPanel inside
    _labelAdornerMarkTooltipContentAdorner = new Adorner(this)
    {
        Child = labelAdornerAdornerPanel
    };

    adornerLayer.Add(_labelAdornerMarkTooltipContentAdorner);
}
3 голосов
/ 09 января 2012

Чтобы переместить Adorner, вы должны переопределить метод ArrangeOverride и отрегулировать там новую позицию Adorner.

Вот пример с простым FrameworkElementAdorner.

  public class FrameworkElementAdorner : Adorner
  {
    private FrameworkElement _child;

    public FrameworkElementAdorner(UIElement adornedElement)
      : base(adornedElement)
    {
    }

    protected override int VisualChildrenCount
    {
      get { return 1; }
    }

    public FrameworkElement Child
    {
      get { return _child; }
      set
      {
        if (_child != null)
        {
          RemoveVisualChild(_child);
        }
        _child = value;
        if (_child != null)
        {
          AddVisualChild(_child);
        }
      }
    }

    protected override Visual GetVisualChild(int index)
    {
      if (index != 0) throw new ArgumentOutOfRangeException();
      return _child;
    }

    protected override Size MeasureOverride(Size constraint)
    {
      _child.Measure(constraint);
      return _child.DesiredSize;
    }

    protected override Size ArrangeOverride(Size finalSize)
    {
      // Adjust your offset here:
      _child.Arrange(new Rect(new Point(-20, -20), finalSize));
      return new Size(_child.ActualWidth, _child.ActualHeight);
    }

Использование:

  TextBlock textBlockMarkTooltipContent = new TextBlock();
  textBlockMarkTooltipContent.Text = "Test Label Adorner";

  var adorner = new FrameworkElementAdorner(this)
  {
    Child = textBlockMarkTooltipContent
  };
...