Mam pole tekstowe z właściwością .Multiline ustawioną na true. W regularnych odstępach czasu dodam do niego nowe wiersze tekstu. Chciałbym, aby pole tekstowe automatycznie przewijało się do najniższego wpisu (najnowszego) za każdym razem, gdy dodawany jest nowy wiersz. Jak to osiągnąć?
295
Odpowiedzi:
Jeśli go użyjesz
TextBox.AppendText(string text)
, nastąpi automatyczne przewinięcie do końca nowo dołączonego tekstu. Pozwala to uniknąć migotania paska przewijania, jeśli wywołujesz go w pętli.Zdarza się również, że jest o rząd wielkości szybszy niż konkatenacja na
.Text
nieruchomości. Chociaż może to zależeć od tego, jak często go nazywasz; Testowałem z ciasną pętlą.Nie przewinie się, jeśli zostanie wywołane przed wyświetleniem pola tekstowego lub jeśli pole tekstowe nie będzie widoczne (np. W innej zakładce TabPanel). Zobacz TextBox.AppendText () nie przewijający się automatycznie . To może, ale nie musi być ważne, w zależności od tego, czy potrzebujesz automatycznego przewijania, gdy użytkownik nie widzi pola tekstowego.
Wydaje się, że alternatywna metoda z innych odpowiedzi również nie działa w tym przypadku. Jednym sposobem jest dodatkowe przewijanie
VisibleChanged
zdarzenia:Wewnętrznie
AppendText
robi coś takiego:Ale nie powinno być żadnego powodu, aby robić to ręcznie.
(Jeśli sam go zdekompilujesz, zobaczysz, że używa on prawdopodobnie bardziej wydajnych metod wewnętrznych i ma coś, co wydaje się być drobnym przypadkiem szczególnym.)
źródło
tb.Text += ....
Możesz użyć następującego fragmentu kodu:
który automatycznie przewinie do końca.
źródło
Wygląda na to, że interfejs zmienił się w .NET 4.0. Istnieje następująca metoda, która pozwala spełnić wszystkie powyższe kryteria. Jak sugerował Tommy Engebretsen, umieszczenie go w module obsługi zdarzeń TextChanged sprawia, że jest on automatyczny.
źródło
TextBoxBase
klasie wSystem.Windows.Controls.Primitives
przestrzeni nazw (PresentationFramework
asembler, WPF). Ta metoda nie istnieje i nie będzie działać w WinForms, którychTextBox
klasa dziedziczyTextBoxBase
poSystem.Windows.Forms
przestrzeni nazw (System.Windows.Forms
asembler, WinForms).ScrollToEnd()
może być bardzo słaba wydajność. W mojej aplikacji stanowiło to ponad 50% czasu profilowania.Spróbuj dodać sugerowany kod do zdarzenia TextChanged:
źródło
nie działało dla mnie (Windows 8.1, bez względu na przyczynę).
A ponieważ wciąż korzystam z platformy .NET 2.0, nie mogę używać ScrollToEnd.
Ale to działa:
VB.NET:
źródło
Musiałem dodać odświeżenie:
źródło
Znalazłem prostą różnicę, której nie uwzględniono w tym wątku.
Jeśli wykonujesz wszystkie
ScrollToCarat()
połączenia w ramachLoad()
zdarzenia formularza , nie działa. Właśnie dodałem swojeScrollToCarat()
wezwanie doActivated()
wydarzenia w moim formularzu i działa dobrze.Edytować
Ważne jest, aby przewijać to tylko przy pierwszym uruchomieniu
Activated
zdarzenia formularza (nie przy kolejnych aktywacjach), lub będzie ono przewijać się przy każdej aktywacji formularza, czego prawdopodobnie nie chcesz.Jeśli więc łapiesz tylko
Activated()
zdarzenie, aby przewinąć tekst podczas ładowania programu, możesz po prostu anulować subskrypcję zdarzenia w samej procedurze obsługi zdarzeń, a zatem:Jeśli masz inne rzeczy do zrobienia za każdym razem, gdy formularz jest aktywowany, możesz ustawić wartość
bool
true za pierwszym razemActivated()
zdarzenia, aby nie przewijać kolejnych aktywacji, ale nadal możesz robić inne rzeczy, które musisz zrobić robić.Ponadto, jeśli
TextBox
jest na karcie, że nie jestSelectedTab
,ScrollToCarat()
nie będzie miało wpływu. Musisz więc przynajmniej zaznaczyć tę zakładkę podczas przewijania. Możesz owinąć kod w paręYourTab.SuspendLayout();
iYourTab.ResumeLayout(false);
sparować, jeśli Twój formularz migocze.Koniec edycji
Mam nadzieję że to pomoże!
źródło
Spowoduje to przewinięcie do końca pola tekstowego, gdy tekst zostanie zmieniony, ale nadal pozwoli użytkownikowi przewinąć w górę
przetestowany na Visual Studio Enterprise 2017
źródło
Dla każdego, kto ląduje tutaj, oczekując implementacji formularzy internetowych, należy skorzystać z modułu obsługi zdarzeń endRequest Menedżera żądań strony ( https://stackoverflow.com/a/1388170/1830512 ). Oto, co zrobiłem dla TextBoxa na stronie treści ze strony wzorcowej, proszę zignorować fakt, że nie użyłem zmiennej do kontroli:
źródło
To działało tylko dla mnie ...
txtSerialLogging-> Text = "";
txtSerialLogging-> AppendText (s);
Próbowałem wszystkich powyższych przypadków, ale problem polega na tym, że w moim przypadku tekst może się zmniejszać, zwiększać, a także może pozostawać statyczny przez długi czas. środki statyczne, długość statyczna (linie), ale treść jest inna.
Tak więc pod koniec miałem do czynienia z sytuacją przeskakiwania jednej linii, gdy długość (linie) przez pewien czas pozostawała taka sama ...
źródło
Używam do tego funkcji:
źródło