gpt4 book ai didi

textbox - 将 Grid 的垂直滚动位置与 RichEditBox 或 TextBox 匹配

转载 作者:行者123 更新时间:2023-12-04 12:54:19 28 4
gpt4 key购买 nike

我有一个带有 RichEditBox 的 Windows 应用商店应用程序(编辑)和一个 Grid (边注)。

我需要始终匹配两个元素的垂直滚动位置。这样做的目的是允许用户在文档的页边空白处添加注释。

我已经根据光标位置确定了笔记定位 - 当添加笔记时,文本选择由光标前的所有内容组成。然后将该选择添加到第二个不可见的 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 的底部时control,按回车几次,光标消失了。 ScrollViewer不随光标自动滚动。

我尝试添加 C# 代码来检查光标的位置,将其与 VerticalOffset 进行比较。和编辑器的高度,然后相应地调整滚动。这有效,但速度非常慢。最初我把它放在 KeyUp 上当我输入一个句子时使应用程序停止的事件。之后我将其设置为 5 秒计时器,但这仍然降低了应用程序的性能,也意味着在光标消失和 RichEditBox 之间可能会有 5 秒的延迟。滚动。

技术二

我也试过只放 MarginNotes在自己的 ScrollViewer ,并以编程方式设置 VerticalOffset基于我的 RichEditBox s 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>

相关事件处理程序

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有时在快速滚动后定位错误。

最佳答案

因此,使这变得困难的是文本的大小或文本在不同类型的 TextBox 中的位置意味着同步滚动条并不能保证您同步文本。话虽如此,这就是你如何做到的。

void MainPage_Loaded(object sender, RoutedEventArgs args)
{
MyRichEditBox.Document.SetText(Windows.UI.Text.TextSetOptions.None, MyTextBox.Text);
var textboxScroll = Children(MyTextBox).First(x => x is ScrollViewer) as ScrollViewer;
textboxScroll.ViewChanged += (s, e) => Sync(MyTextBox, MyRichEditBox);
}

public void Sync(TextBox textbox, RichEditBox richbox)
{
var textboxScroll = Children(textbox).First(x => x is ScrollViewer) as ScrollViewer;
var richboxScroll = Children(richbox).First(x => x is ScrollViewer) as ScrollViewer;
richboxScroll.ChangeView(null, textboxScroll.VerticalOffset, null);
}

public static IEnumerable<FrameworkElement> Children(FrameworkElement element)
{
Func<DependencyObject, List<FrameworkElement>> recurseChildren = null;
recurseChildren = (parent) =>
{
var list = new List<FrameworkElement>();
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(parent); i++)
{
var child = VisualTreeHelper.GetChild(parent, i);
if (child is FrameworkElement)
list.Add(child as FrameworkElement);
list.AddRange(recurseChildren(child));
}
return list;
};
var children = recurseChildren(element);
return children;
}

决定何时调用同步很棘手。也许在 PointerReleased、PointerExit、LostFocus、KeyUp 上——有很多滚动方式才是真正的问题。您可能需要处理所有这些。但是它就是这样啊。至少你可以。

祝你好运。

关于textbox - 将 Grid 的垂直滚动位置与 RichEditBox 或 TextBox 匹配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21674787/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com