我在WPF中有一个TextBox
,如下所示:
<TextBox Height="48" />
没什么特别的,看起来像这样:
现在我需要做的是拥有清晰漂亮的长线标记:
所以基本上我想在位置50处画一个线标记。我将使用固定宽度的字体使我自己更容易,所以我可以轻松地计算位置。
现在问题是,我不想限制它的输入,但是当你达到50个字符的限制时,我希望它能给出一个视觉胶水。
为了使问题更难,我需要对以下行/行(72个字符)的此限制更高,如下所示:
共享相同位置的行标记(行2-n)可以是单行而不是多行。
我也对其他建议持开放态度,但只要它提供一种干净的方式告诉用户他即将超出限制,我就很酷。
注意:我不希望任何文字说“你还剩x个字符”或其他东西。空间有限,我希望它是可视的。
更新:我真的很感激是否可以添加工具提示,以便在悬停标记时向用户说明其目的。
答案 0 :(得分: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
}
}