Узнать выделенный текст в TextBox на WPF

95
14 июня 2019, 11:20

Есть обычный TextBox, в котором написан текст. Мне необходимо следующее:

Я выделяю часть текста мышкой и нажимаю на кнопку "Курсив", после чего перед началом выделения текста добавляется <i>, в конце выделения добавляется </i>.

Вопрос: как определить выделенный мышкой текст для дальнейшей работы с ним?

UPD1:

Я использую модель MVVM + Catel, Catel.Fody

Моя вьюшка:

<TextBox Grid.Row="2" Grid.Column="1" MaxLines="255"
                     AcceptsReturn="True"
                     AcceptsTab="True"
                     Text="{Binding Content, UpdateSourceTrigger=PropertyChanged}" TextChanged="OnTextChanged"
                     SelectedText="{Binding SelectedText, UpdateSourceTrigger=PropertyChanged}"/>

Моя модель:

public ViewModel()
{
    BoldText = new Command(OnBoldText);
    ItalicText = new Command(OnItalicText);
}
public Command BoldText { get; set; }
public Command ItalicText { get; set; }
public string SelectedText { get; set; }
private void OnBoldText()
{
}
private void OnItalicText()
{
}

Сейчас проблема в том что если я во view задал св-во SelecteedText то вкладка в программе попросту перестает открываться. Если я убираю данное св-во, то все работает.

Answer 1

Сделал с помощью триггера следующим образом: (вьюшка)

<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="Auto" />
        <ColumnDefinition Width="Auto" />
        <ColumnDefinition Width="Auto" />
        <ColumnDefinition Width="Auto" />
        <ColumnDefinition Width="Auto" />
        <ColumnDefinition Width="Auto" />
    </Grid.ColumnDefinitions>
    <handal:DropDownButton Grid.Column="0"
                           Header="Размер текста"
                           Margin="0,0,0,3"
                           ToolTip="Размер выделенного текста">
        <handal:DropDownButton.DropDown>
            <ContextMenu>
                <MenuItem Header="Большой"
                          Command="{Binding FormatTextCommand}" CommandParameter="0"
                          ToolTip="Увеличить выделенный текст (big)" />
                <MenuItem Header="Маленький"
                          Command="{Binding FormatTextCommand}" CommandParameter="1"
                          ToolTip="Уменьшить выделенный текст (small)" />
            </ContextMenu>
        </handal:DropDownButton.DropDown>
    </handal:DropDownButton>
    <handal:ImageButton Grid.Column="1"
                        Icon="Bold"
                        Command="{Binding FormatTextCommand}" CommandParameter="2"
                        ToolTip="Сделать выделенный текст жирным (b)" />
    <handal:ImageButton Grid.Column="2"
                        Icon="Italic"
                        Command="{Binding FormatTextCommand}" CommandParameter="3"
                        ToolTip="Сделать выделенный текст курсивом (i)" />
    <handal:ImageButton Grid.Column="3"
                        Icon="CaretDown"
                        Command="{Binding FormatTextCommand}" CommandParameter="4"
                        ToolTip="Новая строка (br)" />
    <handal:ImageButton Grid.Column="4"
                        Icon="Paragraph"
                        Command="{Binding FormatTextCommand}" CommandParameter="5"
                        ToolTip="Объединить выделенный текст в параграф (p)" />
    <handal:ImageButton Grid.Column="5"
                        Icon="Inbox"
                        Command="{Binding FormatTextCommand}" CommandParameter="6"
                        ToolTip="Объединить выделенный текст в контейнер (div)" />
</Grid>
<Label Grid.Row="2" Grid.Column="0" Content="Содержимое письма" VerticalAlignment="Top" />
<TextBox Grid.Row="2" Grid.Column="1" MaxLines="255"
     AcceptsReturn="True"
     AcceptsTab="True"
     TextWrapping="Wrap"
     Text="{Binding Content, UpdateSourceTrigger=PropertyChanged}" TextChanged="OnTextChanged">
    <i:Interaction.Triggers>
        <i:EventTrigger EventName="SelectionChanged">
            <catel:EventToCommand Command="{Binding TextBoxSelectionChangedCommand}"
                                  PassEventArgsToCommand="True" />
        </i:EventTrigger>
    </i:Interaction.Triggers>
</TextBox>

Модель:

private Command<RoutedEventArgs> _textBoxSelectionChangedCommand;
public ClientsMailingViewModel()
{
    FormatTextCommand = new Command<string>(OnFormatText);
}
public Command<string> FormatTextCommand { get; set; }
public int SelectionStart { get; set; }
public int SelectionLength { get; set; }
public string Content { get; set; }
public Command<RoutedEventArgs> TextBoxSelectionChangedCommand
{
    get
    {
        if (_textBoxSelectionChangedCommand == null)
        {
            _textBoxSelectionChangedCommand =
                new Command<RoutedEventArgs>((r) => TextBoxSelectionChanged(r), (r) => true);
        }
        return _textBoxSelectionChangedCommand;
    }
}
protected virtual void TextBoxSelectionChanged(RoutedEventArgs args)
{
    SelectionStart = (args.OriginalSource as System.Windows.Controls.TextBox).SelectionStart;
    SelectionLength = (args.OriginalSource as System.Windows.Controls.TextBox).SelectionLength;
}
private void OnFormatText(string param)
{
    if (!string.IsNullOrEmpty(Content))
    {
        string lastStr = "", firstStr = "";
        // Текст большой
        if (param == "0")
        {
            lastStr = "</big>";
            firstStr = "<big>";
        }
        // Текст маленький
        else if (param == "1")
        {
            lastStr = "</small>";
            firstStr = "<small>";
        }
        // Текст жирным
        else if (param == "2")
        {
            lastStr = "</b>";
            firstStr = "<b>";
        }
        // Текст курсивом
        else if (param == "3")
        {
            lastStr = "</i>";
            firstStr = "<i>";
        }
        // Новая строка <br>
        else if (param == "4")
        {
            lastStr = "";
            firstStr = "\n<br>";
        }
        // Параграф <p>
        else if (param == "5")
        {
            lastStr = "</p>\n";
            firstStr = "\n<p>";
        }
        // Контейнер <div>
        else if (param == "6")
        {
            lastStr = "</div>\n";
            firstStr = "\n<div>";
        }
        var contentTemp = Content.Insert(SelectionStart + SelectionLength, lastStr);
        contentTemp = contentTemp.Insert(SelectionStart, firstStr);
        Content = contentTemp;
    }
}
Answer 2

Не проверял, но должно сработать:

txtBox.Text = txtBox.Text.Replace(txtBox.SelectedText,$"{<i>txtBox.SelectedText}</i>");

Так же нужо учесть что если будет выделена 1на буква, то тегом возьмется каждый инстанс буквы в строке. Так что нужно будет усложнить алгоритм если хочешь быть уверенным что б подобного не случалось.

READ ALSO
Маршрутизация в проекте mvc

Маршрутизация в проекте mvc

Есть проект на mvcИ у него разработан интерфейс под 2 браузера

117
Размеры области графика(Chart)

Размеры области графика(Chart)

Использую компонент Chart для отрисовки некоего графикаРазмер самого компонента Chart прямоугольный(ширина в пикселях больше высоты)

122
No such host is known в Dns.GetHostEntry

No such host is known в Dns.GetHostEntry

При вызове DnsGetHostEntry (или Dns

114