Home > front end >  TextBox Part ReadOnly
TextBox Part ReadOnly

Time:12-02

I am creating an WPF UI which has a console as part of it. For this I want to set a part of the TextBox as read-only, but still be able to input something at the end of the TextBox and also be able to delete that part.

Is it possible to make only a part of the WPF TextBox read-only or would I need to work with an event and code this my self?

CodePudding user response:

Is it possible to make only a Part of the WPF TextBox ReadOnly

To answer your question: No, it's not possible to make only a part of the TextBox read-only using any built-in functionality.

You will have to implement this yourself somehow. Maybe you could consider using several TextBox elements where only the last one is editable or something.

CodePudding user response:

I do not think that this is possible with the default WPF TextBox. However, there is another way you can achieve a console-like control in a different way. Create a ConsoleOutput property of type ObservableCollection<string> which holds the lines of text displayed in your console and a property ConsoleInput for the current input line in your view model. Do not forget to implement INotifyPropertyChanged, otherwise the user interface will not react to changes of ConsoleInput. Additionally, create a command RunCommand, which will be executed when you confirm or run a command in the console.

public ObservableCollection<string> ConsoleOutput { get; }

private string _consoleInput;
public string ConsoleInput
{
   get => _consoleInput;
   set
   {
      if (value.Equals(_consoleInput))
         return;

      _consoleInput = value;
      OnPropertyChanged();
   }
}

public ICommand RunCommand { get; }

Initialize the properties in the constructor like below. The implementation of the RunCommand simply adds the newly confirmed line of console input to the collection of console outputs and empties the input.

public YourViewModel()
{
   //... other code.
   ConsoleOutput = new ObservableCollection<string>();
   OnPropertyChanged(nameof(ConsoleOutput));
   
   RunCommand = new DelegateCommand(ExecuteRun);
   OnPropertyChanged(nameof(RunCommand));
}
   
private void ExecuteRun()
{
   ConsoleOutput.Add(ConsoleInput);
   ConsoleInput = string.Empty;
}

Then create the controls and bind the properties. A ScrollViewer ensures, that there will be a scrollbar, once the console output exceeds to window. There is an ItemsControl that displays all console outputs so far and a TextBox below for inputs. It has no border so it does not stand out. The Enter key in the TextBox is bound to the RunCommand, which means the current input is added to the console output and cleared.

<ScrollViewer>
   <StackPanel>
      <ItemsControl ItemsSource="{Binding ConsoleOutput}" />
      <TextBox BorderThickness="0" Text="{Binding ConsoleInput, UpdateSourceTrigger=PropertyChanged}">
         <TextBox.InputBindings>
            <KeyBinding Key="Enter" Command="{Binding RunCommand}"/>
         </TextBox.InputBindings>
      </TextBox>
   </StackPanel>
</ScrollViewer>

This is the output. The last element is the TextBox that takes the input until you hit Enter.

Sample of multiple lines of output and the line currently typed.

  • Related