2010-01-05 14 views
5

में माता-पिता के आयामों के सापेक्ष पोजिशनिंग एडोर्नर मैं सजे हुए तत्व के माता-पिता के आयामों के आधार पर एक एडॉर्नर को स्थान देने की कोशिश कर रहा हूं। उदाहरण के लिए, मेरे पास एक टेक्स्टबॉक्स है। मैं इस टेक्स्ट बॉक्स सजाना तो यह कुछ इस तरह दिखता हैं:डब्ल्यूपीएफ

how the adorner needs to be placed http://img707.imageshack.us/img707/9840/fig1.png

एक पाठ बॉक्स एक कैनवास वस्तु में रखा गया है और वहाँ है अगर पर्याप्त स्थान उपलब्ध है तो लाइन में adorner (अर्ध पारदर्शी गोल वर्ग) के साथ जगह टेक्स्टबॉक्स के नीचे किनारे। जब उपयोगकर्ता टेक्स्टबॉक्स पर क्लिक करता है तो सजावट शुरू की जाती है।

वर्तमान में कैनवास और इसकी सामग्री (टेक्स्टबॉक्स) को WinForms फॉर्म में होस्ट किया गया है - इसलिए WPF को ElementHost नियंत्रण द्वारा नियंत्रित किया जाता है।

लेकिन जब मैं अपना कोड चलाता हूं, जब टेक्स्टबॉक्स पहली बार क्लिक किया जाता है तो यह टेक्स्टबॉक्स के शीर्ष किनारे पर गठबंधन करने वाले एडोर्नर को प्रदर्शित करता है (नीचे चित्र देखें)। उसके बाद यह स्वयं को सही ढंग से स्थिति देता है (उपरोक्त आंकड़े की तरह) क्या कोई जानता है कि यह क्यों हो सकता है?

how adorner is positions http://img14.imageshack.us/img14/4766/fig2v.png

लिए मैंने नीचे कोड चिपकाया है:

TextBoxAdorner.cs - इस adorner तर्क

public class TextBoxAdorner : Adorner 
{ 
    private TextBox _adornedElement; 
    private VisualCollection _visualChildren; 
    private Rectangle _shape; 
    private Canvas _container; 
    private Canvas _parentCanvas; 

    public TextBoxAdorner(UIElement adornedElement, Canvas parentCanvas) 
     : base(adornedElement) 
    { 
     _adornedElement = (TextBox)adornedElement; 
     _parentCanvas = parentCanvas; 
     _visualChildren = new VisualCollection(this); 

     _container = new Canvas(); 

     _shape = new Rectangle(); 
     _shape.Width = 100; 
     _shape.Height = 80; 
     _shape.Fill = Brushes.Blue; 
     _shape.Opacity = 0.5; 

     _container.Children.Add(_shape); 

     _visualChildren.Add(_container); 
    } 

    protected override Size ArrangeOverride(Size finalSize) 
    { 
     Point location = GetLocation(); 
     _container.Arrange(new Rect(location, finalSize)); 

     return finalSize; 
    } 

    private Point GetLocation() 
    { 
     if (_parentCanvas == null) 
      return new Point(0, 0); 

     Point translate; 
     double xloc = 0, yloc = _shape.Height - _adornedElement.ActualHeight; 

     if (yloc < 0) // textbox is bigger than the shape 
      yloc = 0; 
     else 
     { 
      translate = this.TranslatePoint(new Point(0, -yloc), _parentCanvas); 

      // coordinate is beyond the position of the parent canvas 
      if (translate.Y < 0) // this is true the first time it's run 
       yloc = 0; 
      else 
       yloc = -yloc; 
     } 

     translate = this.TranslatePoint(new Point(_shape.Width, 0), _parentCanvas); 

     // textbox is in right edge of the canvas 
     if (translate.X > _parentCanvas.ActualWidth) 
     { 
      double pos = translate.X - _parentCanvas.ActualWidth; 

      translate = this.TranslatePoint(new Point(-pos,0), _parentCanvas); 

      if (translate.X < 0) 
       xloc = 0; 
      else 
       xloc = translate.X; 
     } 

     return new Point(xloc, yloc); 
    } 

    protected override Size MeasureOverride(Size constraint) 
    { 
     Size myConstraint = new Size(_shape.Width, _shape.Height); 
     _container.Measure(myConstraint); 

     return _container.DesiredSize; 
    } 

    protected override Visual GetVisualChild(int index) 
    { 
     return _visualChildren[index]; 
    } 

    protected override int VisualChildrenCount 
    { 
     get 
     { 
      return _visualChildren.Count; 
     } 
    } 
} 

उत्तर

0

एक adorner की स्थिति सजी तत्व के सापेक्ष है। यदि आप इसे अपने ऑब्जेक्ट के शीर्ष पर रखना चाहते हैं, तो yloc का मान नकारात्मक होना चाहिए। हालांकि, कोड जो आपने कैनवास की सीमाओं का भी सम्मान किया है। यदि उपरोक्त आयताकार के लिए पर्याप्त जगह नहीं है, तो यह इसे नीचे रखेगी। टेक्स्टबॉक्स को कैनवास में थोड़ा कम रखने की कोशिश कर रहा है।