2

私は次のTextBoxようなWPFを持っています:

<TextBox Height="48" />

特別なことは何もありません、このように見えます:

ここに画像の説明を入力してください

今私が達成する必要があるのは、明確で素敵な長い線のマーカーを持つことです:

ここに画像の説明を入力してください

ですから、基本的には50の位置にラインマーカーを描きたいと思います。固定幅フォントを使用して、位置を簡単に計算できるようにします。

さて、入力を制限したくはありませんが、50文字の制限に達したときに視覚的な接着剤を与えるようにしたいのです。

さらに難しいことに、次のような行/行(72文字)では、この制限を高くする必要があります。

ここに画像の説明を入力してください

同じ位置(行2-n)を共有するラインマーカーは、複数ではなく単一のラインである可能性があります。

他の提案も受け付けていますが、制限を超えようとしていることをユーザーに伝えるためのクリーンな方法を提供する限り、私はそれでかっこいいです。

注:「x文字が残っています」などのテキストは必要ありません。スペースに限りがあり、視覚的にしたいと思います。

更新:マーカーにカーソルを合わせると、ユーザーにその目的が示されるようにツールチップを追加できれば幸いです。

4

1 に答える 1

3

Textbox を視覚的に装飾したいので、最初に頭に浮かんだのは、適切な名前のAdnornerです。

Textbox を装飾する方法を示す簡単なデモを作成しました。線画の部分は簡単ですが、どこに線を引くかが難しいところです。私の例では、行の位置をハードコーディングしました。テキストの高さ(行の高さ)と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 に答える