我正在开发一个使用MVVM的WPF应用程序,用户需要将文本从TextBlock元素输入到文本框中.文本框的占位符被"填充"并定位在文本块的正上方.它有一个透明的背景.当用户输入文本时,他们到达TextBlock的右侧,接下来的单词将被隐藏.
我希望文本框自动滚动,以便最后输入的字符在文本框的左侧可见,允许用户看到他们下一步需要输入的内容.
以下是我使用的XAML代码:
<ScrollViewer
x:Name="scroll"
Grid.Row="1"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
CanContentScroll="True"
HorizontalScrollBarVisibility="Visible"
VerticalScrollBarVisibility="Disabled">
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
</Grid.RowDefinitions>
<Border
Grid.Row="0"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Background="#8EABAF">
<TextBlock
x:Name="tblTextToType"
Margin="2,0,0,0"
VerticalAlignment="Center"
AllowDrop="False"
FontFamily="/Fonts/Nunito_Sans/#NunitoSans"
FontSize="28"
Foreground="Gray"
TextAlignment="Center" />
</Border>
<TextBox
x:Name="tbTypedText"
Grid.Row="0"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
AllowDrop="False"
Background="Transparent"
FontFamily="/Fonts/Nunito_Sans/#NunitoSans"
FontSize="28"
Foreground="Black"
IsInactiveSelectionHighlightEnabled="True"
IsReadOnly="True"
IsUndoEnabled="False"
MaxLines="1"
SelectionBrush="Green">
</TextBox>
</Grid>
</ScrollViewer>
此外,我还将两个命令绑定到应用程序窗口以处理击键.如果输入的文本与TextBlock的内容匹配,则会以编程方式将其添加到TextBox中.
The Type method performs the required effect with scrolling text, but only after the first time the text exceeds the width of the TextBox, and I need it to happen after each such exceeding个
C#代码处理KeyDownCommand和KeyUpCommand命令:
public ICommand KeyDownCommand { get; private set; }
private void ExecuteKeyDown(object? obj)
{
if (obj is KeyEventArgs e && _keyboardButtons.ContainsKey(e.Key))
{
Key key = (e.Key == Key.System) ? e.SystemKey : e.Key;
_keyboardButtons[key].KeyGrid.Background = SecondColor;
switch (key)
{
case Key.LeftCtrl:
case Key.RightCtrl:
case Key.LWin:
case Key.RWin:
case Key.LeftAlt:
case Key.RightAlt:
case Key.Back:
case Key.Tab:
case Key.Enter:
return;
case Key.LeftShift:
case Key.RightShift:
case Key.CapsLock:
UpdateKeyboard();
return;
case Key.Space:
Type(' ');
return;
default:
Type(char.Parse(_keyboardButtons[key].Content.Text));
break;
}
return;
}
}
public ICommand KeyUpCommand { get; private set; }
private void ExecuteKeyUp(object? obj)
{
if (obj is KeyEventArgs e && _keyboardButtons.ContainsKey(e.Key))
{
_keyboardButtons[e.Key].KeyGrid.Background = Brushes.Transparent;
UpdateKeyboard();
}
}
private bool isTextWidthExceededViewport = false;
private void Type(char character)
{
if (_textBox.Text.Length < _textBlock.Text.Length)
{
char expectedCharacter = _textBlock.Text[_textBox.Text.Length];
if (character == expectedCharacter)
{
_textBox.Text += character;
correctlyTypedTextLength++;
_progressBar.Value++;
_textBox.Foreground = (correctlyTypedTextLength == _textBox.Text.Length)
? new SolidColorBrush(Colors.Black)
: new SolidColorBrush(Colors.Red);
_textBox.Select(0, correctlyTypedTextLength);
var typeface = new Typeface(_textBox.FontFamily, _textBox.FontStyle, _textBox.FontWeight, _textBox.FontStretch);
var formattedText = new FormattedText(_textBox.Text, Thread.CurrentThread.CurrentCulture, _textBox.FlowDirection, typeface, _textBox.FontSize, _textBox.Foreground);
var size = new Size(formattedText.Width, formattedText.Height);
if (size.Width + 20 > _scrollViewer.ViewportWidth && !isTextWidthExceededViewport)
{
_scrollViewer.ScrollToRightEnd();
isTextWidthExceededViewport = true;
}
}
else
{
Fails++;
_textBox.Foreground = Brushes.Red;
if (Properties.Settings.Default.ErrorSound)
System.Media.SystemSounds.Exclamation.Play();
}
}
}
我也try 过使用其他命令和自定义文本框元素来实现自动滚动,但没有成功.
总而言之,我的WPF应用程序需要一个文本框来自动滚动,以便当用户输入的内容超过文本框的可见宽度时,文本框左侧仍显示最后输入的字符.
如果有任何关于如何实现这种自动滚动行为的见解或解决方案,我将不胜感激.谢谢!