文本框部分只读

TextBox Part ReadOnly

我正在创建一个 WPF UI,其中包含一个控制台。为此,我想将 TextBox 的一部分设置为只读,但仍然能够在 TextBox 的末尾输入一些内容,并且还能够删除该部分。

是否可以仅将 WPF TextBox 的一部分设置为只读,或者我是否需要处理事件并自行编写代码?

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

回答您的问题:不,不可能使用任何内置功能仅将 TextBox 的一部分设置为只读。

您必须自己以某种方式实现它。也许您可以考虑使用几个 TextBox 元素,其中只有最后一个元素是可编辑的或其他东西。

我认为默认 WPF TextBox 不可能做到这一点。但是,还有另一种方法可以用不同的方式实现类似控制台的控制。创建一个类型为 ObservableCollection<string>ConsoleOutput 属性 来保存控制台中显示的文本行,并为视图模型中的当前输入行创建一个 属性 ConsoleInput .不要忘记实现 INotifyPropertyChanged,否则用户界面将不会对 ConsoleInput 的变化作出反应。此外,创建一个命令 RunCommand,当您在控制台中确认或 运行 命令时将执行该命令。

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

像下面这样在构造函数中初始化属性。 RunCommand 的实现只是将新确认的控制台输入行添加到控制台输出集合并清空输入。

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

然后创建控件并绑定属性。 ScrollViewer 确保一旦控制台输出超过 window,就会有一个滚动条。有一个 ItemsControl 显示到目前为止的所有控制台输出,下面有一个 TextBox 用于输入。它没有边框,所以它不突出。 TextBox中的Enter键绑定到RunCommand,表示当前输入被添加到控制台输出并被清除。

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

这是输出。最后一个元素是 TextBox 接受输入,直到您按 Enter