Odrai
Odrai

Reputation: 2353

WPF TextBox performance

I am developing an application which retrieves data in a separate thread. A delegate is 'called' within the thread to get the data in a viewmodel. A string property will be used to set the text of a WPF TextBox (databinding).

ViewModel

private string _resultText;
public string ResultText
{
    get
    {
        return _resultText;
    }
    set
    {
        _resultText = value;
        RaisePropertyChanged();
    }
}

XAML

<TextBox Name="tbxResult" Text="{Binding ResultText, Mode=TwoWay}" TextWrapping="NoWrap" Padding="10,10,10,10" IsReadOnly="True"/>

The thread is retrieving a lot of data, which causes a performance issue. The UI is freezed until all data is retrieved. I already tried to use the Binding IsAsync="True" property, TextWrapping="NoWrap", calling the Dispatcher.Invoke in the setter of ResultText and checked the question 'slow-wpf-textbox'.

None of the provided solution improves the performance.

Executing the following code causes the same (performance) issue:

private void btnRetrieveResultData_Click(object sender, RoutedEventArgs e)
{
    for (int i = 0; i < 3000; i++)
    {
        tbxResult.Dispatcher.Invoke(() =>
        {
            tbxResult.AppendText("testMessage" + i);
        });
    }
}

What is the solution/ implementation to handle a lot of data and display it in a TextBox? (It could be another control which provides scrolling and the option to select text).

Upvotes: 2

Views: 3397

Answers (2)

Subhash Saini
Subhash Saini

Reputation: 274

If you are setting property of TextBox to IsReadOnly="True" then i suggest please use TextBlock instead of using the TextBox because, Textbox uses 30 element to become an control while textblock uses only 1.

Upvotes: 0

Evk
Evk

Reputation: 101463

I'm not sure I understand your problem but I will use "Executing the following code causes the same (performance) issue", changing i to 300.000 to add more text to textbox. Changing that to:

   private void ButtonClicked(object sender, RoutedEventArgs e) {
        Task.Run(() =>
        {
            for (int i = 0; i < 300000; i++) {
                tbxResult.Dispatcher.Invoke(() => {
                    tbxResult.AppendText("testMessage" + i + "\r\n");
                }, DispatcherPriority.Background);
            }
        });
    }

Adds lines to textbox in a very fluid fashion without any UI freezes and you can actually manually scroll textbox while items are being added.

Upvotes: 7

Related Questions