2009-12-17 55 views

回答

5
public class AutoCompleteTextBox : TextBox 
{ 
    public Point GetPositionFromCharacterIndex(int index) 
    { 
     if (TextWrapping == TextWrapping.Wrap) throw new NotSupportedException(); 

     var text = Text.Substring(0, index); 

     int lastNewLineIndex = text.LastIndexOf('\r'); 

     var leftText = lastNewLineIndex != -1 ? text.Substring(lastNewLineIndex + 1) : text; 

     var block = new TextBlock 
         { 
          FontFamily = FontFamily, 
          FontSize = FontSize, 
          FontStretch = FontStretch, 
          FontStyle = FontStyle, 
          FontWeight = FontWeight 
         }; 

     block.Text = text; 
     double y = block.ActualHeight; 

     block.Text = leftText; 
     double x = block.ActualWidth; 

     var scrollViewer = GetTemplateChild("ContentElement") as ScrollViewer; 

     var point = scrollViewer != null 
         ? new Point(x - scrollViewer.HorizontalOffset, y - scrollViewer.VerticalOffset) 
         : new Point(x, y); 
     point.X += BorderThickness.Left + Padding.Left; 
     point.Y += BorderThickness.Top + Padding.Top; 

     return point; 
    } 
} 
2

除了altso's answer,我想提一提,你确实需要调用块.Measure().Arrange()方法.ActualHeight.ActualWidth工作,例如,像这样(参数可能取决于你的用例):

block.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity)); 
block.Arrange(new Rect(0, 0, block.DesiredSize.Width, block.DesiredSize.Height)); 
double y = block.ActualHeight; 

这是在WPF需要,和在Silverlight(包括SL5)。否则,最终WPF中的ActualHeight和Silverlight中奇怪的数字(在我的情况中,这些是围绕的所有文本的边界框的坐标)中的0。


作为一个独立的解决方案,你可以使用FormattedText类做同样的伎俩。

+0

感谢您的补充 – altso

相关问题