【发布时间】:2022-01-08 06:02:34
【问题描述】:
我正在创建一个 WPF UI,其中包含一个控制台。为此,我想将TextBox 的一部分设置为只读,但仍然可以在TextBox 的末尾输入一些内容,也可以删除该部分。
是否可以仅将 WPF TextBox 的一部分设为只读,还是我需要处理事件并自行编写代码?
【问题讨论】:
我正在创建一个 WPF UI,其中包含一个控制台。为此,我想将TextBox 的一部分设置为只读,但仍然可以在TextBox 的末尾输入一些内容,也可以删除该部分。
是否可以仅将 WPF 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 确保一旦控制台输出超出窗口,就会有一个滚动条。有一个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。
【讨论】:
是否可以只将 WPF TextBox 的一部分设为只读
回答您的问题:不,不可能使用任何内置功能仅将TextBox 的一部分设为只读。
您必须以某种方式自己实现它。也许您可以考虑使用几个 TextBox 元素,其中只有最后一个是可编辑的。
【讨论】: