I have a Windows Store app with RichEditBox (editor) and Grid (MarginNotes).
I need a vertical scroll position of two elements that must be consistent at all times. The purpose of this is to allow the user to add notes to the document field.
I already realized that the positioning of notes is based on the cursor position - when a note is added, the text is selected from everything up to the cursor. this selection is then added to the second, invisible RichEditBox , inside a StackPanel . Then I get the ActualHeight this control, which gives me the position of the note in the grid.
My problem is that when I scroll the RichEditBox up and down, the Grid does not scroll accordingly.
First technique
I tried putting them inside a ScrollViewer and disabling scrolling on a RichEditBox
<ScrollViewer x:Name="EditorScroller" VerticalAlignment="Stretch" HorizontalAlignment="Stretch"> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width="150" /> <ColumnDefinition Width="{Binding *" /> <ColumnDefinition Width="150" /> </Grid.ColumnDefinitions> <Grid x:Name="MarginNotes" Grid.Column="0" HorizontalAlignment="Right" Height="{Binding ActualHeight, ElementName=editor}"> </Grid> <StackPanel Grid.Column="1"> <RichEditBox x:Name="margin_helper" Opacity="0" Height="Auto"></RichEditBox> </StackPanel> <RichEditBox x:Name="editor" Grid.Column="1" Height="Auto" ScrollViewer.VerticalScrollBarVisibility="Hidden" /> </Grid> </ScrollViewer>
When I scroll the bottom of the RichEditBox control and press the enter button several times, the cursor drops out of view. ScrollViewer does not scroll automatically with the cursor.
I tried adding C # code that would check the position of the cursor, compare it with VerticalOffset and the height of the editor, and then adjust the scroll accordingly. It worked, but it was incredibly slow. I initially had this at a KeyUp event, which caused the application to stop when I typed in a sentence. Subsequently, I set it to a 5-second timer, but it still slowed down the performance of the application, and also meant that there could be a 5-second delay between moving the cursor out of sight and scrolling RichEditBox .
Second technique
I also tried putting only MarginNotes in my own ScrollViewer and programmatically setting VerticalOffset based on my RichEditBox ViewChanged .
<Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width="150" /> <ColumnDefinition Width="{Binding *" /> <ColumnDefinition Width="150" /> </Grid.ColumnDefinitions> <ScrollViewer x:Name="MarginScroller" Grid.Column="0" VerticalAlignment="Stretch" HorizontalAlignment="Stretch"> <Grid x:Name="MarginNotes" HorizontalAlignment="Right" Height="{Binding ActualHeight, ElementName=editor}"> </Grid> </ScrollViewer> <StackPanel Grid.Column="1"> <RichEditBox x:Name="margin_helper" Opacity="0" Height="Auto"></RichEditBox> </StackPanel> <RichEditBox x:Name="editor" Grid.Column="1" Height="Auto" Loaded="editor_loaded" SizeChanged="editor_SizeChanged" /> </Grid>
relevant event handlers
void editor_Loaded(object sender, RoutedEventArgs e) {
This worked, but was rather backward, as scrolling is not applied until the ViewChanged event ViewChanged , after scrolling has stopped. I tried using the ViewChanging event, but for some reason it does not fire at all. In addition, the Grid sometimes incorrectly positioned after a quick scroll.