I am creating a test version of the page where text will be entered and adjusted, or rather compared with the original and, depending on this, the color of the symbol will be set (if the symbol is entered as in the text – white, otherwise red). The only problem I have is that in the textblock, for example, there is a word that is on a new line, in the textbox when entering, or rather during the process, the entered word will first be at the top and only after being completely written at the bottom (or even leave half of the text at the top, I am attaching a screenshot) . I honestly don’t know how to solve this, so I hope for your help! I will also be glad if you point out any mistakes made in working with the MVVM code (as I said, the code is test and the same binding in the view in the original will be removed and added to OnStarted)
View code:
<Window.DataContext>
<local:MainViewModel/>
</Window.DataContext>
<Grid Background="#282a36">
<TextBlock Text="{Binding OriginalText}"
FontFamily="Consolas"
Foreground="Gray"
FontSize="16"
IsHitTestVisible="False"
TextWrapping="Wrap"/>
<TextBox Text="{Binding UserInput, UpdateSourceTrigger=PropertyChanged}"
FontSize="16"
FontFamily="Consolas"
Background="Transparent"
Foreground="Transparent"
BorderBrush="Transparent"
TextWrapping="Wrap"/>
<ItemsControl ItemsSource="{Binding ColoredUserInput}" VerticalAlignment="Top">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Character}"
Foreground="{Binding Color}"
FontSize="16"
FontFamily="Consolas"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
MainViewModel
public class MainViewModel : INotifyPropertyChanged
{
private string _originalText = "The curious cat explored every corner of the garden, chasing butterflies and sniffing at freshly bloomed flowers. Meanwhile, the old oak tree stood tall, its branches swaying gently in the summer breeze. Birds chirped happily overhead, creating a symphony of natural sounds. The sun painted the sky in shades of orange and pink as evening approached.";
private string _userInput;
private ObservableCollection<ColoredCharacter> _coloredUserInput;
public MainViewModel()
{
ColoredUserInput = new ObservableCollection<ColoredCharacter>();
}
public string OriginalText
{
get => _originalText;
set
{
_originalText = value;
OnPropertyChanged();
}
}
public string UserInput
{
get => _userInput;
set
{
_userInput = value;
OnPropertyChanged();
UpdateColoredUserInput();
}
}
public ObservableCollection<ColoredCharacter> ColoredUserInput
{
get => _coloredUserInput;
set
{
_coloredUserInput = value;
OnPropertyChanged();
}
}
private void UpdateColoredUserInput()
{
ColoredUserInput.Clear();
for (int i = 0; i < OriginalText.Length; i++)
{
if (i < UserInput.Length)
{
var character = OriginalText[i];
var color = UserInput[i] == character ? Brushes.White : Brushes.Red;
ColoredUserInput.Add(new ColoredCharacter { Character = character.ToString(), Color = color });
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
public class ColoredCharacter
{
public string Character { get; set; }
public Brush Color { get; set; }
}
Attempted solutions were only guesswork. For example, somehow track whether the next word is wrapped and, if so, add n