Tuesday, July 14, 2009

Exercise for Part -1

I think the best thing to do here is, let's say I have some hypothetical layout that I want to achieve. Let's say one of the common layouts, favoured for years where we have a menu bar at the top, followed by a main content area, and a status bar area at the bottom. Let's see a mock up (designed as a simple WinForm) of what we are aiming for:


I think I have given you all the tools you need to carry out designing this sort of layout in WPF. Do you want a hint, I think you will need to use the StackPanel DockPanel Grid controls in order to get the job done.

If you're not sure how to do it. I shall give the XAML here below..

<Window x:Class="WPF_Tour_Beginners_Layout.PuttingItAllTogether"

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
WindowStartupLocation="CenterScreen"
Title="PuttingItAllTogether" Width="640" Height="480" >

<DockPanel Width="Auto" Height="Auto" LastChildFill="True">

<Menu Width="Auto" Height="20" Background="#FFA9D1F4"
DockPanel.Dock="Top">


<MenuItem Header="File">
<MenuItem Header="Save"/>
<Separator/>
<MenuItem Header="Exit"/>

MenuItem>

<MenuItem Header="Help">

<MenuItem Header="About"/>
MenuItem>
Menu>


<StackPanel Width="Auto" Height="31" Background="#FFCAC5C5"
Orientation="Horizontal" DockPanel.Dock="Bottom">

<Label Width="155" Height="23" Content="Status Bar Message...."
FontFamily="Arial" FontSize="10"/>

StackPanel>


<StackPanel Width="136" Height="Auto" Background="White">

<Button Margin="5,5,5,5" Width="Auto" Height="26" Content="button1"/>
<Button Width="126" Height="26" Content="button2" Margin="5,5,5,5"/>
<Button Width="126" Height="26" Content="button3" Margin="5,5,5,5"/>

StackPanel>


<Grid Width="Auto" Height="Auto" Background="#FFCC9393">

<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>

Grid.ColumnDefinitions>

<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>

Grid.RowDefinitions>

<Rectangle Fill="Aqua" Margin="10,10,10,10" Grid.Row="0" Grid.Column="0"/>
<Rectangle Fill="Aqua" Margin="10,10,10,10" Grid.Row="0" Grid.Column="1"/>
<Rectangle Fill="Aqua" Margin="10,10,10,10" Grid.Row="1" Grid.Column="0"/>
<Rectangle Fill="Aqua" Margin="10,10,10,10" Grid.Row="1" Grid.Column="1"/>

Grid>

DockPanel>
Window>

There are a couple of tricks here, namely the following:

  • The Grid for the right hand content area, must be the last child declared in order for it to take up the remaining space that the parent DockPanel wants to fill, due to the LastChildFill="True"
  • The StackPanel used for the status bar, must be before any other child that is declared as being DockPanel.Dock="Left" or DockPanel.Dock="Right". As if there was another element before the status bar StackPanel, the status bar StackPanel would not be able to span the entire width available, as this space would have been stolen by any child that was DockPanel.Dock="Left" or DockPanel.Dock="Right". Try it, you'll see what I mean. Simply move the status bar XAML further down in the XAML file, say to the end.

Performance Considerations

As some panels can be bound to items (this will be discussed further in the DataBinding article) there may be occasions where the number of children elements displayed in a panel is quite large. For example, if a StackPanel contains a ListBox that is bound to a large database query. This would be lots of items, OK in this case it's the ListBox that will have lots of children. However, internally, the ListBox control uses a Vertical StackPanel to render its items by default. Mmmm, that's not so great.

However all is not that bad, WPF has one further trick up its sleeve to aid in this situation. We can use the dependency/attached property VirtualizingStackPanel.IsVirtualizing on a ListBox, which means that the ListBox controls internal StackPanel to render its items, will now be virtualized. But what the heck is a vitualizingStackPanel?

When a panel is virtualized, it means that only the visible elements are created. The rest aren't displayed. For example, creating a listbox displaying images bound to a database holding 100,000 rows. This would take a long time for the listbox to load. If you use a virtualize panel, then only the visible images will get created in the UI. When you scroll down, the currently visible items will get destroyed, and the new visible items will get loaded onto the UI. There is only one panel that supports virtualization and it is the VirtualizingStackPanel. If you need to create any new virtualized panels, you will have to write your own.


I suppose, I hope by now you have the basics of layout in WPF.

Friday, July 10, 2009

WPF - Beginners tutorial PART - 1

I have started to induct two .NET people. I would prefer to start a series of tutorials at beginner level. I take advantage of Sacha Barber's tutorials in codeproject which got best article award for the month Jasnuary 2008. I thought of starting this PART - 1 with the following topics covered. The list of topics as of now planned are follows...

* Layout (this article)
* XAML vs Code / Markup Extensions And Resources (next article)
* Commands and Events
* Dependency Properties
* DataBinding
* Styles/Templates

Layout


Layout is one of the most important parts of any WPF project, the following sub sections will introduce you to the new layout options at your disposal.

The Importance of Layout
Layout is a fundamental building block used when writing any WPF. Using the layout controls in WPF allows developers/designers to create very complex arrangements of pages/controls. Without layout, we probably couldn't achieve anything, apart from a mess. So if you are looking for a mess, just quit reading right here. If however you want to know how to use the new layout options in WPF, read on.

These new layout controls will be the main focus of this article. You are of course free to author your own layout controls, if one of the pre-built controls doesn't suit your needs. We will see more on this later.

For the purpose of this article, we will be looking at the following:

* Canvas
* StackPanel
* WrapPanel
* DockPanel
* Grid

Please note that I will only be covering the basics of these controls, there are many more resources available for being clever with these controls, should you wish to research that. I however, consider the more advanced usages of these controls to be outside the scope of this article. Remember it's a beginner's series, so I want to keep it at a beginner's level.

A Brief Detour into the Importance of Margin

One thing that you simply must know, is how important the Margin property is. By using the Margin, we are able to specify how much space the current control (the one we are specifying the Margin property for), wants to have around it. WPF provides a ValueConverter that accepts a string of the format 5,5,5,5, but what does this mean. Well it's basically saying that we want a Margin of 5 pixels all around the control that is declaring this property. The Margin string, is stating Left, Top, Right, Bottom, and is one of 3 overloaded constructors used by the strangely named Thickness class that is used in the case where we are trying to set the Margin in code behind.

Canvas

The Canvas control, is one of the easier layout controls to use. It is a simple X/Y position container. Where each of the contained (children) controls must specify the following four properties in order to be positioned within the parent Canvas control:

* Canvas.Left
* Canvas.Right
* Canvas.Top
* Canvas.Bottom

With these four properties in place, the control will be positioned using these values within the parent Canvas control. These properties probably look a little bit odd, where we have a Canvas.Left for example, well they are a bit odd actually.
What else do we need to know about a Canvas control and its children. Well actually that's almost it, the only other thing to consider is that if the Canvas control is a simple X/Y position container, what's to stop two child controls, overlapping, and which child control should be on top. Well that's all taken care of by another dependency/attached property of the Canvas control. This is called the Canvas.ZIndex property, and this indicates which control should be on top. Basically the higher the Canvas.ZIndex value is, the more on top the control that declares this dependency/attached property will be. If no Canvas.ZIndex is declared for any of the children controls, the Canvas.ZIndex will be set to the order in which the children are added to the Canvas control.

Let's see an example of this, shall we? The following picture shows a Canvas control with two children, one on top of the other. This is taken from the file called CanvasDEMO.xaml in the attached demo project.

In XAML it will be like..

<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

x:Class="WPF_Tour_Beginners_Layout.CanvasDEMO"
x:Name="Window"
Title="CanvasDEMO"
Width="640" Height="480">

<Canvas Margin="0,0,0,0" Background="White">
<Rectangle Fill="Blue"
Stroke="Blue"
Width="145"
Height="126"
Canvas.Left="124" Canvas.Top="122"/>

<Ellipse Fill="Green"
Stroke="Green"
Width="121" Height="100"
Panel.ZIndex="1"
Canvas.Left="195" Canvas.Top="191"/>

</Canvas>

</Window>


And in C#, this would be as follows:

Canvas canv = new Canvas();

//add the Canvas as sole child of Window
this.Content = canv;
canv.Margin = new Thickness(0, 0, 0, 0);
canv.Background = new SolidColorBrush(Colors.White);

//The Rectangle
Rectangle r = new Rectangle();
r.Fill = new SolidColorBrush(Colors.Blue);
r.Stroke = new SolidColorBrush(Colors.Blue);
r.Width = 145;
r.Height = 126;
r.SetValue(Canvas.LeftProperty, (double)124);
r.SetValue(Canvas.TopProperty, (double)122);
canv.Children.Add(r);

//The Ellipse
Ellipse el = new Ellipse();
el.Fill = new SolidColorBrush(Colors.Green);
el.Stroke = new SolidColorBrush(Colors.Green);
el.Width = 121;
el.Height = 100;
el.SetValue(Canvas.ZIndexProperty, 1);
el.SetValue(Canvas.LeftProperty, (double)195);
el.SetValue(Canvas.TopProperty, (double)191);
canv.Children.Add(el);

And that's about all there is to basic Canvas layout.
I'm not good with VB. If you want to have it in VB, you can try some convertors.

StackPanel

The StackPanel control is also very easy to use. It simply stacks its contents, vertically or horizontally, using a single property, called Orientation.

The following picture shows a WrapPanel control with 10 children. This is taken from the file called WrapPanelDEMO.xaml.




Well in XAML, it is as follows:

<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

x:Class="WPF_Tour_Beginners_Layout.WrapPanelDEMO"
x:Name="Window"
Title="WrapPanelDEMO"
WindowStartupLocation="CenterScreen"
Width="640" Height="480">

<WrapPanel Margin="0,0,0,0" Background="White">
<Rectangle Margin="10,10,10,10" Fill ="Blue" Width="60" Height="60"/>

<Rectangle Margin="10,10,10,10" Fill ="Blue" Width="60" Height="60"/>
<Rectangle Margin="10,10,10,10" Fill ="Blue" Width="60" Height="60"/>

<Rectangle Margin="10,10,10,10" Fill ="Blue" Width="60" Height="60"/>
<Rectangle Margin="10,10,10,10" Fill ="Blue" Width="60" Height="60"/>

<Rectangle Margin="10,10,10,10" Fill ="Blue" Width="60" Height="60"/>
<Rectangle Margin="10,10,10,10" Fill ="Blue" Width="60" Height="60"/>

<Rectangle Margin="10,10,10,10" Fill ="Blue" Width="60" Height="60"/>
<Rectangle Margin="10,10,10,10" Fill ="Blue" Width="60" Height="60"/>

<Rectangle Margin="10,10,10,10" Fill ="Blue" Width="60" Height="60"/>
<Rectangle Margin="10,10,10,10" Fill ="Blue" Width="60" Height="60"/>

WrapPanel>

Window>

And in C#, this would be as follows:

WrapPanel wp = new WrapPanel();

//add the WrapPanel as sole child of Window
this.Content = wp;
wp.Margin = new Thickness(0, 0, 0, 0);
wp.Background = new SolidColorBrush(Colors.White);

//Add Rectangles
Rectangle r;
for (int i = 0; i <= 10; i++)
{
r = new Rectangle();
r.Fill = new SolidColorBrush(Colors.Blue);
r.Margin = new Thickness(10, 10, 10, 10);
r.Width = 60;
r.Height = 60;
wp.Children.Add(r);
}

And that's about all there is to basic WrapPanel layout.

DockPanel

The DockPanel control is one of the most useful (IMHO) layout controls. It is the one that we would probably use as the base layout control that any new Window uses. Basically with a DockPanel control (or 2), we can achieve the sort of layout that has been the main layout for most applications we have ever seen. We can basically get a menu docked to the top, then a left/right main content area, and a status strip at the bottom. This is all thanks to a couple of properties on the DockPanel control. Basically we can control the docking of any of our child controls that is within a parent DockPanel control by the use of the following dependency/attached property.

  • DockPanel.Dock

This property may be set to Left/Right/Top or Bottom. There is one further property exposed as a normal CLR property on the DockPanel control which is called LastChildFill which when set to true will make the last child control that was added to the DockPanel control, fill the remaining available space. This will override any DockPanel.Dock property that the child control may have already set.

Let's see an example of this, shall we? The following picture shows a DockPanel control with two children, one docked to the top, and the other docked to fill the remaining available area. This is taken from the file called DockPanelDEMO.xaml in the attached demo project.


So how does this look in code? Well in XAML, it is as follows:

<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

x:Class="WPF_Tour_Beginners_Layout.DockPanelDEMO"
x:Name="Window"
Title="DockPanelDEMO"
WindowStartupLocation="CenterScreen"
Width="640" Height="480">

<DockPanel Width="Auto" Height="Auto" LastChildFill="True">
<Rectangle Fill="CornflowerBlue" Stroke="CornflowerBlue"
Height="20" DockPanel.Dock="Top"/>

<Rectangle Fill="Orange" Stroke="Orange" />
</DockPanel>
</Window>
And in C#, this would be as follows:

DockPanel dp = new DockPanel();
dp.LastChildFill = true;
//this is the same as Width="Auto" in XAML, as long as its not applied
to a GridColumn Width/Height /GridRow Width/Height which has special classes
dp.Width = Double.NaN;
dp.Height = Double.NaN;

//add the WrapPanel as sole child of Window
this.Content = dp;
//Add Rectangles
Rectangle rTop = new Rectangle();
rTop.Fill = new SolidColorBrush(Colors.CornflowerBlue);
rTop.Stroke = new SolidColorBrush(Colors.CornflowerBlue);
rTop.Height = 20;
dp.Children.Add(rTop);
rTop.SetValue(DockPanel.DockProperty,Dock.Top);
Rectangle rFill = new Rectangle();
rFill.Fill = new SolidColorBrush(Colors.Orange);
rFill.Stroke = new SolidColorBrush(Colors.Orange);
dp.Children.Add(rFill);
And that's about all there is to basic DockPanel layout.

Grid

The Grid control, is by far, the most sophisticated WPF layout control there is (at present). It is sort of like an HTML table control, where you can specify rows and columns, and have cells that span multiple rows, or cells that span multiple columns. There is also a strange syntax which may be used for the Width/Height of Columns and Rows, which is known as the Star "*" notation, which is exposed through the use of the GridLength class. Think of this as being like a percentage of what's left divider. For example I could have some markup such as:

<Grid.ColumnDefinitions>
<ColumnDefinition Width="40"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="2*"/>

</Grid.ColumnDefinitions>

Where I have declared three Grid ColumnDefinition controls, where the first ColumnDefinition gets a fixed width of 40 pixels, and the remaining space is divided between the last two ColumnDefinition controls, where the last one gets twice as much as the second last one. This is the same principle for RowDefinition.

In order for child controls of a Grid control to tell the WPF layout system which cell they belong to, we simply use the following dependency/attached properties, which use a 0 based index.

  • Grid.Column
  • Grid.Row

And to specify how many rows or columns a cell should occupy, we simply use the following dependency/attached properties, which starts at 1.

  • Grid.ColumnSpan
  • Grid.RowSpan

By clever usage of a Grid control, you should almost be able to mimic any of the other layout controls. I'll leave that as an exercise for the reader.

Let's see an example of the Grid control, shall we? The following picture shows a Grid control with 3 Columns and 1 Row, where there are two children. The first child occupies Column 1, and the second child occupies Columns 2-3 as its Grid.ColumnSpan is set to 2.

So how does this look in code? Well in XAML, it is as follows:

<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="WPF_Tour_Beginners_Layout.GridDEMO"
x:Name="Window"

Title="GridDEMO"
WindowStartupLocation="CenterScreen"
Width="640" Height="480">

<Grid Width="Auto" Height="Auto" >

<Grid.ColumnDefinitions>
<ColumnDefinition Width="40"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="2*"/>

</Grid.ColumnDefinitions>

<Rectangle Fill="Aqua" Grid.Column="0" Grid.Row="0"/>

<Rectangle Fill="Plum" Grid.Column="1" Grid.ColumnSpan="2"/>

</Grid>
</Window>

And in C#, this would be as follows:

Grid grid = new Grid();
grid.Width = Double.NaN; //this is the same as Width="Auto" in XAML

grid.Height = Double.NaN; //this is the same as Height="Auto" in XAML
//add the Grid as sole child of Window
this.Content = grid;

//col1

ColumnDefinition cd1 = new ColumnDefinition();
cd1.Width = new GridLength(40);
grid.ColumnDefinitions.Add(cd1);
//col2
ColumnDefinition cd2 = new ColumnDefinition();
cd2.Width = new GridLength(1, GridUnitType.Star);
grid.ColumnDefinitions.Add(cd2);

//col3
ColumnDefinition cd3 = new ColumnDefinition();
cd3.Width = new GridLength(2, GridUnitType.Star);
grid.ColumnDefinitions.Add(cd3);
//Now add the cells to the grid
Rectangle r1c1 = new Rectangle();
r1c1.Fill = new SolidColorBrush(Colors.Aqua);
r1c1.SetValue(Grid.ColumnProperty, 0);
r1c1.SetValue(Grid.RowProperty, 0);
grid.Children.Add(r1c1);

Rectangle r1c23 = new Rectangle();
r1c23.Fill = new SolidColorBrush(Colors.Plum);
r1c23.SetValue(Grid.ColumnProperty, 1);
r1c23.SetValue(Grid.ColumnSpanProperty, 2);
grid.Children.Add(r1c23);

As I say, the Grid control is quite sophisticated so I urge you to explore
this one further. You can do all sorts of things with the Grid such as have
GridSplitter controls for resizing Columns/Rows, and you can set up shared
sizes across multiple grids, this is known as SizeGroup. So please explore the
Grid control further
.

Tuesday, April 21, 2009

Free Cool ListBox - Customized for alternate item colors and text wrap properties.

I have got a requirement to design a list box with alternate items coloring and text wrapping feature. I have tried for one in the google but very less help could be found.



So I designed one cool listbox that with the above requirements satisfied. I have given the code below.


My List box looks like the below image..






To acheive this, First you have to add one ListBox control and one Textbox with multiline property enabled underneath it. I have named my textbox as txtMessage and ListBox as ListBox1.



The below code shows how to add the contents from the text box on carriage return press ('Enter' button press)...






   1:  private void txtMessage_KeyPress(object sender, KeyPressEventArgs e)

   2:          {

   3:              if (e.KeyChar == 13)

   4:              {

   5:                  ListBox1.Items.Add(txtMessage.Text.Trim().ToString());

   6:                  txtMessage.Text = "";

   7:              }

   8:          }





Now, folllow the instructions below...



1.Select the ListBox1 from your design view and make the "DrawMode" property as "OwnerDrawVariable"



2. Generate the event for DrawItem and MeasureItem of the ListBox.






   1:    /// <summary>

   2:          /// DrawItem event triggers when the list box is visible in the form

   3:          /// </summary>

   4:          /// <param name="sender"></param>

   5:          /// <param name="e"></param>

   6:          private void ListBox1_DrawItem(object sender, DrawItemEventArgs e)

   7:          {

   8:              if (ListBox1.Items.Count > 0)

   9:              {

  10:                  // Draw the background of the ListBox control for each item.

  11:                  // Create a new Brush and initialize to a Black colored brush

  12:                  // by default. And inintialise other properties to set the font 

  13:                  //bg color font size etc.. as below.

  14:   

  15:                  FontFamily family = FontFamily.GenericSerif;

  16:                  float size = 8F;

  17:                  Font myFont = new Font(family, size, FontStyle.Regular);

  18:                  Color highlightercolor = Color.White;

  19:                  Brush fontcolor = Brushes.Black;

  20:   

  21:                  //Method call to draw the back ground if the list box [Metadata]

  22:                  e.DrawBackground();

  23:   

  24:                  //Inintialize a rectangle to contain each item

  25:                  Rectangle rectangle = new Rectangle(2, e.Bounds.Top + 2,

  26:                              e.Bounds.Height, e.Bounds.Height - 4);

  27:                  

  28:                  //Select alternate items 

  29:                  int type = 0;

  30:                  type = e.Index % 2;

  31:   

  32:                  // Determine the color of the font, bg color, and brush to 

  33:                  //draw each item based on the index of the item to draw.

  34:                  

  35:                  switch (type)

  36:                  {

  37:   

  38:                      case 0:

  39:                          family = FontFamily.GenericSansSerif;

  40:                          size = 8;

  41:                          myFont = new Font(family, size, FontStyle.Regular);

  42:                          highlightercolor = Color.Gainsboro;

  43:                          fontcolor = Brushes.Black;

  44:                          break;

  45:   

  46:                      case 1:

  47:                          family = FontFamily.GenericSansSerif;

  48:                          size = 8;

  49:                          myFont = new Font(family, size, FontStyle.Regular);

  50:                          highlightercolor = Color.WhiteSmoke;

  51:                          fontcolor = Brushes.Black;

  52:                          break;

  53:   

  54:                      default:

  55:                          break;

  56:                  }

  57:                  

  58:                  // Draw the current item text based on the current 

  59:                  // Font and the custom brush settings.

  60:                  e.Graphics.FillRectangle(new SolidBrush(highlightercolor), e.Bounds);

  61:   

  62:                  // Draw each string in the Listbox, 

  63:                  e.Graphics.DrawString(((ListBox)sender).Items[e.Index].ToString(), 

  64:                      myFont, fontcolor, new RectangleF(e.Bounds.X + rectangle.Width, 

  65:                          e.Bounds.Y, e.Bounds.Width, e.Bounds.Height));

  66:                  

  67:                  // If the ListBox has focus, draw a focus rectangle 

  68:                  // around the selected item.

  69:                 // [Metadata]

  70:                  e.DrawFocusRectangle();

  71:              }

  72:   

  73:          }





The above method takes care on the alternate back ground color, font properties etc..







   1:  /// <summary>

   2:          /// Event triggers when the ListBox1 is visible in the form

   3:          /// </summary>

   4:          /// <param name="sender"></param>

   5:          /// <param name="e"></param>

   6:          private void ListBox1_MeasureItem(object sender, MeasureItemEventArgs e)

   7:          {

   8:              Graphics gr = e.Graphics;

   9:              

  10:              //We will get the size of the string which we are about to draw,

  11:              //so that we could set the ItemHeight and ItemWidth property 

  12:              SizeF size = gr.MeasureString(((ListBox)sender).Items[e.Index].ToString(), 

  13:                  ((ListBox)sender).Font,

  14:                  ((ListBox)sender).Width - 3 - SystemInformation.VerticalScrollBarWidth);

  15:              

  16:              //Set the height and width to the item

  17:              e.ItemHeight = Convert.ToInt16(size.Height) + 5;

  18:              e.ItemWidth = Convert.ToInt16(size.Width) + 3;

  19:          }





This above method declares the wrap of the content of the ListBox1.


You can alter the features as you like, hopefully all the code were explained neatly.

Monday, April 20, 2009

Marquee in Windows forms

There are scenarios where we need to use marquees in windows applications. But there are no controls introduced for this in .NET frameworks until 3.5 SP1.


I have tried some marquee controls available ready in google search and code project, but they are not thead safe in my experience i faced problems in using them in my project as it is.


Here I have given a simple code to create your own marquee that is thread safe and reasonably serves your requirement with out causing any problem.






   1:  System.Text.StringBuilder sb;

   2:          /// <summary>

   3:          /// Method called during form load. initiates MArquee items

   4:          /// </summary>

   5:          void StartMarquee()

   6:          {

   7:              //This method sets all the input for your marquee

   8:              sb = new System.Text.StringBuilder(Marquee.marqueeProperties.Text + " -- ");

   9:              //Enable the timer control 

  10:              timerMarquee.Enabled = true;

  11:              //You can simply alter the speed of the marquee

  12:              timerMarquee.Interval = Marquee.marqueeProperties.RotationSpeed;

  13:              //Change the marquee text color

  14:              txtMarqueeDisplay.ForeColor = Marquee.marqueeProperties.TextColor;

  15:              //Change the bach ground color here

  16:              txtMarqueeDisplay.BackColor = Marquee.marqueeProperties.TextBgColor;

  17:          }





The above has to be called from your windows form load where you have to have your text box control where the marquee is going to be displayed. Here my text box is named as "txtMarqueeDisplay".






   1:    /// <summary>

   2:          /// That Runs Marquee

   3:          /// </summary>

   4:          /// <param name="sender"></param>

   5:          /// <param name="e"></param>

   6:          private void timerMarquee_Tick(object sender, EventArgs e)

   7:          {

   8:              //This is the timer's tick event

   9:              char ch = sb[0];

  10:              sb.Remove(0, 1);

  11:              sb.Insert(sb.Length, ch);

  12:              //Change the 100 below to fit your requirement

  13:              if (txtMarqueeDisplay.Text.Length > 100)

  14:                  txtMarqueeDisplay.Clear();

  15:              txtMarqueeDisplay.AppendText(sb.ToString());

  16:          }





The above method the event from the timer control which is availbale from .NET 2.0
the timer is used to make sure the marque is thread safe!



Hope you got the marquee in a very simple way!!