2

TextBox在 WPF 中有一个像这样的:

<TextBox Height="48" />

没什么特别的,看起来像这样:

在此处输入图像描述

现在我需要完成的是有清晰漂亮的长线标记:

在此处输入图像描述

所以基本上我想在位置 50 处画一个线标记。我将使用一个固定宽度的字体来使这对我自己更容易,这样我就可以轻松地计算位置。

现在的问题是,我不想限制在它上面输入,但我希望它在达到 50 个字符的限制时提供视觉粘合。

为了使事情变得更困难,我需要对以下行/行(72 个字符)设置更高的限制,如下所示:

在此处输入图像描述

共享相同位置的线标记(第 2 - n 行)可以是单行而不是多行。

我也对其他建议持开放态度,但只要它提供一种干净的方式来告诉用户他即将超过限制,我对此很满意。

注意:我不希望有任何文字说“你还剩 x 个字符”之类的。空间有限,我希望它是视觉的。

更新:如果可以添加工具提示,以便在悬停标记时向用户说明其用途,我将不胜感激。

4

1 回答 1

3

既然你想在视觉上装饰文本框,我想到的第一件事就是恰当地命名为Adnorner

我写了一个快速演示来展示如何装饰文本框。画线部分很容易,棘手的部分是弄清楚应该在哪里画线。我在示例中对行位置进行了硬编码。我想你必须做一些文本测量来找出你的文本有多高(对于行高)以及 50 个字符的价值是多少(以抵消你的行)。

在此处输入图像描述

这是xaml:

<Window x:Class="WpfApplication4.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Grid  HorizontalAlignment="Stretch"  VerticalAlignment="Stretch" >
        <AdornerDecorator>
            <TextBox TextWrapping="Wrap"  AcceptsReturn="True" x:Name="myTextBox" Width="200px" Height="200px">hello</TextBox>
        </AdornerDecorator>
    </Grid>
</Window>

以及背后的代码

using System.Windows;
using System.Windows.Documents;
using System.Windows.Media;

namespace WpfApplication4
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            AdornerLayer myAdornerLayer = AdornerLayer.GetAdornerLayer(myTextBox);
            myAdornerLayer.Add(new LineAdorner(myTextBox));
        }

        // Adorners must subclass the abstract base class Adorner.

        #region Nested type: LineAdorner

        public class LineAdorner : Adorner
        {
            // Be sure to call the base class constructor.
            public LineAdorner(UIElement adornedElement)
                : base(adornedElement)
            {
            }

            // A common way to implement an adorner's rendering behavior is to override the OnRender
            // method, which is called by the layout system as part of a rendering pass.
            protected override void OnRender(DrawingContext drawingContext)
            {
                var adornedElementRect = new Rect(AdornedElement.DesiredSize);

                var renderPen = new Pen(new SolidColorBrush(Colors.Red), 1.5);

                // Draw lines.
                drawingContext.DrawLine(renderPen,
                                        new Point(adornedElementRect.TopLeft.X + 75, adornedElementRect.TopLeft.Y),
                                        new Point(adornedElementRect.TopLeft.X + 75, adornedElementRect.TopLeft.Y + 20));
                drawingContext.DrawLine(renderPen,
                                        new Point(adornedElementRect.TopLeft.X + 120, adornedElementRect.TopLeft.Y + 20),
                                        new Point(adornedElementRect.TopLeft.X + 120, adornedElementRect.TopLeft.Y + 40));
                drawingContext.DrawLine(renderPen,
                                        new Point(adornedElementRect.TopLeft.X + 120, adornedElementRect.TopLeft.Y + 40),
                                        new Point(adornedElementRect.TopLeft.X + 120, adornedElementRect.TopLeft.Y + 60));
            }
        }

        #endregion
    }
}
于 2012-05-12T16:33:37.673 回答