There is a usual TextBox in which the text is written. I need the following:

I select a part of the text with the mouse and click on the "Italic" button, then <i> added before the start of the text selection, </i> added at the end of the selection.

Question: how to determine the text selected with the mouse for further work with it?

UPD1:

I am using MVVM + Catel, Catel.Fody model

My view:

 <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}"/> 

My model:

 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() { } 

Now the problem is that if I set the view to SelecteedText in SelecteedText then the tab in the program simply stops opening. If I remove this property, then everything works.

  • And if you specify Mode = OneWayToSource? - Andrey NOP
  • @AndreyNOP tried, the tab simply does not open. The tab only works if the following is written SelectedText="" , if you add anything to the brackets, then everything stops working. - Leksor
  • @AndreyNOP maybe there is some nuget package for wpf in which there is a text field with the keys "bold text", "italics", like on stackoverflow when creating a question? - Leksor
  • Just pass the selected text as a parameter to the command that starts by pressing the button - Andrey NOP
  • @AndreyNOP Okay, how can I find out / catch the selected text in order to transfer it to the team? - Leksor

2 answers 2

Made with the help of a trigger as follows: (view)

 <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> 

Model:

 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; } } 

    Not tested, but it should work:

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

    It is also necessary to take into account that if 1 is allocated to a letter, then each instance of a letter in a string will be taken as a tag. So it will be necessary to complicate the algorithm if you want to be sure that this would not happen.

    • I use the model mvvm + catel and this method of defining text will not work for me. - Leksor
    • And what specifically prevents to do it in ViewController (if that is in your implementation of mvvm)? You can, for example, create an Action <string, string> AddTagToSelectedText in the view itself and call it there. And inside the implementation shown above. the opening tag is passed to the first string, Andrew is sent to the second string
    • and, understood, vpf. Well, I won’t help here, I’m not on friendly terms with VfF ... It may not be the case ... - Andrew