# Creating a Custom Sheet Model

This topic explains how you can use a sheet model as a template to create a new custom model in Spread for ASP.NET.

## Content

You can use a sheet model as a template for a new custom model. For example, you might want to make a custom data model. Using a custom data model requires creating a class which implements [ISheetDataModel](/spreadnet/api/latest/online-asp/FarPoint.Web.Spread/FarPoint.Web.Spread.Model.ISheetDataModel.html), then setting an instance of the class into the SheetView.Models.Data property.
[ISheetDataModel](/spreadnet/api/latest/online-asp/FarPoint.Web.Spread/FarPoint.Web.Spread.Model.ISheetDataModel.html) is the only interface required, assuming that you do not need any of the optional interfaces. For more information on the optional interfaces, refer to [Understanding the Optional Interfaces](/spreadnet/docs/latest/online-asp/overview/spweb-devguide/spweb-usemodels/spweb-model-optinterfaces).
All of the optional interfaces are implemented by [DefaultSheetDataModel](/spreadnet/api/latest/online-asp/FarPoint.Web.Spread/FarPoint.Web.Spread.Model.DefaultSheetDataModel.html), so if you want any of them implemented on your data model, it may be easier to simply subclass [DefaultSheetDataModel](/spreadnet/api/latest/online-asp/FarPoint.Web.Spread/FarPoint.Web.Spread.Model.DefaultSheetDataModel.html).
In [BaseSheetDataModel](/spreadnet/api/latest/online-asp/FarPoint.Web.Spread/FarPoint.Web.Spread.Model.BaseSheetDataModel.html), the [Changed](/spreadnet/api/latest/online-asp/FarPoint.Web.Spread/FarPoint.Web.Spread.Model.BaseSheetDataModel.Changed.html) event is also implemented for you, along with the overloaded **FireChanged** method, so you do not need to provide an implementation of that event either. The event itself is the only thing in [BaseSheetDataModel](/spreadnet/api/latest/online-asp/FarPoint.Web.Spread/FarPoint.Web.Spread.Model.BaseSheetDataModel.html) that is not virtual.
The **FireChanged** and **OnChanged** methods are protected members of [BaseSheetDataModel](/spreadnet/api/latest/online-asp/FarPoint.Web.Spread/FarPoint.Web.Spread.Model.BaseSheetDataModel.html) and are not part of any interface. They are virtual helper methods for the **Changed** event. The only difference between the **FireChanged** and **OnChanged** method is that **OnChanged** takes the EventArgs argument, and **FireChanged** takes the arguments used to create the EventArgs. The **FireChanged** method will not create the EventArgs object unless there is actually a handler attached to the delegate, so it is better to use that in subclasses for firing the event.
In a few cases, you may need to create your own custom data model for performance reasons. For example, suppose you want to display a large table of computed values (such as an addition or multiplication table) that consists of a million rows by ten columns. If you used the default sheet data model, you would need to compute and store all ten million values which would consume a lot of time and memory. Here is example code that creates a custom data model that enhances performance.

## Example

This example creates a custom data model.

```csharp
for (r = 0; r < 1000000; r++)
for ( c = 0; c < 10; c++)
spread.Sheets[0].Cells[r,c].Value = r + c;

class ComputedDataModel : BaseSheetDataModel
{
    public override int RowCount
    {
        get { return 1000000; }
    }
    public override int ColumnCount
    {
        get { return 10; }
    }
    public override object GetValue(int row, int column)
    {
        return row + column;
    } 
}
```