Прокрутка WPF FlowDocumentScrollViewer из кода?
У меня есть FlowDocumentScrollViewer, который я хочу автоматически прокрутить вниз при добавлении текста.
<FlowDocumentScrollViewer Name="Scroller">
<FlowDocument Foreground="White" Name="docDebug" FontFamily="Terminal">
<Paragraph Name="paragraphDebug"/>
</FlowDocument>
</FlowDocumentScrollViewer>
в коде я добавляю строки в абзац, но когда есть много текста, я бы хотелось бы иметь возможность просто прокручивать вниз с помощью кода вместо того, чтобы пользователь делал это.
какие предложения?
5 ответов
другие ответы, приведенные здесь, немного озадачивают, так как я не вижу никакого публичного свойства "ScrollViewer" в FlowDocumentScrollViewer.
я взломал проблему, как это. Помните, что этот метод может вернуть null во время инициализации:
public static ScrollViewer FindScrollViewer(this FlowDocumentScrollViewer flowDocumentScrollViewer)
{
if (VisualTreeHelper.GetChildrenCount(flowDocumentScrollViewer) == 0)
{
return null;
}
// Border is the first child of first child of a ScrolldocumentViewer
DependencyObject firstChild = VisualTreeHelper.GetChild(flowDocumentScrollViewer, 0);
if (firstChild == null)
{
return null;
}
Decorator border = VisualTreeHelper.GetChild(firstChild, 0) as Decorator;
if (border == null)
{
return null;
}
return border.Child as ScrollViewer;
}
попробуй:
Scroller.ScrollViewer.ScrollToEnd();
где "Scroller" - это имя вашего FlowDocumentScrollViewer.
редактировать: я написал этот ответ слишком быстро. FlowDocumentScrollViewer не предоставляет свойство ScrollViewer. Я фактически расширил класс FlowDocumentScrollViewer и реализовал свойство ScrollViewer самостоятельно. Вот реализация:
/// <summary>
/// Backing store for the <see cref="ScrollViewer"/> property.
/// </summary>
private ScrollViewer scrollViewer;
/// <summary>
/// Gets the scroll viewer contained within the FlowDocumentScrollViewer control
/// </summary>
public ScrollViewer ScrollViewer
{
get
{
if (this.scrollViewer == null)
{
DependencyObject obj = this;
do
{
if (VisualTreeHelper.GetChildrenCount(obj) > 0)
obj = VisualTreeHelper.GetChild(obj as Visual, 0);
else
return null;
}
while (!(obj is ScrollViewer));
this.scrollViewer = obj as ScrollViewer;
}
return this.scrollViewer;
}
}
я столкнулся с подобной проблемой: я хотел текстовая область который может содержать мой текст, может обернуть его, он заполняет родительский элемент управления и прокручивается.
сначала я попытался использовать TextBlock С ScrollViewer и я думаю, что это сработало, но по какой-то причине я хотел использовать FlowDocument вместо с FlowDocumentScrollViewer. Последнее не сработало, и я просто не мог оставить бой без присмотра. поэтому я попытался найти решения, и вот как я попал сюда. Я попытался применить обходные пути, представленные в ответах на исходный вопрос, однако ни одно из решений не сработало для меня (я использую .NET 4.5, возможно, он работает в других версиях, но я не знаю об этом).
Я пробовал использовать один FlowDocument сам по себе, но элемент управления содержит некоторые элементы пользовательского интерфейса, которые я не хотел. Поэтому я придумал другое решение.
<ScrollViewer VerticalScrollBarVisibility="Auto">
<FlowDocumentScrollViewer HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden">
<FlowDocument>
Это верно. Он работает! Зову ScrollViewer.ScrollToBottom() просто работает! The ScrollViewer включает прокрутку и FlowDocumentScrollViewer удаляет элементы пользовательского интерфейса от FlowDocument. Надеюсь, это поможет!
видимо, у моей конструкции был недостаток, потому что таким образом FlowDocument не прокручивается через колесо прокрутки мыши. Однако установка FlowDocumentScrollViewer управления IsHitTestVisible свойство False решает эту.
этот вопрос был задан 7 лет назад, сейчас у меня такая же проблема, и я нашел простое решение. Следующий код добавляет раздел в Flowdocument, который то же самое к абзацу, а затем прокрутите до конца.
private void addSection(Section section)
{
section.Loaded += section_Loaded;
fdoc.Blocks.Add(section);
}
private void section_Loaded(object sender, RoutedEventArgs e)//scroll to end
{
var sec = sender as Section;
if (sec != null)
{
sec.BringIntoView();
}
}
Это может быть очень поздний ответ, но я нашел способ сделать это.
//after your FlowDocumentScrollViewer(for example, x:Name="fdsv") loaded
ScrollViewer sv = fdsv.Template.FindName("PART_ContentHost", fdsv) as ScrollViewer;
sv.ScrollToBottom();
sv.ScrollToTop();
sv.ScrollToVerticalOffset(100);
// etc.
Регистрация IScrollInfo и ScrollViewer для сведения.
надеюсь, это вам поможет.