Click here to Skip to main content
Click here to Skip to main content

XPTable - .NET ListView meets Java's JTable

By , 17 Sep 2005
 
Prize winner in Competition "C# Aug 2005"

Contents

Introduction

For a project I'm working on I needed a highly customized ListView - one that would allow checkboxes and images in any column, ComboBoxes and NumericUpDowns for editing and it had to be easy to swap data in and out. Anyone who has tried customizing a ListView knows how painful it can be trying to bend it to your will, so I decided to create one from scratch. Having come from a Java background I decided to base it somewhat loosely on Java's JTable.

Features

  • Fully customizable visual appearance - from columns to rows and cells.
  • Supports Windows XP visual styles.
  • Powerful renderers that give cells the ability to act like controls.
  • Easy to add your own custom renderers and editors.
  • Columns can be hidden.
  • Rows, columns or individual cells can be disabled.
  • ToolTips for columns and cells.
  • Plus much more....

XPTable

XPTable consists of the following components:

  1. A Table,
  2. A ColumnModel and its Columns,
  3. A TableModel and its Rows and Cells,
  4. Renderers and
  5. Editors

I'm not going to go into much detail about the first three points and will only show the basics for points 4 and 5 as otherwise this article would be much larger than it already is. If you want more details on any of these topics then you should read the User Guide supplied with the documentation.

Using XPTable

Before using the XPTable, you need to add a reference to XPTable.dll in the References section of your project.

To add the XPTable.dll to the toolbox, you can either:

  1. Select Tools -> Add/Remove Toolbox Items from the menu, or
  2. Right click on the toolbox, select Add/Remove Items.

and browse for XPTable.dll and then press OK. You can then drag the controls onto your Form.

Note: If you recompile the source code you will need to re-sign XPTable.dll, as otherwise Visual Studio may throw an exception when you attempt to add it to the toolbox.

  1. Open up the VS .NET command prompt and change the directory to point to the XPTable\bin\Release directory.
  2. Then type "sn -R XPTable.dll ..\..\XPTable.snk" (without the quotes of course).

You should then be able to add it to the toolbox.

After that, all you need to do is drag a Table, ColumnModel and TableModel onto your form, set the Table's ColumnModel and TableModel properties, and add Columns to the ColumnModel and Rows and Cells to the TableModel.

or if you prefer code:

Table table = new Table();
ColumnModel columnModel = new ColumnModel();
TableModel tableModel = new TableModel();

// set the Table's ColumModel and TableModel
table.ColumnModel = columnModel;
table.TableModel = tableModel;

// add some Columns to the ColumnModel
columnModel.Columns.Add(new TextColumn("Text"));
columnModel.Columns.Add(new CheckBoxColumn("CheckBox"));
columnModel.Columns.Add(new ButtonColumn("Button"));

// add some Rows and Cells to the TableModel
tableModel.Rows.Add(new Row());
tableModel.Rows[0].Cells.Add(new Cell("Text 1"));
tableModel.Rows[0].Cells.Add(new Cell("CheckBox 1", true));
tableModel.Rows[0].Cells.Add(new Cell("Button 1"));
tableModel.Rows.Add(new Row());
tableModel.Rows[1].Cells.Add(new Cell("Text 2"));
tableModel.Rows[1].Cells.Add(new Cell("CheckBox 2", false));
tableModel.Rows[1].Cells.Add(new Cell("Button 2"));

Table

A Table is "simple" object in that it doesn't actually contain or know how to draw the data it will display. Instead it uses a ColumnModel to keep track of its Columns, a TableModel to keep track of its Rows and Cells, and Renderers and Editors to draw and edit its data. The Table's primary role is to manage the drawing operations and pass on events to the Renderers and Editors so that they can take the appropriate action.

ColumnModel

A ColumnModel contains a collection of Columns that will be displayed in a Table. It also keeps track of whether a CellRenderer or CellEditor has been created for a particular Column.

Columns

After thinking for a while about the best way to implement Columns I decided to use the same approach as a DataGrid - that is to have different types of Columns based on the type of data their Cells will contain. The following Column types are available:

  • Column - Base class for all Columns.
  • TextColumn - A Column whose Cells are displayed as strings.
  • ButtonColumn - A Column whose Cells are displayed as Buttons.
  • CheckBoxColumn - A Column whose Cells are displayed as CheckBoxes.
  • ImageColumn - A Column whose Cells are displayed as Images.
  • NumberColumn - A Column whose Cells are displayed as numbers.
  • ProgressBarColumn - A Column whose Cells are displayed as ProgressBars.
  • DropDownColumn - Base class for Columns that display a dropdown box for editing.
  • ComboBoxColumn - Represents a Column whose Cells are displayed as ComboBoxes.
  • DateTimeColumn - Represents a Column whose Cells contain DateTimes.
  • ColorColumn - Represents a Column whose Cells contain Colors.

TableModel

A TableModel contains a collection of Rows that will be displayed in a Table.

Rows

A Row represents a row in a Table and contains a collection of Cells that will be displayed in the Row.

Cells

A Cell contains a piece of data that will be displayed in a Table.

Renderers

As mentioned earlier, a Table doesn't know how to draw Cells or Column headers. Instead, it uses objects called Renderers to do all the drawing for it. The Java website describes a renderer as "a configurable ink stamp that the table uses to stamp appropriately formatted data onto each cell".

A Table uses two different types of Renderers: CellRenderers which draw the Cells, and HeaderRenderers which draw the Column headers

CellRenderers

CellRenderers are powerful objects in that they allow Cells to look and behave like Windows controls without consuming any extra resources.

The list below shows all the CellRenderers provided with XPTable:

  • ICellRenderer - Exposes common methods provided by Cell renderers.
  • CellRenderer - Base class for all Cell renderers.
  • TextCellRenderer - A CellRenderer that draws Cell contents as strings.
  • ButtonCellRenderer - A CellRenderer that draws Cell contents as Buttons.
  • CheckBoxCellRenderer - A CellRenderer that draws Cell contents as CheckBoxes.
  • ImageCellRenderer - A CellRenderer that draws Cell contents as Images.
  • NumberCellRenderer - A CellRenderer that draws Cell contents as numbers.
  • ProgressBarCellRenderer - A CellRenderer that draws Cell contents as a ProgressBar.
  • DropDownCellRenderer - Base class for CellRenderers that draw Cell contents like ComboBoxes.
  • ComboBoxCellRenderer - A CellRenderer that draws Cell contents as a ComboBox.
  • ColorCellRenderer - A CellRenderer that draws Cell contents as Colors.
  • DateTimeCellRenderer - A CellRenderer that draws Cell contents as a DateTime.

The image below shows the default output of each CellRenderer:

Creating a custom CellRenderer

If you want to create a custom CellRenderer you have two choices - subclass CellRenderer and override (at least) the OnPaint and OnPaintBackground methods (the easiest and preferred method) or implement ICellRenderer (a lot of work).

Below is the code for the Table's built in TextCellRenderer:

public class TextCellRenderer : CellRenderer
{
   protected override void OnPaint(PaintCellEventArgs e)
   {
      base.OnPaint(e);
 
      // don't bother going any further if the Cell is null
      if (e.Cell == null)
      {
         return;
      }
 
      // make sure we have some text to draw
      if (e.Cell.Text != null && e.Cell.Text.Length != 0)
      {
         // check whether the cell is enabled
         if (e.Enabled)
         {
            e.Graphics.DrawString(e.Cell.Text, base.Font, 
                        base.ForeBrush, base.ClientRectangle, 
                        base.StringFormat);
         }
         else
         {
            e.Graphics.DrawString(e.Cell.Text, base.Font, 
                    base.GrayTextBrush, base.ClientRectangle, 
                    base.StringFormat);
         }
      }
 
      // draw a focus rect around the cell if it is
      // enabled and has focus
      if (e.Focused && e.Enabled)
      {
         ControlPaint.DrawFocusRectangle(e.Graphics, 
                                       base.ClientRectangle);
      }
   }
}

For a more complex example, see the User Guide provided with the documentation.

HeaderRenderers

Unlike CellRenderers which are used on a per-column basis, a Table uses a single HeaderRenderer to draw all its Column headers.

The list below shows all the HeaderRenderers provided with XPTable:

  • IHeaderRenderer - Exposes common methods provided by Column header renderers.
  • HeaderRenderer - Base class for Renderers that draw Column headers.
  • XPHeaderRenderer - A HeaderRenderer that draws Windows XP themed Column headers.
  • GradientHeaderRenderer - A HeaderRenderer that draws gradient Column headers.
  • FlatHeaderRenderer - A HeaderRenderer that draws flat Column headers.

The image below shows the built in HeaderRenderers in action:

You can specify the HeaderRenderer that a Table will use by setting its HeaderRenderer property:

// get the table to use a FlatHeaderRenderer
// to draw the column headers
table.HeaderRenderer = new FlatHeaderRenderer();

Creating a custom HeaderRenderer

If you want to create a custom HeaderRenderer you have two choices - subclass HeaderRenderer and override (at least) the OnPaint and OnPaintBackground methods (the easiest and preferred method) or implement IHeaderRenderer (a lot of work).

Below is the code for the Table's built in XPHeaderRenderer:

public class XPHeaderRenderer : HeaderRenderer
{
   protected override void OnPaintBackground(PaintHeaderEventArgs e)
   {
      base.OnPaintBackground(e);

      if (e.Column == null)
      {
         ThemeManager.DrawColumnHeader(e.Graphics, e.HeaderRect, 
                                       ColumnHeaderStates.Normal);
      }
      else
      {
         ThemeManager.DrawColumnHeader(e.Graphics, e.HeaderRect, 
                         (ColumnHeaderStates) e.Column.ColumnState);
      }
   }


   protected override void OnPaint(PaintHeaderEventArgs e)
   {
      base.OnPaint(e);

      // don't bother if we don't have a column
      if (e.Column == null)
      {
         return;
      }

      Rectangle textRect = base.ClientRectangle;
      Rectangle imageRect = Rectangle.Empty;

      // check whether we can draw an image on the column header
      if (e.Column.Image != null)
      {
         imageRect = base.CalcImageRect();
         textRect.Width -= imageRect.Width;
         textRect.X += imageRect.Width;

         if (e.Column.ImageOnRight)
         {
            imageRect.X = base.ClientRectangle.Right - imageRect.Width;
            textRect.X = base.ClientRectangle.X;
         }

         // column headers that aren't themed and are pressed need
         // their contents shifted down and to the right by 1 pixel 
         if (!ThemeManager.VisualStylesEnabled && 
             e.Column.ColumnState == ColumnState.Pressed)
         {
            imageRect.X += 1;
            imageRect.Y += 1;
         }

         base.DrawColumnHeaderImage(e.Graphics, e.Column.Image, 
                                    imageRect, e.Column.Enabled);
      }

      // column headers that aren't themed and are pressed need
      // their contents shifted down and to the right by 1 pixel 
      if (!ThemeManager.VisualStylesEnabled && 
          e.Column.ColumnState == ColumnState.Pressed)
      {
         textRect.X += 1;
         textRect.Y += 1;
      }

      // check whether we need to draw a sort arrow
      if (e.Column.SortOrder != SortOrder.None)
      {
         // work out where to draw it
         Rectangle arrowRect = base.CalcSortArrowRect();
    
         // adjust the textRect to take the arrow into account
         arrowRect.X = textRect.Right - arrowRect.Width;
         textRect.Width -= arrowRect.Width;

         base.DrawSortArrow(e.Graphics, arrowRect, e.Column.SortOrder, 
                                                     e.Column.Enabled);
      }

      // check whether we have any text to draw
      if (e.Column.Text == null)
      {
         return;
      }

      if (e.Column.Text.Length > 0 && textRect.Width > 0)
      {
         if (e.Column.Enabled)
         {
            e.Graphics.DrawString(e.Column.Text, 
                           base.Font, base.ForeBrush,
                           textRect, base.StringFormat);
         }
         else
         {
            using (SolidBrush brush = 
                   new SolidBrush(SystemPens.GrayText.Color))
            {
               e.Graphics.DrawString(e.Column.Text, 
                                   base.Font, brush, 
                                   textRect, base.StringFormat);
            }
         }
      }
   }
}

Editors

XPTable contains five built-in editors:

  • ICellEditor - Exposes common methods provided by Cell editors.
  • CellEditor - Base class for Cell editors.
  • TextCellEditor - A class for editing Cells that contain strings.
  • NumberCellEditor - A class for editing Cells that contain numbers.
  • DropDownCellEditor - Base class for editing Cells that contain drop down buttons.
  • ComboBoxCellEditor - A class for editing Cells that look like a ComboBox.
  • ColorCellEditor - A class for editing Cells that contain Colors.
  • DateTimeCellEditor - A class for editing Cells that contain DateTimes.
  • IEditorUsesRendererButtons - Specifies that a CellEditor uses the buttons provided by its counter-part CellRenderer during editing.

Note: For more information about IEditorUsesRendererButtons see the User Guide provided with the documentation.

The image below shows the editors that use a drop-down control to edit Cell contents:

You can programmatically edit a Cell by using the table's EditCell method:

// start editing the cell at (0, 0)
table.EditCell(0, 0);

// stop editing the cell and commit any changes
table.StopEditing();

// or cancel editing and ignore any changes
table.CancelEditing();

Note: If you want to stop or cancel editing always use the table's StopEditing or CancelEditing methods (even when implementing a custom CellEditor). This gives the table a chance to do any work it needs to do before calling the CellEditor's StopEditing or CancelEditing methods.

Creating a custom CellEditor

If you want to create a custom CellEditor you have two choices - subclass CellEditor and override (at least) the SetEditValue, SetCellValue and SetEditLocation methods (the easiest and preferred method) or implement ICellEditor (a lot of work).

Below is the code for the Table's built in TextCellEditor:

public class TextCellEditor : CellEditor
{
   public TextCellEditor() : base()
   {
      TextBox textbox = new TextBox();
      textbox.AutoSize = false;
      textbox.BorderStyle = BorderStyle.None;

      base.Control = textbox;
   }


   // Sets the location and size of the CellEditor
   protected override void SetEditLocation(Rectangle cellRect)
   {
      this.TextBox.Location = cellRect.Location;
      this.TextBox.Size = new Size(cellRect.Width-1, 
                                       cellRect.Height-1);
   }


   // Sets the initial value of the 
   // editor based on the contents of 
   // the Cell being edited
   protected override void SetEditValue()
   {
      this.TextBox.Text = base.EditingCell.Text;
   }


   // Sets the contents of the Cell 
   // being edited based on the value 
   // in the editor
   protected override void SetCellValue()
   {
      base.EditingCell.Text = this.TextBox.Text;
   }


   // Starts editing the Cell
   public override void StartEditing()
   {
      this.TextBox.KeyPress += 
                 new KeyPressEventHandler(OnKeyPress);
      this.TextBox.LostFocus += 
                 new EventHandler(OnLostFocus);

      base.StartEditing();

      this.TextBox.Focus();
   }


   // Stops editing the Cell and commits any changes
   public override void StopEditing()
   {
      this.TextBox.KeyPress -= 
                 new KeyPressEventHandler(OnKeyPress);
      this.TextBox.LostFocus -= 
                 new EventHandler(OnLostFocus);
            
      base.StopEditing();
   }


   // Stops editing the Cell and ignores any changes
   public override void CancelEditing()
   {
      this.TextBox.KeyPress -= 
                   new KeyPressEventHandler(OnKeyPress);
      this.TextBox.LostFocus -= 
                   new EventHandler(OnLostFocus);
            
      base.CancelEditing();
   }


   // Gets the TextBox used to edit the Cells contents
   public TextBox TextBox
   {
      get
      {
         return base.Control as TextBox;
      }
   }


   // Handler for the editors TextBox.KeyPress event
   protected virtual void OnKeyPress(object sender, 
                                       KeyPressEventArgs e)
   {
      // check whether we nned to stop or cancel editing
      if (e.KeyChar == AsciiChars.CarriageReturn /*Enter*/)
      {
         if (base.EditingTable != null)
         {
            base.EditingTable.StopEditing();
         }
      }
      else if (e.KeyChar == AsciiChars.Escape)
      {
         if (this.EditingTable != null)
         {
            base.EditingTable.CancelEditing();
         }
      }
   }


   // Handler for the editors TextBox.LostFocus event
   protected virtual void OnLostFocus(object sender, 
                                           EventArgs e)
   {
      // if the textbox loses focus 
      // we should stop editing
      if (base.EditingTable != null)
      {
         base.EditingTable.StopEditing();
      }
   }
}

Visual styles

With XPTable, visual styles are inheritable - that is Rows and Cells will use the visual settings of their parent container (unless otherwise told). XPTable also provides style objects that can be shared between Rows and Cells which save system resources. The image below shows an example of this:

CellStyles

Cells have a CellStyle property which allows you to provide a consistent look and feel across multiple Cells while saving system resources. The CellStyle object provides four properties that control the appearance of a Cell:

  • BackColor - specifies the background color for the Cell.
  • ForeColor - specifies the foreground color for the Cell.
  • Font - specifies the font used by the Cell.
  • CellPadding - specifies the amount of space between the Cell's border and its contents.

Note: Setting one of these values on a Cell will override the same values inherited from its parent Row. Cells also have BackColor, ForeColor, Font and CellPadding properties that use the CellStyle property to store their values. Setting one of these properties on a Cell that shares its CellStyle with other Cells will affect all the other Cells as well.

RowStyles

RowStyles are the same as CellStyles, except that they are shared between Rows and don't have a CellPadding property.

Table styles

In this version Tables do not have a TableStyle property (although future versions will). Instead a Table has the following properties to control its appearance:

  • BackColor - specifies the background color for the Table.
  • ForeColor - specifies the foreground color for the Table.
  • Font - specifies the font used by the Table.
  • AlternatingRowColor - specifies the Table's alternating row background color.
  • SelectionBackColor - specifies the background color of selected Rows and Cells.
  • SelectionForeColor - specifies the foreground color of selected Rows and Cells.
  • UnfocusedSelectionBackColor - specifies the background color of selected Rows and Cells when the Table doesn't have focus.
  • UnfocusedSelectionForeColor - specifies the foreground color of selected Rows and Cells when the Table doesn't have focus.
  • HeaderFont - specifies the font used to draw the text in the Column headers.
  • GridColor - specifies the color of the grid lines.
  • GridLineStyle - specifies the line style of the grid lines.
  • SortedColumnBackColor - specifies the color of a sorted Column's background.

Note: Rows and Cells will inherit these values unless explicitly set.

The example below shows how CellStyles and Rowstyles can be shared:

// create a new CellStyle object
CellStyle cellStyle = new CellStyle();
cellStyle.BackColor = Color.Blue;
cellStyle.ForeColor = Color.Red;
cellStyle.Font = new Font("Tahoma", 8.25f, FontStyle.Bold);

// create a new RowStyle object
RowStyle rowStyle = new RowStyle();
rowStyle.BackColor = Color.Yello;
rowStyle.ForeColor = Color.Green;
rowStyle.Font = new Font("Arial", 8.25f, FontStyle.Italics);

for (int i=0; i<3; i++)
{
   tableModel.Rows[i].RowStyle = rowStyle;

   // only set the cellstyle for cells in the 3rd column
   tableModel[i, 2].CellStyle = cellStyle;
}

Sorting

Sorting a table is performed on a per-column basis, and can be initiated by clicking on a Column's header or through code.

There are six inbuilt comparers:

  • ComparerBase - Base class for Cell comparers.
  • TextComparer - for comparing Cells based on the Text property.
  • CheckBoxComparer - for comparing Cells based on the Checked property.
  • NumberComparer - for comparing Cells that contain numbers in the Data property.
  • ImageComparer - for comparing Cells based on the Image property.
  • ColorComparer - for comparing Cells that contain Colors in the Data property.
  • DateTimeComparer - for comparing Cells that contain DateTimes in the Data property.

There are also four inbuilt sorters:

  • InsertionSorter
  • MergeSorter
  • ShellSorter
  • HeapSorter

InsertionSort and MergeSort are considered to be stable sorts, whereas ShellSort and HeapSort are unstable. Also, InsertionSort and ShellSort are faster than MergeSort and HeapSort on smaller lists and slower on large lists. The actual algorithm used to sort a Column depends on the number of Rows in the Table and whether a stable sort is required.

For more information on sorting methods and stable/unstable sorting refer to this site.

You can programmatically sort a Column by calling one of the table's Sort methods:

// sort the currently sorted column in the opposite direction
// to its currnent sort order, or if no columns are sorted, the
// column that has focus in ascending order
table.Sort();

// sort the currently sorted column in the opposite direction
// to its currnent sort order, or if no columns are sorted, the
// column that has focus in ascending order using an unstable 
// sort method
table.Sort(false);

// sort the column at index 3 in the table's ColumnModel 
// opposite to its current sort order, or in ascending order 
// if the column is not sorted
table.Sort(3);

// sort the column at index 3 in the table's ColumnModel 
// opposite to its current sort order, or in ascending order 
//if the column is not sorted using a stable sort method
table.Sort(3, true);

// sort the column at index 3 in the table's ColumnModel
// in descending order
table.Sort(3, SortOrder.Descending);

// sort the column at index 3 in the table's ColumnModel
// in ascending order using an unstable sort method
table.Sort(3, SortOrder.Ascending, false);

Note: The Sort methods that don't supply an option for specifying a stable or unstable sort automatically use a stable sort.

You can disable Column sorting by setting the Column's Sortable property to false:

// disable sorting for a column
column.Sortable = false;

Note: Setting the Table's HeaderStyle property to NonClickable or None will stop column sorting from clicking on a column header, however the Column can still be sorted programmatically.

Creating a custom comparer

It is also possible to create a custom comparer for use by a Column by sub classing ComparerBase and overriding the Compare method:

public class TextComparer : ComparerBase
{
   // Compares two objects and returns a 
   // value indicating whether one is less
   // than, equal to or greater than the other
   public override int Compare(object a, object b)
   {
      Cell cell1 = (Cell) a;
      Cell cell2 = (Cell) b;
 
      // check for null cells
      if (cell1 == null && cell2 == null)
      {
         return 0;
      }
      else if (cell1 == null)
      {
         return -1;
      }
      else if (cell2 == null)
      {
         return 1;
      }
 
      // check for null data
      if (cell1.Text == null && cell2.Text == null)
      {
         return 0;
      }
      else if (cell1.Text == null)
      {
         return -1;
      }
 
      // now that we know both cells contain valid data,
      // use the frameworks built in string comparer
      return cell1.Text.CompareTo(cell2.Text);
   }
}

Selections

A Table provides two ways that selected Cells can be visualized - Grid style where the individual selected Cells are highlighted, or ListView style where only the Cell in the first visible Column is highlighted. The images below show an example of this:

Top: ListView style selection

Bottom: Grid style selection

This can be set using the table's SelectionStyle property:

// use grid style selection
table.SelectionStyle = SelectionStyle.Grid;

Note: With ListView style selection the highlighted Cell may not actually be selected.

The TableModel also provides a Selection object that you can use to programmatically select or deselect Cells.

Future features

Below is a list of features that I would like to add to future versions:

  • Word wrapping for cells and column headers
  • Autosizing rows and columns
  • Variable height rows
  • LinkLabel cells
  • RichTextFormat cells
  • Dialog based CellEditors
  • ListView style icon mode
  • RightToLeft support
  • Cut and paste support
  • Drag and drop support
  • Data binding
  • Column re-ordering
  • Printing support
  • Export to HTML and XML
  • Serialization
  • Other stuff I've forgotten or haven't thought of yet

History

  • 11th September, 2005 - Initial release.
  • 13th September, 2005 - Version 1.0.1.
    • Fixed Table causing a crash when an application is minimized.
    • Updated future features list.
  • 17th September, 2005 - Version 1.0.2
    • Fixed using a DropDownCellEditor causes a crash when the dropdown portion is displayed.
    • Fixed exception thrown when removing Rows from a TableModel.
    • Fixed TableModels/Rows not updating Row/Cell indices when Row/Cells are added/removed causing drawing problems.
    • Fixed HideSelection bug where selected items were not drawn as selected even when the Table had focus.
    • Fixed Table overriding Cursors set by a CellRenderer.
    • Added utility methods InvalidateCell and InvalidateRow to the Table for convenience.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

Mathew Hall
Web Developer
Australia Australia
No Biography provided

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
QuestionCell Edit LocationmemberJugonza16-Apr-13 6:35 
I have run into an issue where my textbox edit location in my cell does not match up with my cell's location after I resize the row height and column width.
 
My code for resizing is simple:
            int height = myTable.Size.Height-20;
            int width = myTable.Size.Width;
 
            for (int i = 0; i < nrows; i++)
            {
                myTable.TableModel.Rows[i].Height = height/nrows;
            }
 
            for (int i = 0; i < ncols; i++)
            {
                myTable.ColumnModel.Columns[i].Width = width / ncols;
            }
Although the cells now fit nicely into my panel, when I click to edit them, the edit location is where it was prior to resizing the cell height/width. Is there some way to remap the editting location on the cells text box?
 
Thanks!
GeneralMy vote of 5memberMember 768501216-Oct-12 0:43 
Bro, just awesome!! no other words for it. I am also a huge fan of Java like simplicity. This was exactly what I was hoping to do myself. But now I'll just use your work of art. thanks.
GeneralRe: My vote of 5memberadambl19-Feb-13 22:15 
For more features use the updated code on SourceForge[^].
 
See also the Code Project article[^] on an update to XPTable.
 
Adam
QuestionProgressBar colormembermadmaxor23-May-12 23:50 
Can someone can tell me how i can change color on progressbar?
Bugusing with weifenluo, largechange property failsmemberNiyazi Yarar27-Feb-12 20:50 
my app uses a weifenluo as a dock manager. when i create a new float window and try to dock it to the some panel, an error occurs like this: Value of '-1' is not valid for 'LargeChange'. 'LargeChange' must be greater than or equal to 0.
Parameter name: LargeChange
. could you help about this?
mn.yarar

QuestionPicture over more than one rowmemberjulianw9228-Sep-11 3:41 
Hello,
 
is it possible, to draw a picture over more than 1 row? So that it looks like the view in the Windows Media Player?
 
This is my current version:
PICTURE
 

I would like to get something like this:
PICTURE
 

It would be very nice if somebody could help me Smile | :)
 

Greetings from Germany
Julian
BugBug - HideDropDown - Object Reference not set to an objectmemberMember 376612121-Jun-11 5:49 
I was using an older version of XPTable, but had problems with drop down boxes when using in 64-bit. I've now updated to the latest version 1.2. Now I am also having problems with drop down boxes. I am able to repeat the same steps and it will work the first time I open and select an item, but the next time I open a combo box and select an item it will crash in "HideDropDown" with "Object Reference not set to an object". I'm working on Windows 7 and 32-bit application and 64-bit application will both crash. These errors occur on 2 other machines I have tried as well. It crashes with the color combo box and the custom combo box. I am thinking about removing the drop downs, but I would hate to lose that functionality. Any suggestions?
 
System.NullReferenceException: Object reference not set to an instance of an object.
   at XPTable.Editors.DropDownCellEditor.HideDropDown()
   at XPTable.Editors.ComboBoxCellEditor.listbox_Click(Object sender, EventArgs e)
   at System.Windows.Forms.Control.OnClick(EventArgs e)
   at System.Windows.Forms.ListBox.WndProc(Message& m)
   at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
   at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)

GeneralRe: Bug - HideDropDown - Object Reference not set to an objectmemberadambl21-Jun-11 23:05 
Hi,
 
I am using XPTable on Win7 64 bit and can use drop down boxes with no problems.
 
Can you post some code that will show the bug?
 
Adam
GeneralRe: Bug - HideDropDown - Object Reference not set to an objectmemberNayan Choudhary2-Feb-12 9:58 
This issue happens on 64 bit versions also. I changed the function signature to this and it works fine:
 
Interface: IKeyMessageFilterClient
 
Change
bool ProcessKeyMessage(Control target, WindowMessage msg, int wParam, int lParam);
to
bool ProcessKeyMessage(Control target, WindowMessage msg, long wParam, long lParam);
 
You may need to change signature wherever this function has been implemented, which is 2-3 places only.
GeneralRe: Bug - HideDropDown - Object Reference not set to an objectmemberadambl19-Feb-13 22:15 
This is fixed in the updated code on SourceForge[^].
 
See also the Code Project article[^] on an update to XPTable.
 
Adam
QuestionBatch changing with comboboxmemberijavid30-Apr-11 1:43 
great library, many thanks! Thumbs Up | :thumbsup:
 
I want to do the following
- select multiple rows, (line select enabled)
- use the any combobox cell (from select rows)
- then apply the new value to each selected rows
 
is it possible ? anybody made something like this with this component ?
 
thx for any advice...
GeneralScrollbar Event Needed.membervishjhs13-Feb-11 20:46 
Hi,
 
I want to fire some code on Scroll bar Event.? But i dont see any Event mapped for it?
 
Regards,
Vishal

Questionhow to add a imge in a imagecolumnmemberdatsspeed21-Dec-10 23:05 
hello i tried to add a image in my imagecolumn ...
 

this is my code...
 

Dim myPic As Image = New System.Drawing.Bitmap(startpfad & "\Icons\email_accept.bmp")
 

 
tableModel.Rows(zeilex).Cells(6).Image = myPic
 
whats wrong :/ it not runs
 

lg datsspeed
GeneralRow Heightmemberwebmonk1219-Nov-10 5:03 
Any chance we can get an update which allows you to change individual row heights or have the row heights auto calculate when the content of the cell has carriage returns in them?
GeneralRe: Row Heightmemberadambl19-Feb-13 22:14 
Text wrapping has been added in the updated code on SourceForge[^].
 
See also the Code Project article[^] on an update to XPTable.
 
Adam
Questionhow to display a checkbox in a column header ?memberthononv30-Sep-10 23:33 
Hello,
I would like to display a checkbox in the header of a checkBoxColumn to select/unselect all rows
can you help me ?
Regards
Virginie
GeneralHide/Show a control in the gridmemberEd K20-Sep-10 11:34 
Is there a way to make a control hide/show in the grid?
 
I have two columns where in the last row I only need a button in one of the columns. So rather than disable the button I'd like to hide it.
 
Thanks!!
 
Neat control!
ed
 
~"Watch your thoughts; they become your words. Watch your words they become your actions.
Watch your actions; they become your habits. Watch your habits; they become your character.
Watch your character; it becomes your destiny."
-Frank Outlaw.

GeneralMy vote of 4membertingispig16-Sep-10 22:21 
it's just i need,3q
QuestionHow could I use it in VS?memberAric Green27-Jun-10 15:24 
How could I use it in VS?
I am not a genius, but shed more sweat!

GeneralHelpmemberhuangpu22-May-10 23:23 
It's very Good! But How Can I add a gif to TextColumn and Renderer is ImageCellRenderer?
 
Thank you!
ff

GeneralGroupingmemberDanielku1517-May-10 21:43 
Hi There.
I know it's an old and often requested feature: Will you implement the grouping feature like in Winforms Listview?
Are there any solutions for this problem yet?
 
--
ps: 5 stars Wink | ;)
GeneralRe: Groupingmemberadambl19-Feb-13 22:13 
This is fixed in the updated code on SourceForge[^].
 
See also the Code Project article[^] on an update to XPTable.
 
Adam
GeneralMerging of the Header TextColumnmembermellali8-Apr-10 22:54 
Hi dear devoloper.
I have a question , it es Possible, that i merge some Header Textcolumn ????
GeneralListen for changes in CheckBox columnmemberNeesy12-Mar-10 1:04 
Hi Matthew,
 
I am using the XPTable and I have a CheckBoxColumn in my ColumnModel.
When the table appears the check boxes are always unchecked regardles of whether or no the underlying cell value is true or false. How do I get the checkboxes to be checked for true and unchecked for false?
 
Additionally how do I get the check box in each cell to update the underlying boolean cell value?
 
Thanks
 
Kieran
QuestionDropDownCellEditor encount error,who can tell me how to use it?membertiger549101-Feb-10 17:21 
有关调用实时(JIT)调试而不是此对话框的详细信息,
请参阅此消息的结尾。
 
************** 异常文本 **************
System.NullReferenceException: 未将对象引用设置到对象的实例。
at XPTable.Editors.DropDownCellEditor.ShowDropDown()
at XPTable.Editors.ComboBoxCellEditor.ShowDropDown()
at XPTable.Editors.DropDownCellEditor.set_DroppedDown(Boolean value)
at XPTable.Editors.DropDownCellEditor.OnEditorButtonMouseDown(Object sender, CellMouseEventArgs e)
at XPTable.Renderers.DropDownCellRenderer.OnMouseDown(CellMouseEventArgs e)
at XPTable.Models.Table.OnCellMouseDown(CellMouseEventArgs e)
at XPTable.Models.Table.RaiseCellMouseDown(CellPos cellPos, MouseEventArgs e)
at XPTable.Models.Table.OnMouseDown(MouseEventArgs e)
at System.Windows.Forms.Control.WmMouseDown(Message& m, MouseButtons button, Int32 clicks)
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.ControlNativeWindow.OnMessage(Message& m)
at System.Windows.Forms.ControlNativeWindow.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
GeneralAwesome but found a tiny bugmemberXmen W.K.10-Nov-09 14:42 
First thanks for this awesome article...have 5
 

Reproducing the bug : When hover mouse to resize column header, the Cursor get changed to VSplit and when move mouse in vertically down direction...it never change back to normal unless you move mouse out of the ListView. Tested in Vista.
 


TVMU^P[[IGIOQHG^JSH`A#@`RFJ\c^JPL>;"[,*/|+&WLEZGc`AFXc!L
%^]*IRXD#@GKCQ`R\^SF_WcHbORY87֦ʻ6ϣN8ȤBcRAV\Z^&SU~%CSWQ@#2
W_AD`EPABIKRDFVS)EVLQK)JKQUFK[M`UKs*$GwU#QDXBER@CBN%
R0~53%eYrd8mt^7Z6]iTF+(EWfJ9zaK-i’TV.C\y<pŠjxsg-b$f4ia>
-----------------------------------------------
128 bit encrypted signature, crack if you can

GeneralRe: Awesome but found a tiny bugmemberadambl19-Feb-13 22:12 
This is fixed in the updated code on SourceForge[^].
 
See also the Code Project article[^] on an update to XPTable.
 
Adam
QuestionHow to set time in DateTimeColumnmembermehafi26-Oct-09 3:02 
Hi,
How to set time in DateTimeColumn? When I double click on it, displays a calendar so I could set a day, yer etc., but time is set to 00:00:00. So how to set time?
 
thanks in advance.
GeneralDrag & Drop again!memberthewizr2n29-Sep-09 12:56 
Sorry to bother ye guys with this!
 
Yet another one who would like to see dragging work...
I guess you guys are busy with other stuff and as I use an old version (constraints unfortunately) I only will need a hint of where I have to implement the delegate for DragEnter and DragDrop events in order to have a raise of those events in the callee application!
 
I thank you all in advance for your valuable time!
 
Kindly
Arthur
Questionnice job!! Have Web Version? I want to use in web pagememberscate27-Sep-09 21:50 
looks more better than MS gridviewCool | :cool:
I want to use in web Roll eyes | :rolleyes:
GeneralDrag Drap - How to Initiatemembercinamon16-Sep-09 12:00 
I see a similar post further below around April with no definitive response, so I'd like to ask again
 
I would like to initiate a Drag & Drop Opertion from XPtable into another control (a treelistview)
The XPTable does not seem to have a .ItemDrag event that could initiate the .DoDragDrop( function as a listview does. What is the recommended way to initiate a drag & drop opertion of multiple select rows ?
 
thanks in advance
QuestionColumn Fill feature.memberTheDmD22-Aug-09 1:42 
Is there a way to select a column which will be resized to fill the empty space? Exacly like in StatusStrip control in standard System.Windows.Forms library.
Questionhow do i center a checkbox column?memberagelospanagiotakis21-Jul-09 8:37 
how do i center the checkbox in a chackboxcolumn ?
QuestionSome question abort ColumnModel (such as comboboxColumn,datetimeColumn and numberColumn)[modified]memberDoubleHappyWolf8-Jul-09 16:03 
Hi All,
I am using the XPTable with c#.net 2005 and puzzled by some problems
1.comboboxColumn can not be rewriten by hand;
2.datetimeColumn's dropdownlist only dispaly half;
3.numberColumn's value is noly changed by arrowhead and Can not be negative
English is my foreign language and i am not good at it.
Wait for your reply
Thanks,
David
 
modified on Wednesday, July 8, 2009 10:53 PM

Question[Message Deleted]memberPatrick Schuetz5-Jul-09 20:09 

Questionauto Header Column width feature?memberagelospanagiotakis26-Jun-09 10:41 
Hi all is there a feature to this great control to set an automatic "Column Header Width" based on the text displayed on the column header?
Confused | :confused:
I searched the forums but did not find anything
how can i implement this ?
AnswerRe: auto Header Column width feature?memberadambl30-Jun-09 5:56 
Download the updated version of XPTable. See here[^]
 
Adam
GeneralRe: auto Header Column width feature?memberagelospanagiotakis30-Jun-09 6:46 
i don't understand .... which properties or methods should i use?
GeneralRe: auto Header Column width feature?memberadambl1-Jul-09 22:25 
You can call Table.AutoResizeColumnWidths() to resize all columns.
 
Adam
GeneralRe: auto Header Column width feature?memberagelospanagiotakis2-Jul-09 0:40 
this is the code i use to make the xptable resize columns correctly.
If you don't refresh first then the ContentWidth has no value.
  Public Shared Sub setColToDisplayAllContent(ByVal Cm As ColumnModel)
        If Cm.Table IsNot Nothing Then
            'this solves bug of xptable 
            'search http://www.codeproject.com/script/Forums/Search.aspx?fid=430881&kw=ContentWidth&FrmSrch=Search
            'http://www.codeproject.com/Messages/3003474/Re-Table-AutoResizeColumnWidths-still-doesn-t-work-in-my-code.aspx
            'http://www.codeproject.com/Messages/2874114/Re-Column-Width.aspx

            Cm.Table.Refresh()
            For Each Col As Column In Cm.Columns
                If Col.WidthNotSet Then
                    'Col.Width = Col.MinimumWidth
                End If
                If TypeOf (Col) Is ButtonColumn Then
                    Continue For
                End If
                If Col.Width < Col.ContentWidth Then
                    Col.Width = Col.ContentWidth
                End If
            Next
            Cm.Table.AutoResizeColumnWidths()
            Cm.Table.Refresh()
 
        End If

GeneralCan't set Ward-wrap to Truememberron197713-May-09 2:52 
hi,
i am trying to set word-wrap = true on a specific column.
after i change the cell property to true nothing happens.
 
i have a cell that the text in it is larger then the cell width.
the text is split into 2 lines. i want the text to be trimmed without changing the column size and without splitting the text into 2 lines.
Thanx.
Ron.
GeneralRe: Can't set Ward-wrap to Truememberadambl30-Jun-09 5:56 
You need to set the property Table.EnableWordWrap to true.
 
Adam
GeneralDrag/DropmemberDaniel Kamisnki4-Apr-09 4:50 
How can I implement Drag/Drop between the XPTable and a TreeView?
 
Thanks,
Daniel
QuestionRe: Drag/DropmemberDaniel Kamisnki4-Apr-09 8:16 
I just don't seem to be able to get the DragDrop operation started.
I have set these properties in the table:

MyXpTable.AllowSelection = True
MyXpTable.AllowDrop = True
MyXpTable.HideSelection = False
MyXpTable.SelectionStyle = SelectionStyle.ListView
MyXpTable.MultiSelect = True
 
but none of the DragDrop events seem to fire when I try to drag some cells over. Also the selection is reset and only one cell is selected.
 
I would appreciate any tips on how to make this work. The XpTable is fantastic by the way, great job!
 
Daniel
AnswerRe: Drag/Dropmemberiafaneh15-Apr-09 4:13 
You have to install latest version from source forge.
QuestionRe: Drag/DropmemberDaniel Kamisnki15-Apr-09 15:53 
iafaneh,
I did download the new version, thanks for letting me know, but I still not able to understand how to make it work. When I use a regular listview I implement the ItemDrag method to start the drag/drop operation... this method is not available in the XPTable! Could you please provide me with a few pointers on how to implement drag/drop in the XPTable?
 
Thanks,
Daniel
AnswerRe: Drag/Dropmemberiafaneh16-Apr-09 2:50 
Hello,
 
in couple of days i have to implement drag & drop functionality. and i will update you.
 
Thanks,
GeneralRe: Drag/DropmemberDaniel Kamisnki16-Apr-09 3:39 
Thanks! Please let me know when I can download it!
 
Daniel
GeneralRe: Drag/DropmemberBigNat22-Aug-09 20:00 
Is this available yet? Thanks.
GeneralERROR on SelectCellsmemberMember 376563827-Mar-09 0:51 
Hello,
 
The XPTable hat error!
At first Select a Row (ex. nr =0 ) with SelectCells.
XPTable got focus, and we change the Row by Up and Down (keyboard). Ex. Now the XPtable hat Selectrow=5
Remove all the Rows.
Add another Items to Tablemodel. (ex RowCount=3)
Select a Row (ex. nr =0 ) with SelectCells.
Change the Selectrow by keyboard >>>>> ERROR.
 
Please help me!
 
Thanks.

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web03 | 2.6.130617.1 | Last Updated 17 Sep 2005
Article Copyright 2005 by Mathew Hall
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid