Изменение ширины символа / ширины в элементе управления TextBox - PullRequest
3 голосов
/ 07 января 2012

Я пытаюсь динамически установить интервал (ширину) каждого символа в элементе управления TextBox. Я много читал, и я не верю, что это возможно даже в обычном TextBox. Я открыт для RichTextBox или любого другого элемента управления, который может решить эту проблему.

Чтобы доказать, что это возможно, я открыл Word и смог выбрать один символ, настроить его интервал и «растянуть» его. Я пытаюсь добиться того же поведения в моем приложении .NET.

Modified M

Существует ли пример кода или элемент управления, показывающий, как это можно сделать?

Ответы [ 3 ]

4 голосов
/ 16 января 2012

Если вы согласны ссылаться на некоторые сборки WPF (WindowsBase и PresentationCore), вы можете написать собственный TextBox и использовать его в реализации WinForms.В WPF есть несколько хороших классов, таких как GlyphTypeFace (позволяет загружать файл шрифтов и создавать геометрии из глифов) и GlyphRun (который позволяет рисовать список глифов - текст).Но мы не можем использовать GlyphRun здесь, потому что мы хотим иметь возможность изменять геометрию некоторых глифов.Поэтому нам нужно вручную получить геометрию и преобразовать ее.

Вот пример:

Код Winforms:

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();

        // ElementHost allows Winforms to host WPF visual components
        ElementHost host = new ElementHost();
        host.Dock = DockStyle.Fill;
        host.Child = new MyTextBox();
        Controls.Add(host);
    }

Пользовательский код TextBox:

public class MyTextBox: UIElement
{
    protected override void OnRender(DrawingContext drawingContext)
    {
        const string sampleText = "Sample String";
        const int sampleEmSize = 30;

        GlyphTypeface typeFace = new GlyphTypeface(new Uri("file:///C:/WINDOWS/FONTS/segoeui.ttf"));

        GeometryGroup group = new GeometryGroup();
        group.FillRule = FillRule.Nonzero;

        double x = 0;
        double y = sampleEmSize;
        for (int i = 0; i < sampleText.Length; i++)
        {
            ushort glyphIndex = typeFace.CharacterToGlyphMap[sampleText[i]];
            Geometry glyphGeometry = typeFace.GetGlyphOutline(glyphIndex, sampleEmSize, sampleEmSize).Clone();
            TransformGroup glyphTransform = new TransformGroup();

            if (sampleText[i] == 'm') // this is a sample, we just change the 'm' characte
            {
                const double factor = 2;
                glyphTransform.Children.Add(new ScaleTransform(factor, 1));
                glyphTransform.Children.Add(new TranslateTransform(x, y));
                x += factor * typeFace.AdvanceWidths[glyphIndex] * sampleEmSize;
            }
            else
            {
                glyphTransform.Children.Add(new TranslateTransform(x, y));
                x += typeFace.AdvanceWidths[glyphIndex] * sampleEmSize;
            }

            glyphGeometry.Transform = glyphTransform;
            group.Children.Add(glyphGeometry);
        }

        drawingContext.DrawGeometry(Brushes.Black, null, group);
    }
}

А вот результат на WinForms:

enter image description here

Конечно, есть некоторая работа, если вы хотите поддержать редактирование, но это может привести кВы начали.

0 голосов
/ 16 января 2012

Вы можете посмотреть элементы управления Telerik для WinForms. Я знаю, что они уделяют большое внимание элементам стиля.

0 голосов
/ 16 января 2012

для справки, я написал этот код, который позволит вам изменять шрифт, fontstyle для каждого символа, который вы вводите в RichTextBox.

public int a = 0;
private void richTextBox1_TextChanged(object sender, EventArgs e)
    {
        if (a == 0)
        {
            richTextBox1.SelectionFont = new Font(RichTextBox.DefaultFont, FontStyle.Bold);
            a = 1;
        }
        else if (a == 1)
        {
            richTextBox1.SelectionFont = new Font("Georgia",13, FontStyle.Bold);
            a = 2;
        }
        else if (a == 2)
        {
            richTextBox1.SelectionFont = new Font("Impact", 11, FontStyle.Italic);
            a = 0;
        }
    }

Дайте мне знать, если это поможет вам.

...