|
Advanced Search Add to IE Search |
|
|
|
||||||||||||||||
It's sometimes useful to be able to relay information back to the user with line by line text. The need is to provide a listing of information forming a trace. An example most developers will be familiar with is the Visual Studio output view pane during build and load etc.
The usual option in the Forms environment without such a control is to modify a List View Control, Multiline Edit Control etc. It's possible to achieve good results using these — but there can be a bit of work required to make them behave in a way they weren't really designed for. It would be much more convenient to have something ready to use and built for the task, so I decided to fill this gap in my toolbox and write one based on UserControl. It's a fundamental interface device that predates any GUI control so it provided an interesting development task. If you are looking for an output console in your .NET Forms development I hope this control will meet your needs.
Those interested in control development might find some of the control code useful. In this respect I have demonstrated using AutoScroll combined with painting text etc. The code may be helpful to those learning to use the AutoScroll feature.
To incorporate the control into your C# Forms Project add the Files ConsoleWriter.cs, and LockAssistant.cs to your project. These files share the namespace Elements. You can refer to Elements.ConsoleWriter or add using Elements; at the top of your code file to be able to refer to just the class. Of course if you don't want the two files or to use the namespace Elements you are free to recompose them to suit your needs. However, it will be easier to add any revisions or use other controls I might publish in the future that use this namespace if you keep them intact.
To code your own ConsoleWriter member you can do something like:
//MyForm.cs
using Elements;
//declare a variable of type ConsoleWriter
private ConsoleWriter m_ConsoleWriter;
//provide a property accessor (optional)
public ConsoleWriter MyConsoleWriter
{
get
{
return m_ConsoleWriter;
}
private set
{
m_ConsoleWriter = value;
}
}
public class MyForm()
{
//create and add it to the controls
MyConsoleWriter = new ConsoleWriter();
MyConsoleWriter.Dock = DockStyle.Fill;
Controls.Add(MyConsoleWriter);
}
If you use form designers you should find the ConsoleWriter available in the Toolbox once it is added to your project. You can drag it onto your design surface from there.
The control derives from UserControl so the inherited functionality is applicable to the ConsoleWriter where relevant.
There are two methods exposed by the ConsoleWriter itself:
Add( string text )
This takes a string parameter and is the text you want to output to the ConsoleWriter.
The principle behind this one means of adding output to the control is that the user can either send in one line of text, or text that contains multiple lines. The Add function parses the input text for line feeds and processes each of those lines as a new row. There are many ways to prepare strings as multiple lines with .NET. One of the most useful is StringBuilder from System.Text. This allows you to build up a string and includes a method AppendLine which will embed line feeds in the string output available from its ToString() method.
Clear()
This is a parameterless method that instructs ConsoleWriter to clear the console.
There are three properties exposed by the ConsoleWriter:
LineBufferLimit
In order to be able to scroll back through previous output, the control retains a buffer of lines. You can set this to a positive integer value to suit your needs. The default value is 1000. If you set it to zero or below then the buffer will grow unchecked. A call to Clear() will empty the buffer. The buffer is a SortedDictionary that holds all the information the control needs to paint the text from the current scroll position.
AutoRemoveCount
If there is a LineBufferLimit greater than zero, e.g. the default of 1000, when that limit is reached the value of AutoRemoveCount - the default is 250 - items are removed from the top of the buffer. Therefore in the default mode (1000/250), once the LineBufferLimit has been reached there are always between 750 and 1000 items in the buffer. If you have a LineBufferLimit greater than zero but an AutoRemoveCount of zero then the buffer will behave like a FIFO queue with a fixed size once the limit is reached. This is not advised unless the effect is desired as the list can never enter a Stationary mode. (See the section headed Trailing for more about modes).
BandColor
ConsoleWriter supports alternating colored lines, which appear as bands like listing paper if the chosen color is pale enough. The default color is SystemColors.ControlLight. The background color defaults to SystemColors.Window and the text color defaults to SystemColors.WindowText.
If you want the optimization of no BandColor, e.g. a plain background, then set the BandColor to the BackColor value - those interested in the control code will note that the OnPaintBackground override of ConsoleWriter.cs checks for this equality and makes no attempt to paint bands of the same color.
Set an alternative BandColor value if required. This code example sets the control to a plain display:
//MyForm.cs
...
MyConsoleWriter.BandColor = ConsoleWriter.BackColor;
...
Use the BackColor property to set an alternative background color, and similarly set the ForeColor derived property to change the color of text.
//MyForm.cs
...
MyConsoleWriter.BackColor = System.Drawing.Color.White;
MyConsoleWriter.BandColor = System.Drawing.Color.PaleGreen;
MyConsoleWriter.ForeColor = System.Drawing.Color.Black;
...
Font
I have chosen to default the ConsoleWriter Font to Courier New 8.25 a fixed character width font which provides a standard appearance and easily read output. You can choose any font for the control by setting the Font property at construction e.g. For designer hosted composition these properties are available in the properties task pane of Visual studio.
//MyForm.cs
...
MyConsoleWriter.Font = new System.Drawing.Font("Arial", 11.25f,
System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
...
The ConsoleWriter has two modes it can be in, either Stationary or Trailing. If Trailing the control keeps the latest output visible at the bottom of the screen, this means that the window is being scrolled automatically and the older lines beyond the display capacity of the ClientRectangle Height will scroll off screen. Those interested in how this is achieved using the functions related to AutoScroll can see this in the Controls InternalRefresh method. The AutoScrollMinSize property is checked and, if necessary, reset, and if the control is in Trailing mode the AutoScrollPosition is set to correspond with the last line, e.g. the most recent.
When Stationary the control is at a fixed point in the AutoScroll DisplayRectangle - this allows the user of the program to scroll back through the current buffer of lines.
There is no programming or control properties for the developer employing the control to consider in respect of these two modes. I have made this feature as natural as possible for the end user. The control starts life in Trailing mode and will therefore show latest output and scroll automatically. If the user scrolls the display up at all then the control will automatically enter the Stationary mode.
When the control is scrolled back down to the end of the list then the Trailing mode will automatically be engaged again.
The control responds in a natural manner to scrolling using the mouse and scrollbar controls. The scroll arrows when pressed move the display by a line increment either up or down. Direct manipulation of the scroll box (thumb) moves the display with the standard scroll behaviour as does mouse clicking within the scrollbar shaft itself. The control also responds normally to mousewheel activity.
Control developers can observe the OnScroll and OnMouseWheel overrides to see how this is implemented. You will note that the VerticalScroll.SmallChange is set to the LineHeight to ensure that the one line increment can be achieved.
When the mousewheel attempts to move the display beyond the end of the list the control will automatically enter the Trailing mode. This is also the case for the scroll arrow. I have not implemented this behaviour when the thumb is moved to the end of the list because this allows the user to remain in Stationary mode when observing values at the end of the list. This is most appreciable when the control is rapidly receiving values.
The control also responds to the following command keys:
Ctrl-Home scrolls the display to top of the DisplayRectangle and leaves the control in Stationary mode.
Ctrl-End scrolls the to the end of the DisplayRectangle and leaves the control in Trailing mode (A single click to the thumb will halt Trailing and enter Stationary mode).
PageUp and PageDown scroll the display by the display height. If the PageDown key attempts to move beyond the end of the list the control will automatically enter the Trailing mode.
ArrowUp and ArrowDown scroll the display by the line height. If the ArrowDown key attempts to move beyond the end of the list the control will automatically enter the Trailing mode.
Control developers can observe the ProcessCmdKey override to see how this is implemented.
To help you evaluate and understand how the ConsoleWriter works and behaves I have created a sample MDI Application. It's a meaningless application in itself — it's sole purpose is to show you one or more ConsoleWriters working.
To keep a constant supply of information available to the ConsoleWriter the main form of the application has a timer. The child windows of this application all contain a ConsoleWriter and they can subscribe to a timer event published by the main form. When the main form receives the timers elapsed event it broadcasts this event to the subscribing child windows and they in turn write this information to the ConsoleWriter. To provide further test output to the ConsoleWriter the child form also supports two commands. One is to list the current environment and the other to list the currently loaded module.
You can alter the interval period of the main form timer via a dialog provided under the main forms options menu. You can alter the settings for the ConsoleWriter control programatically in the ConsoleChild Create method.
The bitmaps used in the menus and buttons are public domain and available from www.famfamfam.com
Version 1.0.0 Released: 8th January 2009
Version 1.0.1 Released: 17th January 2009 - Fixes to OnResize override code that could cause a refresh problem| You must Sign In to use this message board. | |||||||||||||||
|
|||||||||||||||
|
|||||||||||||||
|
|||||||||||||||
|
|||||||||||||||
General
News
Question
Answer
Joke
Rant
Admin
|
PermaLink |
Privacy |
Terms of Use
Last Updated: 20 Jan 2009 Editor: Sean Ewington |
Copyright 2009 by TwinLane Everything else Copyright © CodeProject, 1999-2009 Web18 | Advertise on the Code Project |