Permalänk

WPF och RichTextBox

Hej, jag har ett problem i WPF och RichTextBox. Jag kodar i C#.

Min applikation skriver text till en RichTextBox ifrån en kolumn i en databas.

Jag har en event-hanterare för RichTextBox.TextChanged eventet, där jag läser ExtentHeight
från min RichTextBox för aktuell databas-post.

Men... ExtentHeight i min event-hanterare håller värdet för ExtentHeight ifrån föregående
databas-post.

Jag har kollat i debuggern att texten i min RichTextBox är korrekt, men ExtentHeight har föregående värde.

Vad gör jag för fel?

Kan någon hjälpa mig?

Följande förenklade applikation belyser mitt problem.
En RichTextBox, en Button och en TextBox.

private void Button_Click(object sender, RoutedEventArgs e)
{
var text = new TextRange(richTextBox.Document.ContentStart, richTextBox.Document.ContentEnd);
text.Text = "A multimillionaire is murdered, and his will leaves all his money to a beautiful young blonde. The murdered man's son thinks something is fishy, and a homicide cop sets out to find out who was behind the man's death. Complications ensue.";

textBox.Text = richTextBox.ExtentHeight.ToString();
}

Jag är tvungen att klicka två ggr på button för att få det korrekta värdet på ExtentHeight,

Per

Permalänk
Medlem

Har inte lekt med WPF, men hur ser den logiska ordningen ut när du tilldelar saker olika värden? Spontant så känns det som att du hämtar ut ExtentHeight innan den uppdaterats.

Visa signatur

Dator:
Intel Core i5 14600K 3.5 GHz 44MB
ASUS Prime Z790-P
G.Skill 32GB (2x16GB) DDR5 7200MHz CL 35 Triden
EVGA GeForce RTX 3070 8GB XC3 ULTRA

Permalänk

Du har i princip rätt Eroo. Jag fick hjälp av Slypenslyde på reddit (r/csharp) och han tipsade mig om
att använda "await Task.Delay(1000)" innan jag läser värdet på richTextBox.ExtentHeight.

Han förklarade det med: "But what I keep finding in MAUI is sometimes the UI is really stubborn about updating and if you don't let the UI thread idle for about 250ms it won't update."

Och det fungerade!

Per

Permalänk
Medlem

Är det inte så att RichTextBox ärver från TextBoxBase som har ett event TextChanged?

Jag tänker att du borde ha en metod till där du reagerar på att texten förändras och då hämtar ut värdet från höjden.

Alltså något i stil med:

private void richTextBox_TextChanged(object sender, EventArgs e) { textBox.Text = richTextBox.ExtentHeight.ToString(); }

Permalänk

Jodå MickeBoy, jag försöker läsa ExtentHeight i min event-hanterare i Text_Changed, men ExtentHeight har inte uppdaterats med rätt värde (den har föregående värde)

Men med Slypenslydes fix (från reddit), await Task.Delay(1000) , så hinner värdet uppdateras korrekt av WPF ramverk, och då efteråt läser jag ut värdet på ExtentHeight . (Dock väntar jag bara 100ms, det funkar också).

Per

Permalänk
Medlem

Testa med följande och se om det fungerar:

private async void Button_Click(object sender, RoutedEventArgs e) { var text = new TextRange(richTextBox.Document.ContentStart, richTextBox.Document.ContentEnd); text.Text = "A multimillionaire is murdered, and his will leaves all his money to a beautiful young blonde. The murdered man's son thinks something is fishy, and a homicide cop sets out to find out who was behind the man's death. Complications ensue."; // Vänta på att UI uppdateras innan du hämtar ExtentHeight await Dispatcher.InvokeAsync(() => { textBox.Text = richTextBox.ExtentHeight.ToString(CultureInfo.InvariantCulture); }, DispatcherPriority.Background); }

Visa signatur

MSI PRO Z790-P WIFI | Intel i9 13900K | 128 GB DDR5
GTX 4070 12 GB
Samsung 990 Pro 4 TB | WD Black SN850X 2 TB Gen 4 | 2 x 1 TB Samsung 970 EVO Plus
3 x ASUS 27" | 1 x Philips 49"

Permalänk

Tack Superfrog!
Din lösning fungerar ju klockrent och är mycket mer elegant än min await Task.Delay().
Din lösning kommar jag att använda i min applikation.
(Får erkänna att jag aldrig hade kommit fram till den, lite för hög C#-nivå för mig)

Per

Permalänk
Medlem
Skrivet av pjakesson:

Tack Superfrog!
Din lösning fungerar ju klockrent och är mycket mer elegant än min await Task.Delay().
Din lösning kommar jag att använda i min applikation.
(Får erkänna att jag aldrig hade kommit fram till den, lite för hög C#-nivå för mig)

Per

Du får tacka ChatGPT, för jag kopierade helt sonika din fråga och klistrade in hos ChatGPT, kopierade dess kod och testade innan jag postade svaret Så ChatGPT ska ha all kredit.

Men jag höll på med ett projekt igår där dokumentationen rådde en att använda separata trådar för event-hantering, för att undvika liknande problem, så jag misstänkte att det var något sådant det handlade om. Men koden ChatGPT spottade ur sig för att lösa ditt problem hade jag aldrig någonsin kommit på själv.

Visa signatur

MSI PRO Z790-P WIFI | Intel i9 13900K | 128 GB DDR5
GTX 4070 12 GB
Samsung 990 Pro 4 TB | WD Black SN850X 2 TB Gen 4 | 2 x 1 TB Samsung 970 EVO Plus
3 x ASUS 27" | 1 x Philips 49"

Permalänk

Lite skrämmande att AI (ChatGPT) måste lösa ens programmerins-problem, men också bra såklart.

Tack för att du gav en bakgrund till lösningen Superfrog.

Per