C# WPF Изменение текстового события из TextBox

у меня проблема. Я создал новый класс под названием «LetterBox», этот класс наследуется от TextBox, сейчас все работает. Но вот проблема: мне нужно событие или функция, которая «заполняет» текстовое поле.

Например: я нажимаю клавишу «T», и в текстовом поле TextBox появляется буква T. Но какое событие или функция заполняет это поле?

Я хочу изменить текстовое поле со String на свой собственный объект WordElement.

Вот мой класс LetterBox:

internal class LetterBox : TextBox
{
    public static List<WordElement> Letters { get; set; } = new();

    public LetterBox()
    {
        FontSize = 20;

        KeyDown += LetterBox_KeyDown;
    }
    
    // This event wont work as expected, because the Text gets added twice
    public void LetterBox_KeyDown(object sender, KeyEventArgs e)
    {
        // Retrieve the Key that was pressed
        Key key = e.Key;
        char ckey = (char)key;

        WordElement we = new();
        
        // Set the Letter in the WordElement to manipulate it later
        we.SetLetter(ckey);
        
        Letters.Add(we);

        // Delete the Text to "refresh" it
        Text = "";

        // Put every Letter from the list back in the Text
        foreach (WordElement wordElement in Letters)
        {
            Text += wordElement.Letter;
        }
    }
}

Вот мой класс WordElement:

internal class WordElement
{
    public char Letter { get; private set; }
    public Color Color { get; private set; } = Colors.Black;
    public float Size { get; private set; } = 12;
    public bool Bold { get; private set; } = false;
    public bool Italic { get; private set; } = false;
    public bool Underlined { get; private set; } = false;

    public void SetLetter(char letter)
    {
        Letter = letter;
    }

    public void SetColor(Color color)
    {
        Color = color;
    }

    public void SetSize(float size)
    {
        Size = size;
    }

    public void SetBold(bool bold)
    {
        Bold = bold;
    }

    public void SetItalic(bool italic)
    {
        Italic = italic;
    }

    public void SetUnderlined(bool underlined)
    {
        Underlined = underlined;
    }
}

Надеюсь, вы понимаете мою проблему и сможете мне помочь :)

P.S.: мой английский не самый лучший :P

Могу ли я спросить, чего именно вы пытаетесь достичь? Очистка всего текста при каждом вводе не очень эффективна и, скорее всего, вызовет проблемы, поскольку всегда вызывает событие TextChanged. В чем идея? Почему вы очищаете все данные только для того, чтобы добавить их обратно? Конкатенация в вашем цикле также неэффективна с точки зрения скорости и памяти.

BionicCode 24.07.2024 20:11

это для более крупного проекта, над которым я работаю, этот код находится в другом решении для проверки моей идеи о собственном текстовом поле. мне нужно текстовое поле, в котором я могу раскрасить некоторые части текста, например, то, что я выбираю, может быть изменено в цвете или шрифте и т. д., но я не хочу использовать richtextbox, потому что мне не нужен формат rtf. я хочу, чтобы это было так же, как в классе элемента слова, поэтому я могу сделать что-то вроде: «Letter[3].Color», чтобы получить цвет этой буквы

Aquedus 24.07.2024 20:23

Ах я вижу. но TextBox — неправильный элемент управления для выделения ext, не так ли? Он не поддерживает форматированный текст. Вам следует взглянуть на FormattedText. Это позволяет отображать текст вручную. Вы можете форматировать посимвольно. Вы можете нарисовать FormattedText, используя DrawingContext.DrawText. TextBox вас точно ни к чему не приведет. Я бы не стал больше тратить на это время. Он специализируется на вводе текста. Простой текстовый ввод.

BionicCode 24.07.2024 21:38

Вы также можете использовать TextBlock и составить его, используя отформатированные Run элементы, как если бы вы делали это в FlowDocument. Но TextBlock не предназначен для отображения больших текстов. Для более крупных текстов вы можете просмотреть FormattedText. Вы можете управлять кареткой с помощью Win32 API.

BionicCode 24.07.2024 21:38

Я знаю, что не могу отображать форматированный текст с помощью стандартного TextBox, но я использовал его в этом тестовом решении для тестирования своих классов. Следующим шагом будет создание чего-то вроде текстового поля, которое может отображать форматированный текст, и пользователь может редактировать текст (это должно быть «текстовое поле»). мой более крупный проект — это инструмент для людей, которые хотят писать истории или книги, а текстовое поле или текстовое поле — это самое важное, но чтобы облегчить мне задачу в будущем, я хочу, чтобы он работал с WordElement сорт.

Aquedus 25.07.2024 11:08

также я создал LetterBox, который, как я думал, смогу создать свое собственное текстовое поле с этим форматированным текстом, потому что richtextbox тоже наследуется от класса текстового поля, верно? поэтому я пытаюсь использовать этот класс для создания собственного текстового поля.

Aquedus 25.07.2024 11:10

RichTextBox не наследуется от TextBox. Он наследует TextBoxBase. Это огромная разница, поскольку вся обработка текстового контейнера отсутствует. RichTextBox не использует текстовый контейнер по умолчанию, поскольку он работает с FlowDocument. Не думайте, что это будет легкая задача. Вам необходимо реализовать всю отрисовку текста и взаимодействие с ним, например, позиционирование курсора, команды клавиатуры, выделение текста, с нуля. Я не говорю, что это выходит за рамки ваших навыков (просто говорю это, чтобы не допустить неверного истолкования моих слов).

BionicCode 25.07.2024 12:12

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

BionicCode 25.07.2024 12:12
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
8
52
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Установите e.Handled = true;, чтобы подавить стандартную обработку ввода в LetterBox_KeyDown.

Но если вы получаете результат от другого элемента управления, вы переопределите OnKeyDown вместо подписки на событие, а затем просто не будете вызывать base.OnKeyDown();, чтобы подавить стандартную обработку ввода.

protected override void OnKeyDown(KeyEventArgs e)
{
    // Your code
}

Спасибо за ваш ответ, я просто забыл, что «e.Handled = true» подавляет стандартную обработку, но теперь это работает :)

Aquedus 24.07.2024 20:16

Другие вопросы по теме