I've create a solution, mixed the information of varius post.
Its a form, that contains a label and one textbox. The console output is redirected to the textbox.
There are too a class called ConsoleView that implements three publics methods: Show(), Close(), and Release(). The last one is for leave open the console and activate the Close button for view results.
The forms is called FrmConsole. Here are the XAML and the c# code.
The use is very simple:
ConsoleView.Show("Title of the Console");
For open the console. Use:
System.Console.WriteLine("The debug message");
For output text to the console.
Use:
ConsoleView.Close();
For Close the console.
ConsoleView.Release();
Leaves open the console and enables the Close button
XAML
<Window x:Class="CustomControls.FrmConsole" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:CustomControls" mc:Ignorable="d" Height="500" Width="600" WindowStyle="None" ResizeMode="NoResize" WindowStartupLocation="CenterScreen" Topmost="True" Icon="Images/icoConsole.png"> <Grid> <Grid.RowDefinitions> <RowDefinition Height="40"/> <RowDefinition Height="*"/> <RowDefinition Height="40"/> </Grid.RowDefinitions> <Label Grid.Row="0" Name="lblTitulo" HorizontalAlignment="Center" HorizontalContentAlignment="Center" VerticalAlignment="Center" VerticalContentAlignment="Center" FontFamily="Arial" FontSize="14" FontWeight="Bold" Content="Titulo"/> <Grid Grid.Row="1"> <Grid.ColumnDefinitions> <ColumnDefinition Width="10"/> <ColumnDefinition Width="*"/> <ColumnDefinition Width="10"/> </Grid.ColumnDefinitions> <TextBox Grid.Column="1" Name="txtInner" FontFamily="Arial" FontSize="10" ScrollViewer.CanContentScroll="True" VerticalScrollBarVisibility="Visible" HorizontalScrollBarVisibility="Visible" TextWrapping="Wrap"/> </Grid> <Button Name="btnCerrar" Grid.Row="2" Content="Cerrar" Width="100" Height="30" HorizontalAlignment="Center" HorizontalContentAlignment="Center" VerticalAlignment="Center" VerticalContentAlignment="Center"/> </Grid>
The code of the Window:
partial class FrmConsole : Window { private class ControlWriter : TextWriter { private TextBox textbox; public ControlWriter(TextBox textbox) { this.textbox = textbox; } public override void WriteLine(char value) { textbox.Dispatcher.Invoke(new Action(() => { textbox.AppendText(value.ToString()); textbox.AppendText(Environment.NewLine); textbox.ScrollToEnd(); })); } public override void WriteLine(string value) { textbox.Dispatcher.Invoke(new Action(() => { textbox.AppendText(value); textbox.AppendText(Environment.NewLine); textbox.ScrollToEnd(); })); } public override void Write(char value) { textbox.Dispatcher.Invoke(new Action(() => { textbox.AppendText(value.ToString()); textbox.ScrollToEnd(); })); } public override void Write(string value) { textbox.Dispatcher.Invoke(new Action(() => { textbox.AppendText(value); textbox.ScrollToEnd(); })); } public override Encoding Encoding { get { return Encoding.UTF8; } } } //DEFINICIONES DE LA CLASE #region DEFINICIONES DE LA CLASE #endregion //CONSTRUCTORES DE LA CLASE #region CONSTRUCTORES DE LA CLASE public FrmConsole(string titulo) { InitializeComponent(); lblTitulo.Content = titulo; Clear(); btnCerrar.Click += new RoutedEventHandler(BtnCerrar_Click); Console.SetOut(new ControlWriter(txtInner)); DesactivarCerrar(); } #endregion //PROPIEDADES #region PROPIEDADES #endregion //DELEGADOS #region DELEGADOS private void BtnCerrar_Click(object sender, RoutedEventArgs e) { Close(); } #endregion //METODOS Y FUNCIONES #region METODOS Y FUNCIONES public void ActivarCerrar() { btnCerrar.IsEnabled = true; } public void Clear() { txtInner.Clear(); } public void DesactivarCerrar() { btnCerrar.IsEnabled = false; } #endregion }
the code of ConsoleView class
static public class ConsoleView { //DEFINICIONES DE LA CLASE #region DEFINICIONES DE LA CLASE static FrmConsole console; static Thread StatusThread; static bool isActive = false; #endregion //CONSTRUCTORES DE LA CLASE #region CONSTRUCTORES DE LA CLASE #endregion //PROPIEDADES #region PROPIEDADES #endregion //DELEGADOS #region DELEGADOS #endregion //METODOS Y FUNCIONES #region METODOS Y FUNCIONES public static void Show(string label) { if (isActive) { return; } isActive = true; //create the thread with its ThreadStart method StatusThread = new Thread(() => { try { console = new FrmConsole(label); console.ShowDialog(); //this call is needed so the thread remains open until the dispatcher is closed Dispatcher.Run(); } catch (Exception) { } }); //run the thread in STA mode to make it work correctly StatusThread.SetApartmentState(ApartmentState.STA); StatusThread.Priority = ThreadPriority.Normal; StatusThread.Start(); } public static void Close() { isActive = false; if (console != null) { //need to use the dispatcher to call the Close method, because the window is created in another thread, and this method is called by the main thread console.Dispatcher.InvokeShutdown(); console = null; StatusThread = null; } console = null; } public static void Release() { isActive = false; if (console != null) { console.Dispatcher.Invoke(console.ActivarCerrar); } } #endregion }
I hope this result usefull.