1

In my application i have a console-like-control that displays infromation I send from various functions using:

Run run = new Run("FancyText");
run.FontSize = 15;
run.FontFamily = new System.Windows.Media.FontFamily("Consolas");
run.Foreground = FancyColor;
tbConsole.Inlines.Add(run);
tbConsole.Inlines.Add(new LineBreak());

However this slows down my programm drastically after adding a lot of textboxes. Am i doing something wrong or is this just what you can expect? (By the way if i instead of the adding Runs to the Textbox i use a Stackpanel and add Textboxes it works fine and fast)

Denis Schaf
  • 2,478
  • 1
  • 8
  • 17
  • Do you have a windows form application? If you are updating the textbox on the same thread that handles the form it could hurt performance. You can update the textbox value from a different thread, which could increase performance. Take a look at: https://stackoverflow.com/questions/519233/writing-to-a-textbox-from-another-thread – AsusT9 Jan 17 '19 at 14:57
  • im sorry i didnt mention it i thought having it in the tags is enough im using WPF and the inlines get added via Dispatcher on a seperate thread – Denis Schaf Jan 17 '19 at 15:02
  • @DenisSchaf I'm having the same problem - did you ever get to solve it? – Norbert Hüthmayr Dec 10 '20 at 00:43
  • @NorbertHüthmayr I use a vitualized stackpanel now and add Textboxes to it. Never got the runs to work as fast, if the text gets longer. This also gives you the advantage that you can style each run differently, for example using font colors etc. A virtualized stack panel makes sure that only the visible controls are loaded so even if you add 999999999 textbockes to it it will not slow down your program – Denis Schaf Dec 10 '20 at 08:32

1 Answers1

1

I have never been able to get this to run as fast as i wanted so i came up with a different approach which complies to MVVM. I created a virtualized stackpanel to contain textboxes that i create and add in code:

 <ScrollViewer Grid.Column="2" Name="consoleScroll" Background="Black">
    <ItemsControl  ItemsSource="{Binding Log}">
       <ItemsControl.ItemsPanel>
          <ItemsPanelTemplate>
             <VirtualizingStackPanel/>
          </ItemsPanelTemplate>
       </ItemsControl.ItemsPanel>
    </ItemsControl>
 </ScrollViewer>

Code:

public ObservableCollection<System.Windows.Controls.Control> Log
{
    get { return (ObservableCollection<System.Windows.Controls.Control>)this.GetValue(LogProperty); }
    set { this.SetValue(LogProperty, value); }
}

// Using a DependencyProperty as the backing store for Log.  This enables animation, styling, binding, etc...
public static readonly DependencyProperty LogProperty =
    DependencyProperty.Register(nameof(Log), typeof(ObservableCollection<System.Windows.Controls.Control>), typeof(ViewModel), new PropertyMetadata(default(ObservableCollection<System.Windows.Controls.Control>)));

//Code to call in a function
TextBox tb = new TextBox();
tb.Foreground = new SolidColorBrush(Colors.Hotpink);
tb.HorizontalContentAlignment = HorizontalAlignment.Left;
tb.Text = "my nice string";
Log.Add(tb);

The resulting console window works as expected and supports multi color. Needed to censor parts of it... Resulting console window

Denis Schaf
  • 2,478
  • 1
  • 8
  • 17