Desidero rilevare (preferibilmente attraverso un evento) quando un contenuto è aggiunto, modificato, ecc. In un FlowDocument
e quando lo fa voglio un FlowDocumentScrollViewer
visualizzare lo FlowDocument
per scorrere automaticamente fino alla fine .Detect FlowDocument Change and Scroll
risposta
È possibile rilevare le modifiche nel FlowDocument
creando un intervallo di testo e monitorandolo per le modifiche. Scorrere verso il basso è più difficile perché devi trovare lo ScrollViewer
. Anche per le prestazioni non si desidera ripetere tutti i calcoli di scorrimento ad ogni modifica, quindi è necessario utilizzare DispatcherOperations
.
Mettere tutto insieme, questo codice dovrebbe fare il trucco:
var range = new TextRange(flowDocument.ContentStart, flowDocument.ContentEnd);
object operation = null;
range.Changed += (obj, e) =>
{
if(operation==null)
operation = Dispatcher.BeginInvoke(DispatcherPriority.Input, new Action(() =>
{
operation = null;
var scrollViewer = FindFirstVisualDescendantOfType<ScrollViewer>(flowDocument);
scrollViewer.ScrollToBottom();
});
};
dove FindFirstVisualDescendantOfType
è una semplice ricerca di prefisso in profondità dell'albero visiva utilizzando VisualTreeHelper.GetChildrenCount()
e VisualTreeHelper.GetChild()
e restituendo il primo visiva trovato del specificato genere.
Si noti che per la generalità completa non precompasso scrollViewer nella parte superiore del codice poiché il modello di FlowDocumentScrollViewer
può essere modificato. Se questo non accadrà, questo codice può essere accelerato chiamando .ApplyTemplate()
sulla FlowDocumentScrollViewer
e poi calcolando scrollViewer
prima del gestore di eventi è registrato:
var range = new TextRange(flowDocument.ContentStart, flowDocument.ContentEnd);
object operation = null;
flowDocument.ApplyTemplate();
var scrollViewer = FindFirstVisualDescendantOfType<ScrollViewer>(flowDocument);
range.Changed += (obj, e) =>
{
if(operation==null)
operation = Dispatcher.BeginInvoke(DispatcherPriority.Input, new Action(() =>
{
operation = null;
scrollViewer.ScrollToBottom();
});
};
Nota che non possiamo semplicemente chiamare scrollViewer.GetTemplateChild("PART_ContentHost")
e saltare la ricerca ad albero visuale perché GetTemplateChild
è protetto.
Si sta utilizzando un RichTextBox per eseguire la modifica? In tal caso dovresti essere in grado di agganciare lo the TextChanged
event e chiamare il the ScrollToVerticalOffset
method con il valore da the ViewportHeight
property.
No. Utilizzo di FlowDocumentScrollViewer, non RichTextBox. –
Una volta collegati ad un TextChanged Event, si può semplicemente utilizzare:
// Showing Last Block
YourReader.Document.Blocks.LastBlock.BringIntoView();
// Or.. showing the last Inline
(YourReader.Document.Blocks.LastBlock as Paragraph).Inlines.LastInline.BringIntoView();
Ma, questo funziona solo su un FlowDocumentPageViewer, ed anche su un FlowDocumentReader (con pagine ViewingModes), per FlowDocumentScrollViewer si dovrebbe usare l'albero visivo come menzionato
public static ScrollViewer FindScroll(Visual visual)
{
if (visual is ScrollViewer)
return visual as ScrollViewer;
ScrollViewer searchChiled = null;
DependencyObject chiled;
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(visual); i++)
{
chiled = VisualTreeHelper.GetChild(visual, i);
if (chiled is Visual)
searchChiled = FindScroll(chiled as Visual);
if (searchChiled != null)
return searchChiled;
}
return null;
}
ScrollViewer scroller = FindScroll(YourReader as Visual);
if (scroller != null)
(scroller as ScrollViewer).ScrollToBottom();
Sto usando solo un FlowDocument e FlowDocumentscrollViewer.La soluzione BringIntoView sopra funziona perfettamente per me. Non avevo bisogno di VisualTreeHelper La mia soluzione è usare Dispatcher.Invoke per scrivere creare il paragrafo, memorizzare quel paragrafo come variabile e poi Dispatcher.Invoke di nuovo per portarlo in vista. Questo sembra il metodo più semplice. –
È possibile utilizzare il seguente metodo di estensione per ottenere lo spettatore di scorrimento interno:
public static class FlowDocumentScrollViewerExtensions
{
public static ScrollViewer GetScrollViewer(this FlowDocumentScrollViewer element) {
if (element == null) {
throw new ArgumentNullException(nameof(element));
}
return element.Template?.FindName("PART_ContentHost", element) as ScrollViewer;
}
}
Inoltre è possibile utilizzare questi metodi di estensione prima di aggiungere contenuti per controllare la posizione di scorrimento ScrollViewer stesso (nel caso in cui si desidera scorrere - solo- se lo spettatore di scorrimento era già alla fine, per esempio):
public static class ScrollViewerExtensions
{
public static bool IsAtHome(this ScrollViewer element) {
if (element == null) {
throw new ArgumentNullException(nameof(element));
}
return element.VerticalOffset <= 0;
}
public static bool IsAtEnd(this ScrollViewer element) {
if (element == null) {
throw new ArgumentNullException(nameof(element));
}
return element.VerticalOffset >= element.ScrollableHeight;
}
}
Successivamente basta chiamare scrollViewer.ScrollToEnd(), per esempio.
- 1. javascript: detect scroll end
- 2. Copia di una FlowDocument a Second FlowDocument
- 3. JQuery Detect Scorri in basso
- 4. Detect comando vuoto
- 5. Ruby Detect metodo
- 6. SWT DateTime change change
- 7. Detect Browser Close su Asp.net
- 8. VB Detect Tempo di inattività
- 9. FlowDocument Force a PageBreak (BreakPageBefore)
- 10. WPF FlowDocument - Posizione carattere assoluto
- 11. Converti FlowDocument in testo semplice
- 12. Come convertire FlowDocument in rtf
- 13. Disabilita Orientamento Change
- 14. javascript canvas detect click on shape
- 15. jQuery detect css background-image finish download
- 16. Java JTable detect Colonna ridimensionata dall'utente
- 17. ipad detect quando UIPopoverControllers sono stati scaricati
- 18. Change classloader
- 19. Change AVMetadataItem
- 20. C'è qualche evento "on DOM change"?
- 21. Ridurre l'interlinea in un TextBlock/FlowDocument
- 22. Evita più colonne nella stampa FlowDocument
- 23. Problema di memoria FlowDocument in C#
- 24. Nascondi barra degli strumenti in WPF FlowDocument
- 25. WPF FlowDocument Adatta alla pagina Pagina
- 26. Come fare un drag and drop su una lista dinamica all'interno di un div con scroll?
- 27. header and footer and freemarker
- 28. Come eseguire lo scroll scroll reset con nuovo contenuto Ajax
- 29. gitosis change server
- 30. jQuery change input type
Non ho avuto bisogno di questo con il codice dell'albero visivo FlowDocument e FlowDocumentScrollViewer. Solo 2 invoca, 1 per creare e aggiungere il paragrafo da una stringa e 1 per visualizzare quel paragrafo. –