tags:

views:

126

answers:

3

I would like simmulate Console text output in my WPF app but when I add new lines in TextBox I should use scroll bar to see last added text but I want to see last added text but for firsts lines use scroll bar

<TextBox TextWrapping="Wrap" AcceptsReturn="True" VerticalScrollBarVisibility="Auto"
                   Text="{Binding Path=Data, Mode=TwoWay}" />`
A: 

Use the ScrollToLine method of TextBox (and the LineCount property to know how many lines there are) after adding text in order to make sure that the just-added line is visible.

Timores
A: 

Hi Janus,

Please consider scrolling the textbox directly from code behind like this (e.g. when text changes):

private void SampleTextBox_TextChanged(object sender, TextChangedEventArgs e)
{
   if (SampleTextBox.LineCount != -1)
   {
      SampleTextBox.ScrollToLine(SampleTextBox.LineCount - 1);
   }
}

Please tell me if this helps.

Piotr Justyna
A: 

thanks for answers: I expected to do it from XAML but as I undestood it's only possible from code behind so here is my implimentation now with checkbox for stop ScrollToEnd function:

public partial class MainWindow : Window
{
    private bool isScrollToEnd; 
    Timer timer; 

    public double WaitTime 
    {
        get { return waitTime / 1000; }
        set { waitTime = value * 1000; }
    }
    private double waitTime;

    public MainWindow()
    {
        InitializeComponent();
        isScrollToEnd = true;
        waitTime = 5000;
        tbWaitTime.DataContext = this;
        timer = new Timer(waitTime);
        timer.Elapsed += new ElapsedEventHandler(timer_Elapsed);
    }

    // событие изменения текста в контроле tbConsole
    private void tbConsole_TextChanged(object sender, TextChangedEventArgs e)
    {
        if (tbConsole.LineCount != -1 && isScrollToEnd)
        {
            tbConsole.ScrollToLine(tbConsole.LineCount - 1);
            cbIsScrolling.IsChecked = false;
        } 
    }

   private void cbIsScrolling_Click(object sender, RoutedEventArgs e)
    {
        if ((bool)cbIsScrolling.IsChecked)
        {
            isScrollToEnd = !(bool)cbIsScrolling.IsChecked;
            isScrollToEnd = false;
            timer.Interval = waitTime;
            timer.Start(); 
            return;
        }
        isScrollToEnd = true;
        timer.Stop();
        cbIsScrolling.IsChecked = false;
    }

    void timer_Elapsed(object sender, ElapsedEventArgs e)
    {
        timer.Stop();
        isScrollToEnd = true;
    }
}

and here is XAML code:

 <StackPanel  Grid.Column="1" Grid.Row="2" Grid.ColumnSpan="2" Grid.RowSpan="2">
        <StackPanel Orientation="Horizontal" HorizontalAlignment="Right" Margin="0,3,10,2" VerticalAlignment="Top">
            <Label Content="Stop autoscrolling for:" />
            <TextBox Name="tbWaitTime" Text="{Binding Path=WaitTime}"
                     MinWidth="25" MaxWidth="50" Margin="5,0,0,0" />
            <Label Content="sec."/>
            <CheckBox Name="cbIsScrolling"  
                      HorizontalAlignment="Right" VerticalAlignment="Center"
                      Click="cbIsScrolling_Click" />
        </StackPanel>
        <TextBox Name="tbConsole" 
                     Background="LightGoldenrodYellow" Padding="5" Height="100"
                     VerticalScrollBarVisibility="Auto"
                     TextWrapping="Wrap" 
                     AcceptsReturn="True" 
                     Text="{Binding Path=Data, Mode=TwoWay}" TextChanged="tbConsole_TextChanged" />
    </StackPanel>
Janus