2010-11-15 58 views
2

我有一個自定義的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(或標籤)?

我試着在裏面添加一個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

添加裝飾器

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

現在,ap父母代碼永遠不會進入OnRender裝飾器方法...

+0

我希望你的畫布的backgroundColor是不是白... – VRage 2017-10-12 11:05:15

回答

2

如果您不希望文本顯示在同一個畫筆中作爲行,那麼您可能不希望使用Shape作爲基類,如從DefiningGeometry返回的Geometry呈現在一個畫筆中。如果您確實想使用Shape作爲基類,則可能希望將文本添加爲​​可視子元素,而不是將其添加到現有的Geometry

如果你不打算使用了很多這些,並且能買得起一個稍微重量級的容器,我建議乾脆創建一個包含此Shape創建,一個文本UserControl基於控制像TextBox這樣的元素在Canvas(用於絕對定位)。再次說明,如果您擁有數百或數千個解決方案,這不會是一個很好的解決方案,但如果您只有幾十個,那麼這可能是最簡單和最快捷的解決方案。

+0

我已經有一個工作邏輯與這種形狀,主要是,線移動等等。我會搜索一些有關兒童視覺...只是需要一些在所有行附近顯示(或不顯示)文本信息。 – serhio 2010-11-15 23:50:03

+0

你可以看看張貼的編輯? – serhio 2010-11-16 00:17:01

+0

如果您要使用可視化子方法,您需要的不僅僅是AddVisualChild - 奇怪的是,該方法實際上並沒有添加子對象,它只是設置父/子關係。您還需要重寫'VisualChildCount','GetVisualChild'以實際將該項目作爲子項目,並使用'ArrangeOverride'來定位元素。 – 2010-11-16 13:26:55

0

我會使用一個裝飾者來繪製文本的頂部。

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

+0

也添加了這個變體,但不能像我寫的那樣工作,請參閱我的編輯2 – serhio 2010-11-16 02:58:14

+0

你不能在構造函數中這樣做。 OnLoaded/OnApply模板是你應該在哪裏AdornerLayer.GetAdornerLayer(this) – NVM 2010-11-16 04:46:12

+0

修正了這一點,現在,顯然代碼從來沒有進入OnRender裝飾器方法...(參見編輯) – serhio 2010-11-16 10:03:05