Class TableModel<T>
Provides a strongly typed base class for implementing a table model.
public abstract class TableModel<T> : TableModel
Type Parameters
TThe cell value type exposed by the model. This can be a simple value such as string or int, or a richer object type that exposes multiple values through properties.
- Inheritance
-
TableModel<T>
- Inherited Members
Remarks
Derive from TableModel<T> when each cell in your table can be represented as a
value of type T. Implement Rows, Columns,
and the row/column indexer to describe the table shape and read or write cell values.
If T is a simple convertible type such as string or
int, the model automatically exposes that value through the built-in display
and edit roles. If T is a custom type, public instance properties of
that type are exposed automatically as named roles, and the whole item can also be exposed
through the item role.
Custom item types can opt into additional behavior by implementing IDisplayable, IEditable, or IModelItem: IDisplayable controls the value shown by default, IEditable enables in-place editing through the built-in edit role, and IModelItem controls whether a cell is enabled or selectable.
Row and column insert/remove operations follow the same begin/end notification contract as
Model. The public overrides are sealed and handled by this base class. To add
or remove rows or columns, implement the corresponding Can* and protected mutation
methods such as CanInsertRows(int, int) and InsertRows(int, int).
public class ScoreTable : TableModel<int>
{
private readonly int[,] values =
{
{ 10, 20, 30 },
{ 40, 50, 60 }
};
protected override int Rows => values.GetLength(0);
protected override int Columns => values.GetLength(1);
protected override int this[int row, int col]
{
get => values[row, col];
set => values[row, col] = value;
}
protected override string ColumnHeader(int column) => column switch
{
0 => "A",
1 => "B",
2 => "C",
_ => string.Empty
};
}
Properties
Columns
Gets the number of columns in the table.
protected abstract int Columns { get; }
Property Value
Remarks
Return the current root-level column count. The base class handles valid parent indexes for you and reports zero child columns automatically.
HasItemRole
Gets whether custom item types should expose the whole cell object through the
item role.
protected virtual bool HasItemRole { get; }
Property Value
Remarks
This applies only when T is not a simple convertible value.
Returning false hides the automatically added item role while
still exposing property-based roles.
IsReadOnly
Gets whether the model should reject all edit operations.
protected virtual bool IsReadOnly { get; }
Property Value
Remarks
When this property returns true, the model does not expose the built-in edit role and SetData(ModelIndex, object, int) always returns false.
this[int, int]
Gets or sets the value stored at the specified row and column.
protected abstract T this[int row, int col] { get; set; }
Parameters
Property Value
- T
Remarks
This is the primary hook for reading and writing cell data. For simple value types, the base class uses this indexer to serve both display and edit requests. For custom item types, the returned object is also used to resolve property-based roles.
Rows
Gets the number of rows in the table.
protected abstract int Rows { get; }
Property Value
Remarks
Return the current root-level row count. The base class handles valid parent indexes for you and reports zero child rows automatically.
Methods
Buddy(ModelIndex)
Returns an alternate item that should be edited instead of the specified item.
public override sealed ModelIndex Buddy(ModelIndex index)
Parameters
indexModelIndex
Returns
- ModelIndex
CanFetchMore(ModelIndex)
Returns whether more child items can be loaded for the specified parent.
public override sealed bool CanFetchMore(ModelIndex parent)
Parameters
parentModelIndex
Returns
CanInsertColumns(int, int)
Returns whether columns can be inserted at the specified position.
protected virtual bool CanInsertColumns(int column, int count)
Parameters
Returns
Remarks
Use this to validate column insertion requests before the model begins its structural change notification sequence. The default implementation returns false.
CanInsertRows(int, int)
Returns whether rows can be inserted at the specified position.
protected virtual bool CanInsertRows(int row, int count)
Parameters
Returns
Remarks
Use this to validate row insertion requests before the model begins its structural change notification sequence. The default implementation returns false.
CanRemoveColumns(int, int)
Returns whether columns can be removed from the specified position.
protected virtual bool CanRemoveColumns(int column, int count)
Parameters
Returns
Remarks
Use this to validate column removal requests before the model begins its structural change notification sequence. The default implementation returns false.
CanRemoveRows(int, int)
Returns whether rows can be removed from the specified position.
protected virtual bool CanRemoveRows(int row, int count)
Parameters
Returns
Remarks
Use this to validate row removal requests before the model begins its structural change notification sequence. The default implementation returns false.
ClearItemData(ModelIndex)
Clears the value for the specified cell.
public override sealed bool ClearItemData(ModelIndex index)
Parameters
indexModelIndex
Returns
Remarks
This forwards a valid model index to ClearItemData(int, int) and rejects invalid indexes.
ClearItemData(int, int)
Clears the value at the specified cell.
protected virtual bool ClearItemData(int row, int col)
Parameters
Returns
Remarks
Override this when your model supports a "clear cell" operation that is distinct from setting a normal value. The default implementation returns false. Call one of the DataChanged(int, int) overloads after a successful clear so connected views refresh.
ColumnCount(ModelIndex)
Returns the number of columns for the specified parent index.
public override sealed int ColumnCount(ModelIndex idx)
Parameters
idxModelIndex
Returns
Remarks
For the root level, this returns Columns. For valid parent indexes, it
returns 0 because TableModel<T> does not expose child items.
ColumnHeader(int)
Returns the label for a column header.
protected virtual string ColumnHeader(int column)
Parameters
columnint
Returns
Remarks
The default implementation returns C1, C2, and so on. Override this to
provide domain-specific column names such as field names or spreadsheet letters.
Data(ModelIndex, int)
Returns the value for the specified cell and role.
public override sealed object Data(ModelIndex index, int role)
Parameters
indexModelIndexroleint
Returns
Remarks
For simple value types, the built-in display and edit roles return the cell value
directly. For custom item types, the base class uses IDisplayable,
IEditable, the optional item role, and public instance properties
to resolve role values.
DataChanged(int, int)
Notifies that a single cell value has changed.
protected void DataChanged(int row, int column)
Parameters
Remarks
Call this after updating the backing store outside of SetData(ModelIndex, object, int) so views and delegates refresh the cell.
DataChanged(int, int, int, int)
Notifies that a rectangular cell range has changed.
protected void DataChanged(int topRow, int leftColumn, int bottomRow, int rightColumn)
Parameters
Remarks
Use this overload when one operation updates multiple cells, such as recalculating a block of formulas or replacing a rectangular selection.
FetchMore(ModelIndex)
Loads additional child items for the specified parent.
public override sealed void FetchMore(ModelIndex parent)
Parameters
parentModelIndex
Flags(ModelIndex)
Returns the capability flags for the specified cell.
public override sealed int Flags(ModelIndex index)
Parameters
indexModelIndex
Returns
Remarks
The base implementation derives enabled/selectable state from IModelItem
when available and derives editability from IsReadOnly,
T, and IEditable.
HeaderData(int, int, int)
Returns the header value for the specified section.
public override sealed object HeaderData(int section, int orientation, int role)
Parameters
Returns
Remarks
The base implementation exposes only display values for horizontal and vertical headers, using ColumnHeader(int) and RowHeader(int).
InsertColumns(int, int)
Inserts columns at the specified position.
protected virtual bool InsertColumns(int column, int count)
Parameters
Returns
Remarks
This method is called only after CanInsertColumns(int, int) succeeds. The base class performs the required begin/end notification calls around this method, so your implementation should perform the already-validated backing-store update rather than re-checking whether the operation is allowed.
InsertColumns(int, int, ModelIndex)
Inserts columns at the specified root-level position.
public override sealed bool InsertColumns(int column, int count, ModelIndex parent = null)
Parameters
Returns
Remarks
The base class rejects valid parent indexes, validates the request with CanInsertColumns(int, int), and performs the required structural change notifications around InsertColumns(int, int).
InsertRows(int, int)
Inserts rows at the specified position.
protected virtual bool InsertRows(int row, int count)
Parameters
Returns
Remarks
This method is called only after CanInsertRows(int, int) succeeds. The base class performs the required begin/end notification calls around this method, so your implementation should perform the already-validated backing-store update rather than re-checking whether the operation is allowed.
InsertRows(int, int, ModelIndex)
Inserts rows at the specified root-level position.
public override sealed bool InsertRows(int row, int count, ModelIndex parent = null)
Parameters
Returns
Remarks
The base class rejects valid parent indexes, validates the request with CanInsertRows(int, int), and performs the required structural change notifications around InsertRows(int, int).
MoveColumns(ModelIndex, int, int, ModelIndex, int)
Moves columns from one parent and position to another.
public override sealed bool MoveColumns(ModelIndex sourceParent, int sourceColumn, int count, ModelIndex destinationParent, int destinationChild)
Parameters
sourceParentModelIndexsourceColumnintcountintdestinationParentModelIndexdestinationChildint
Returns
MoveRows(ModelIndex, int, int, ModelIndex, int)
Moves rows from one parent and position to another.
public override sealed bool MoveRows(ModelIndex sourceParent, int sourceRow, int count, ModelIndex destinationParent, int destinationChild)
Parameters
Returns
RemoveColumns(int, int)
Removes columns from the specified position.
protected virtual bool RemoveColumns(int column, int count)
Parameters
Returns
Remarks
This method is called only after CanRemoveColumns(int, int) succeeds. The base class performs the required begin/end notification calls around this method, so your implementation should perform the already-validated backing-store update rather than re-checking whether the operation is allowed.
RemoveColumns(int, int, ModelIndex)
Removes columns from the specified root-level position.
public override sealed bool RemoveColumns(int column, int count, ModelIndex parent = null)
Parameters
Returns
Remarks
The base class rejects valid parent indexes, validates the request with CanRemoveColumns(int, int), and performs the required structural change notifications around RemoveColumns(int, int).
RemoveRows(int, int)
Removes rows from the specified position.
protected virtual bool RemoveRows(int row, int count)
Parameters
Returns
Remarks
This method is called only after CanRemoveRows(int, int) succeeds. The base class performs the required begin/end notification calls around this method, so your implementation should perform the already-validated backing-store update rather than re-checking whether the operation is allowed.
RemoveRows(int, int, ModelIndex)
Removes rows from the specified root-level position.
public override sealed bool RemoveRows(int row, int count, ModelIndex parent = null)
Parameters
Returns
Remarks
The base class rejects valid parent indexes, validates the request with CanRemoveRows(int, int), and performs the required structural change notifications around RemoveRows(int, int).
RoleNames()
Returns the role names inferred from T.
public override sealed Dictionary<int, string> RoleNames()
Returns
Remarks
Depending on the item type, this can include the built-in display and
edit roles, the item role for the whole cell object, and property-based
roles generated from public instance properties.
RowCount(ModelIndex)
Returns the number of rows for the specified parent index.
public override sealed int RowCount(ModelIndex idx)
Parameters
idxModelIndex
Returns
Remarks
For the root level, this returns Rows. For valid parent indexes, it
returns 0 because TableModel<T> is always a flat table rather
than a hierarchical model.
RowHeader(int)
Returns the label for a row header.
protected virtual string RowHeader(int row)
Parameters
rowint
Returns
Remarks
The default implementation returns R1, R2, and so on. Override this to
provide application-specific row labels.
SetData(ModelIndex, object, int)
Updates the value for the specified cell and role.
public override sealed bool SetData(ModelIndex index, object value, int role)
Parameters
Returns
Remarks
For editable simple value types, this updates the cell through the row/column indexer.
For custom item types, it updates either EditValue, the full
item via the item role, or a writable public property. Successful updates
automatically notify connected views.
SetHeaderData(int, int, object, int)
Updates the value of a header section for the specified role.
public override sealed bool SetHeaderData(int section, int orientation, object value, int role)
Parameters
Returns
Sort(int, int)
Reorders the model by the specified column and direction.
public override sealed void Sort(int column, int order)