在形状内添加文本

时间:2010-11-15 22:58:46

标签: wpf wpf-controls

我有一个自定义WPF控件MyLine,它应该代表或不代表中间的某些文本。

public class MyLine : Shape
{   
    public double X1, Y1, X2, Y2;
    public bool IsTextDisplayed;
    public string Caption;

    protected override System.Windows.Media.Geometry DefiningGeometry
    {
        get
        {
            var geometryGroup = new GeometryGroup();

            if (IsTextDisplayed)
            {
                // calculate text point
                var midPoint = new Point((X1 + X2) / 2.0, (Y1 + Y2) / 2.0);
                // add a TextBlock with the Caption text in that point
                // ???
            }

            // Add line
            geometryGroup.Children.Add(new LineGeometry(
                new Point(X1, Y1), new Point(X2, Y2)));

            return geometryGroup;

        }
    }
}

我应该如何在这里添加一个TextBlock(或Label)?

我尝试在里面添加一个FormattedText,但这是NOK,因为它使用行胖画笔绘制文本,无法读取内容。

修改

添加可视子项

public MyLine() : base()
{
    textBlock = new System.Windows.Controls.TextBlock();
    textBlock.Visibility = System.Windows.Visibility.Hidden;
    this.AddVisualChild(textBlock);
}

protected override System.Windows.Media.Geometry DefiningGeometry
{
    get
    {
    ...

if (IsTextDisplayed)
{
    var midPoint = new Point((X1 + X2) / 2.0, (Y1 + Y2) / 2.0);
    string text = "some custom text";

    Canvas.SetLeft(textBlock, midPoint.X);
    Canvas.SetBottom(textBlock, midPoint.Y);

    textBlock.Text = text;
    this.textBlock.Visibility = System.Windows.Visibility.Visible;    
}
else 
{
    this.textBlock.Visibility = System.Windows.Visibility.Hidden;
}

我没有看到任何标签......:“/

EDIT2

添加Adorner

public MyLine() : base()
{
    this.Loaded += new RoutedEventHandler(MyLine_Loaded);
}

void MyLine_Loaded(object sender, RoutedEventArgs e)
{
    AdornerLayer aLayer = AdornerLayer.GetAdornerLayer(this);
    if (aLayer != null)
        aLayer.Add(new TextAdorner(this));        
}

class TextAdorner : Adorner
{
    public TextAdorner(UIElement adornedElement) : base(adornedElement) 
    { }

    protected override void OnRender(DrawingContext drawingContext)
    {
        MyLine segment = (this.AdornedElement as MyLine);            
        if (segment != null && segment.IsLabelUsed)
        {
            Rect segmentBounds = new Rect(segment.DesiredSize);

            FormattedText ft = new FormattedText(
                "654 m", Thread.CurrentThread.CurrentCulture,
                System.Windows.FlowDirection.LeftToRight,
                new Typeface("Arial"), 12, Brushes.White);

            drawingContext.DrawText(ft, segmentBounds.BottomRight);
        }
    }
}

现在,显然代码永远不会进入OnRender adorner方法......

2 个答案:

答案 0 :(得分:2)

如果您不希望文本显示在与该行相同的画笔中,您可能不希望使用Shape作为基类,因为从{{返回Geometry 1}}在一个画笔中呈现。如果您确实希望使用DefiningGeometry作为基类,则可能希望将文本添加为​​可视子项,而不是将其添加到现有Shape

如果您不打算使用其中的大量产品,并且能够承受轻量级容器,我建议您只创建一个基于Geometry的控件,其中包含此UserControl您在Shape上创建了文本元素,如TextBox(用于绝对定位)。同样,如果您拥有数百或数千个,这不是一个很好的解决方案,但如果您只有数十个,那么它可能是最简单,最快捷的解决方案。

答案 1 :(得分:0)

我会使用装饰器在文本顶部绘制文字。

http://msdn.microsoft.com/en-us/library/ms746703.aspx