我有一个Windows Store应用程序,其中包含一个
我需要两个元素的垂直滚动位置始终匹配。这样做的目的是允许用户在文档的边距中添加注释。
我已经根据光标位置确定了注释位置 - 当添加注释时,会对光标之前的所有内容进行文本选择。然后将此选择添加到第二个不可见的
我的问题是,当我上下滚动
当我滚动到
我尝试添加C#代码来检查光标位置,将其与编辑器的
第二种技术
我还尝试将
相关事件处理程序
RichEditBox
(编辑器)和一个Grid
(MarginNotes)。我需要两个元素的垂直滚动位置始终匹配。这样做的目的是允许用户在文档的边距中添加注释。
我已经根据光标位置确定了注释位置 - 当添加注释时,会对光标之前的所有内容进行文本选择。然后将此选择添加到第二个不可见的
RichEditBox
中,该控件位于StackPanel
内。然后,我获取此控件的ActualHeight
,以获得注释在网格中的位置。我的问题是,当我上下滚动
RichEditBox
时,Grid
不会相应地滚动。
第一种技术
我尝试将它们都放在ScrollViewer
中,并在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>
当我滚动到
RichEditBox
控件的底部并按几次回车键时,光标消失了。 ScrollViewer
不会自动随着光标滚动。我尝试添加C#代码来检查光标位置,将其与编辑器的
VerticalOffset
和高度进行比较,然后相应地调整滚动。这个方法有效,但速度非常慢。最初我将它放在KeyUp
事件上,当我输入句子时,应用程序就会停止响应。之后我将其放在5秒计时器上,但这仍然会减慢应用程序的性能,并且意味着光标消失并且RichEditBox
滚动之间可能会有5秒的延迟。第二种技术
我还尝试将
MarginNotes
放在自己的ScrollViewer
中,并根据我的RichEditBox
的ViewChanged
事件编程设置VerticalOffset
。<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>
相关事件处理程序
void editor_Loaded(object sender, RoutedEventArgs e)
{
// setting this in the OnNavigatedTo causes a crash, has to be set here.
// this uses WinRTXAMLToolkit as suggested by Nate Diamond to find the
// ScrollViewer and add the event handler
editor.GetFirstDescendantOfType<ScrollViewer>().ViewChanged += editor_ViewChanged;
}
private void editor_ViewChanged(object sender, ScrollViewerViewChangedEventArgs e)
{
// when the RichEditBox scrolls, scroll the MarginScroller the same amount
double editor_vertical_offset = ((ScrollViewer)sender).VerticalOffset;
MarginScroller.ChangeView(0, editor_vertical_offset, 1);
}
private void editor_SizeChanged(object sender, SizeChangedEventArgs e)
{
// when the RichEditBox size changes, change the size of MarginNotes to match
string text = "";
editor.Document.GetText(TextGetOptions.None, out text);
margin_helper.Document.SetText(TextSetOptions.None, text);
MarginNotes.Height = margin_helper.ActualHeight;
}
这个方案可以运行,但由于滚动的应用直到 ViewChanged
事件被触发后才能生效,所以它的执行速度相当缓慢。我尝试使用 ViewChanging
事件,但出于某种原因它根本不会触发。此外,在快速滚动后,Grid
有时会位置不正确。
RichEditBox
上启用了VerticalScrollChaining
。您还可以尝试禁用RichEditBox
上的整个滚动并查看是否可以解决问题。您可能需要在SizeChanged
或类似事件上更新偏移量。 - Nate DiamondRichEditBox
上的滚动。 - Nate Diamond