Edit

Share via


DataGridViewImageColumn Class

Definition

Hosts a collection of DataGridViewImageCell objects.

public ref class DataGridViewImageColumn : System::Windows::Forms::DataGridViewColumn
[System.Drawing.ToolboxBitmap(typeof(System.Windows.Forms.DataGridViewImageColumn), "DataGridViewImageColumn.bmp")]
public class DataGridViewImageColumn : System.Windows.Forms.DataGridViewColumn
[System.Drawing.ToolboxBitmap(typeof(System.Windows.Forms.DataGridViewImageColumn), "DataGridViewImageColumn")]
public class DataGridViewImageColumn : System.Windows.Forms.DataGridViewColumn
[<System.Drawing.ToolboxBitmap(typeof(System.Windows.Forms.DataGridViewImageColumn), "DataGridViewImageColumn.bmp")>]
type DataGridViewImageColumn = class
    inherit DataGridViewColumn
[<System.Drawing.ToolboxBitmap(typeof(System.Windows.Forms.DataGridViewImageColumn), "DataGridViewImageColumn")>]
type DataGridViewImageColumn = class
    inherit DataGridViewColumn
Public Class DataGridViewImageColumn
Inherits DataGridViewColumn
Inheritance
Attributes

Examples

The following code example demonstrates how to use images to create a TicTacToe game.

#using <System.Drawing.dll>
#using <System.dll>
#using <system.windows.forms.dll>

using namespace System::IO;
using namespace System::Windows::Forms;
using namespace System::Drawing;
using namespace System;
public ref class TicTacToe: public System::Windows::Forms::Form
{
public:
   TicTacToe()
      : Form()
   {
      oBytes = gcnew array<Byte>{
        0x42, 0x4D, 0xC6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x76, 
        0x0, 0x0, 0x0, 0x28, 0x0, 0x0, 0x0, 0xB, 0x0, 0x0, 0x0, 0xA,
        0x0, 0x0, 0x0, 0x1, 0x0, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x50,
        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10,
        0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
        0x0, 0x80, 0x0, 0x0, 0x80, 0x0, 0x0, 0x0, 0x80, 0x80, 0x0, 
        0x80, 0x0, 0x0, 0x0, 0x80, 0x0, 0x80, 0x0, 0x80, 0x80, 0x0, 
        0x0, 0xC0, 0xC0, 0xC0, 0x0, 0x80, 0x80, 0x80, 0x0, 0x0, 0x0,
        0xFF, 0x0, 0x0, 0xFF, 0x0, 0x0, 0x0, 0xFF, 0xFF, 0x0, 0xFF, 
        0x0, 0x0, 0x0, 0xFF, 0x0, 0xFF, 0x0, 0xFF, 0xFF, 0x0, 0x0, 
        0xFF, 0xFF, 0xFF, 0x0, 0xFF, 0xFF, 0x0, 0xF, 0xFF, 0xF0, 
        0x0, 0x0, 0xFF, 0x0, 0xFF, 0xF0, 0xF, 0xF0, 0x0, 0x0, 0xF0, 
        0xFF, 0xFF, 0xFF, 0xF0, 0xF0, 0x0, 0x0, 0xF0, 0xFF, 0xFF, 
        0xFF, 0xF0, 0xF0, 0x0, 0x0, 0xF, 0xFF, 0xFF, 0xFF, 0xFF, 
        0x0, 0x0, 0x0, 0xF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0, 0x0, 0x0, 
        0xF0, 0xFF, 0xFF, 0xFF, 0xF0, 0xF0, 0x0, 0x0, 0xF0, 0xFF, 
        0xFF, 0xFF, 0xF0, 0xF0, 0x0, 0x0, 0xFF, 0x0, 0xFF, 0xF0, 
        0xF, 0xF0, 0x0, 0x0, 0xFF, 0xFF, 0x0, 0xF, 0xFF, 0xF0, 0x0, 
        0x0};
      xBytes = gcnew array<Byte>{
        0x42, 0x4D, 0xC6, 0x0, 0x0, 0x0, 0x0, 
        0x0, 0x0, 0x0, 0x76, 0x0, 0x0, 0x0, 0x28, 0x0, 0x0, 0x0, 
        0xB, 0x0, 0x0, 0x0, 0xA, 0x0, 0x0, 0x0, 0x1, 0x0, 0x4, 0x0, 
        0x0, 0x0, 0x0, 0x0, 0x50, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
        0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 
        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x80, 0x0, 0x0, 0x80, 
        0x0, 0x0, 0x0, 0x80, 0x80, 0x0, 0x80, 0x0, 0x0, 0x0, 0x80, 
        0x0, 0x80, 0x0, 0x80, 0x80, 0x0, 0x0, 0xC0, 0xC0, 0xC0, 0x0,
        0x80, 0x80, 0x80, 0x0, 0x0, 0x0, 0xFF, 0x0, 0x0, 0xFF, 0x0, 
        0x0, 0x0, 0xFF, 0xFF, 0x0, 0xFF, 0x0, 0x0, 0x0, 0xFF, 0x0, 
        0xFF, 0x0, 0xFF, 0xFF, 0x0, 0x0, 0xFF, 0xFF, 0xFF, 0x0, 
        0xF0, 0xFF, 0xFF, 0xFF, 0xF0, 0xF0, 0x0, 0x0, 0xFF, 0xF, 
        0xFF, 0xFF, 0xF, 0xF0, 0x0, 0x0, 0xFF, 0xF0, 0xFF, 0xF0, 
        0xFF, 0xF0, 0x0, 0x0, 0xFF, 0xFF, 0xF, 0xF, 0xFF, 0xF0, 0x0,
        0x0, 0xFF, 0xFF, 0xF, 0xF, 0xFF, 0xF0, 0x0, 0x0, 0xFF, 0xFF,
        0xF, 0xF, 0xFF, 0xF0, 0x0, 0x0, 0xFF, 0xF0, 0xFF, 0xF0, 
        0xFF, 0xF0, 0x0, 0x0, 0xFF, 0xF, 0xFF, 0xFF, 0xF, 0xF0, 0x0,
        0x0, 0xF0, 0xFF, 0xFF, 0xFF, 0xF0, 0xF0, 0x0, 0x0, 0xFF, 
        0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x0, 0x0};
      blankBytes = gcnew array<Byte>{
        0x42, 0x4D, 0xC6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x76, 
        0x0, 0x0, 0x0, 0x28, 0x0, 0x0, 0x0, 0xB, 0x0, 0x0, 0x0, 0xA,
        0x0, 0x0, 0x0, 0x1, 0x0, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x50,
        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10,
        0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
        0x0, 0x80, 0x0, 0x0, 0x80, 0x0, 0x0, 0x0, 0x80, 0x80, 0x0, 
        0x80, 0x0, 0x0, 0x0, 0x80, 0x0, 0x80, 0x0, 0x80, 0x80, 0x0, 
        0x0, 0xC0, 0xC0, 0xC0, 0x0, 0x80, 0x80, 0x80, 0x0, 0x0, 0x0,
        0xFF, 0x0, 0x0, 0xFF, 0x0, 0x0, 0x0, 0xFF, 0xFF, 0x0, 0xFF, 
        0x0, 0x0, 0x0, 0xFF, 0x0, 0xFF, 0x0, 0xFF, 0xFF, 0x0, 0x0, 
        0xFF, 0xFF, 0xFF, 0x0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 
        0x0, 0x0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x0, 0x0, 
        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x0, 0x0, 0xFF, 0xFF, 
        0xFF, 0xFF, 0xFF, 0xF0, 0x0, 0x0, 0xFF, 0xFF, 0xFF, 0xFF, 
        0xFF, 0xF0, 0x0, 0x0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 
        0x0, 0x0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x0, 0x0, 
        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x0, 0x0, 0xFF, 0xFF, 
        0xFF, 0xFF, 0xFF, 0xF0, 0x0, 0x0, 0xFF, 0xFF, 0xFF, 0xFF, 
        0xFF, 0xF0, 0x0, 0x0};
      blank = gcnew Bitmap( gcnew MemoryStream( blankBytes ) );
      x = gcnew Bitmap( gcnew MemoryStream( xBytes ) );
      o = gcnew Bitmap( gcnew MemoryStream( oBytes ) );
      this->AutoSize = true;
      turn = gcnew Label;
      Button1 = gcnew Button;
      Button2 = gcnew Button;
      Button3 = gcnew Button;
      Button4 = gcnew Button;
      Button5 = gcnew Button;
      Panel1 = gcnew FlowLayoutPanel;
      SetupButtons();
      InitializeDataGridView( nullptr, nullptr );

      xString = L"X's turn";
      oString = L"O's turn";
      gameOverString = L"Game Over";
      bitmapPadding = 6;
   }


private:
   DataGridView^ dataGridView1;
   Button^ Button1;
   Label^ turn;
   Button^ Button2;
   Button^ Button3;
   Button^ Button4;
   Button^ Button5;
   FlowLayoutPanel^ Panel1;

#pragma region S " bitmaps " 
   array<Byte>^oBytes;
   array<Byte>^xBytes;
   array<Byte>^blankBytes;

#pragma endregion 
   Bitmap^ blank;
   Bitmap^ x;
   Bitmap^ o;
   String^ xString;
   String^ oString;
   String^ gameOverString;
   int bitmapPadding;
   void InitializeDataGridView( Object^ ignored, EventArgs^ e )
   {
      this->Panel1->SuspendLayout();
      this->SuspendLayout();
      ConfigureForm();
      SizeGrid();
      CreateColumns();
      CreateRows();
      this->Panel1->ResumeLayout( false );
      this->ResumeLayout( false );
   }

   void ConfigureForm()
   {
      AutoSize = true;
      turn->Size = System::Drawing::Size( 75, 34 );
      turn->TextAlign = ContentAlignment::MiddleLeft;
      Panel1->Location = System::Drawing::Point( 0, 8 );
      Panel1->Size = System::Drawing::Size( 120, 196 );
      Panel1->FlowDirection = FlowDirection::TopDown;
      ClientSize = System::Drawing::Size( 355, 200 );
      Controls->Add( this->Panel1 );
      Text = L"TicTacToe";
      dataGridView1 = gcnew System::Windows::Forms::DataGridView;
      dataGridView1->Location = Point(120,0);
      dataGridView1->AllowUserToAddRows = false;
      dataGridView1->CellClick += gcnew DataGridViewCellEventHandler( this, &TicTacToe::dataGridView1_CellClick );
      dataGridView1->CellMouseEnter += gcnew DataGridViewCellEventHandler( this, &TicTacToe::dataGridView1_CellMouseEnter );
      dataGridView1->CellMouseLeave += gcnew DataGridViewCellEventHandler( this, &TicTacToe::dataGridView1_CellMouseLeave );
      Controls->Add( dataGridView1 );
      turn->Text = xString;
      turn->AutoSize = true;
   }

   void SetupButtons()
   {
      Button1->AutoSize = true;
      SetupButton( Button1, L"Restart", gcnew EventHandler( this, &TicTacToe::Reset ) );
      Panel1->Controls->Add( turn );
      SetupButton( Button2, L"Increase Cell Size", gcnew EventHandler( this, &TicTacToe::MakeCellsLarger ) );
      SetupButton( Button3, L"Stretch Images", gcnew EventHandler( this, &TicTacToe::Stretch ) );
      SetupButton( Button4, L"Zoom Images", gcnew EventHandler( this, &TicTacToe::ZoomToImage ) );
      SetupButton( Button5, L"Normal Images", gcnew EventHandler( this, &TicTacToe::NormalImage ) );
   }

   void SetupButton( Button^ button, String^ buttonLabel, EventHandler^ handler )
   {
      Panel1->Controls->Add( button );
      button->Text = buttonLabel;
      button->AutoSize = true;
      button->Click += handler;
   }


   void CreateColumns()
   {
      DataGridViewImageColumn^ imageColumn;
      int columnCount = 0;
      do
      {
         Bitmap^ unMarked = blank;
         imageColumn = gcnew DataGridViewImageColumn;
         
         //Add twice the padding for the left and 
         //right sides of the cell.
         imageColumn->Width = x->Width + 2 * bitmapPadding + 1;
         imageColumn->Image = unMarked;
         dataGridView1->Columns->Add( imageColumn );
         columnCount = columnCount + 1;
      }
      while ( columnCount < 3 );
   }


   void CreateRows()
   {
      dataGridView1->Rows->Add();
      dataGridView1->Rows->Add();
      dataGridView1->Rows->Add();
   }


   void SizeGrid()
   {
      dataGridView1->ColumnHeadersVisible = false;
      dataGridView1->RowHeadersVisible = false;
      dataGridView1->AllowUserToResizeColumns = false;
      dataGridView1->AllowUserToResizeRows = false;
      dataGridView1->BorderStyle = BorderStyle::None;
      
      //Add twice the padding for the top of the cell 
      //and the bottom.
      dataGridView1->RowTemplate->Height = x->Height + 2 * bitmapPadding + 1;
      dataGridView1->AutoSize = true;
   }


   void Reset( Object^ sender, System::EventArgs^ e )
   {
      dataGridView1->~DataGridView();
      InitializeDataGridView( nullptr, nullptr );
   }


   void dataGridView1_CellClick( Object^ sender, DataGridViewCellEventArgs^ e )
   {
      if ( turn->Equals( gameOverString ) )
      {
         return;
      }

      DataGridViewImageCell^ cell = dynamic_cast<DataGridViewImageCell^>(dataGridView1->Rows[ e->RowIndex ]->Cells[ e->ColumnIndex ]);
      if ( cell->Value == blank )
      {
         if ( IsOsTurn() )
         {
            cell->Value = o;
         }
         else
         {
            cell->Value = x;
         }

         ToggleTurn();
      }

      if ( IsAWin( cell ) )
      {
         turn->Text = gameOverString;
      }
   }


   void dataGridView1_CellMouseEnter( Object^ sender, DataGridViewCellEventArgs^ e )
   {
      Bitmap^ markingUnderMouse = dynamic_cast<Bitmap^>(dataGridView1->Rows[ e->RowIndex ]->Cells[ e->ColumnIndex ]->Value);
      if ( markingUnderMouse == blank )
      {
         dataGridView1->Cursor = Cursors::Default;
      }
      else
      if ( markingUnderMouse == o || markingUnderMouse == x )
      {
         dataGridView1->Cursor = Cursors::No;
         ToolTip(e,true);
      }
   }

   void ToolTip( DataGridViewCellEventArgs^ e, bool showTip )
   {
      DataGridViewImageCell^ cell = dynamic_cast<DataGridViewImageCell^>(dataGridView1->Rows[ e->RowIndex ]->Cells[ e->ColumnIndex ]);
      DataGridViewImageColumn^ imageColumn = dynamic_cast<DataGridViewImageColumn^>(dataGridView1->Columns[ cell->ColumnIndex ]);
      if ( showTip )
            cell->ToolTipText = imageColumn->Description;
      else
      {
         cell->ToolTipText = String::Empty;
      }
   }

   void dataGridView1_CellMouseLeave( Object^ sender, DataGridViewCellEventArgs^ e )
   {
      ToolTip( e, false );
      dataGridView1->Cursor = Cursors::Default;
   }


   void Stretch( Object^ sender, EventArgs^ e )
   {
      System::Collections::IEnumerator^ myEnum = dataGridView1->Columns->GetEnumerator();
      while ( myEnum->MoveNext() )
      {
         DataGridViewImageColumn^ column = safe_cast<DataGridViewImageColumn^>(myEnum->Current);
         column->ImageLayout = DataGridViewImageCellLayout::Stretch;
         column->Description = L"Stretched";
      }
   }

   void ZoomToImage( Object^ sender, EventArgs^ e )
   {
      System::Collections::IEnumerator^ myEnum1 = dataGridView1->Columns->GetEnumerator();
      while ( myEnum1->MoveNext() )
      {
         DataGridViewImageColumn^ column = safe_cast<DataGridViewImageColumn^>(myEnum1->Current);
         column->ImageLayout = DataGridViewImageCellLayout::Zoom;
         column->Description = L"Zoomed";
      }
   }

   void NormalImage( Object^ sender, EventArgs^ e )
   {
      System::Collections::IEnumerator^ myEnum2 = dataGridView1->Columns->GetEnumerator();
      while ( myEnum2->MoveNext() )
      {
         DataGridViewImageColumn^ column = safe_cast<DataGridViewImageColumn^>(myEnum2->Current);
         column->ImageLayout = DataGridViewImageCellLayout::Normal;
         column->Description = L"Normal";
      }
   }


   void MakeCellsLarger( Object^ sender, EventArgs^ e )
   {
      System::Collections::IEnumerator^ myEnum3 = dataGridView1->Columns->GetEnumerator();
      while ( myEnum3->MoveNext() )
      {
         DataGridViewImageColumn^ column = safe_cast<DataGridViewImageColumn^>(myEnum3->Current);
         column->Width = column->Width * 2;
      }

      System::Collections::IEnumerable^ temp = safe_cast<System::Collections::IEnumerable^>(dataGridView1->Rows);
      System::Collections::IEnumerator^ myEnum4 = temp->GetEnumerator();

      //System::Collections::IEnumerator^ myEnum4 = dataGridView1->Rows->GetEnumerator();
      while ( myEnum4->MoveNext() )
      {
         DataGridViewRow^ row = safe_cast<DataGridViewRow^>(myEnum4->Current);
         if ( row->IsNewRow )
                  break;
         row->Height = (int)(row->Height * 1.5);
      }
   }

   bool IsAWin( DataGridViewCell^ cell )
   {
      if ( ARowIsSame() || AColumnIsSame() || ADiagonalIsSame() )
            return true;
      else
            return false;
   }

   bool ARowIsSame()
   {
      Bitmap^ marking = nullptr;
      System::Collections::IEnumerable^ temp = safe_cast<System::Collections::IEnumerable^>(dataGridView1->Rows);
      System::Collections::IEnumerator^ myEnum5 = temp->GetEnumerator();
      //System::Collections::IEnumerator^ myEnum5 = dataGridView1->Rows->GetEnumerator();
      while ( myEnum5->MoveNext() )
      {
         DataGridViewRow^ row = safe_cast<DataGridViewRow^>(myEnum5->Current);
         if ( row->IsNewRow )
                  break;

         marking = dynamic_cast<Bitmap^>(row->Cells[ 0 ]->Value);
         if ( marking != blank )
         {
            if ( marking == row->Cells[ 1 ]->Value && marking == row->Cells[ 2 ]->Value )
                        return true;
         }
      }

      return false;
   }

   bool AColumnIsSame()
   {
      int columnIndex = 0;
      Bitmap^ marking;
      do
      {
         marking = dynamic_cast<Bitmap^>(dataGridView1->Rows[ 0 ]->Cells[ columnIndex ]->Value);
         if ( marking != blank )
         {
            if ( marking == dynamic_cast<Bitmap^>(dataGridView1->Rows[ 1 ]->Cells[ columnIndex ]->Value) && marking == dynamic_cast<Bitmap^>(dataGridView1->Rows[ 2 ]->Cells[ columnIndex ]->Value) )
                        return true;
         }

         columnIndex = columnIndex + 1;
      }
      while ( columnIndex < dataGridView1->Columns->GetColumnCount( DataGridViewElementStates::Visible ) );

      return false;
   }

   bool ADiagonalIsSame()
   {
      if ( LeftToRightDiagonalIsSame() )
      {
         return true;
      }

      if ( RightToLeftDiagonalIsSame() )
      {
         return true;
      }

      return false;
   }

   bool LeftToRightDiagonalIsSame()
   {
      return IsDiagonalSame( 0, 2 );
   }

   bool RightToLeftDiagonalIsSame()
   {
      return IsDiagonalSame( 2, 0 );
   }

   bool IsDiagonalSame( int startingColumn, int lastColumn )
   {
      Bitmap^ marking = dynamic_cast<Bitmap^>(dataGridView1->Rows[ 0 ]->Cells[ startingColumn ]->Value);
      if ( marking == blank )
            return false;

      if ( marking == dataGridView1->Rows[ 1 ]->Cells[ 1 ]->Value && marking == dataGridView1->Rows[ 2 ]->Cells[ lastColumn ]->Value )
            return true;

      return false;
   }

   void ToggleTurn()
   {
      if ( turn->Text->Equals( xString ) )
      {
         turn->Text = oString;
      }
      else
      {
         turn->Text = xString;
      }
   }

   bool IsOsTurn()
   {
      if ( turn->Text->Equals( oString ) )
            return true;

      return false;
   }


public:

   [STAThread]
   static void Main()
   {
      Application::Run( gcnew TicTacToe );
   }

};

int main()
{
   TicTacToe::Main();
}
using System.IO;
using System.Windows.Forms;
using System.Drawing;
using System;

public class TicTacToe : System.Windows.Forms.Form
{
    public TicTacToe()
    {
        blank = new Bitmap(new MemoryStream(blankImage));
        x = new Bitmap(new MemoryStream(xImage));
        o = new Bitmap(new MemoryStream(oImage));

        this.AutoSize = true;
        SetupButtons();
        InitializeDataGridView(null, null);
    }

    private DataGridView dataGridView1;
    private Button Button1 = new Button();
    private Label turn = new Label();
    private Button Button2 = new Button();
    private Button Button3 = new Button();
    private Button Button4 = new Button();
    private Button Button5 = new Button();
    private FlowLayoutPanel Panel1 = new FlowLayoutPanel();

    #region "bitmaps"
    private byte[] oImage = new byte[] {
        0x42, 0x4D, 0xC6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x76, 
        0x0, 0x0, 0x0, 0x28, 0x0, 0x0, 0x0, 0xB, 0x0, 0x0, 0x0, 0xA,
        0x0, 0x0, 0x0, 0x1, 0x0, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x50,
        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10,
        0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
        0x0, 0x80, 0x0, 0x0, 0x80, 0x0, 0x0, 0x0, 0x80, 0x80, 0x0, 
        0x80, 0x0, 0x0, 0x0, 0x80, 0x0, 0x80, 0x0, 0x80, 0x80, 0x0, 
        0x0, 0xC0, 0xC0, 0xC0, 0x0, 0x80, 0x80, 0x80, 0x0, 0x0, 0x0,
        0xFF, 0x0, 0x0, 0xFF, 0x0, 0x0, 0x0, 0xFF, 0xFF, 0x0, 0xFF, 
        0x0, 0x0, 0x0, 0xFF, 0x0, 0xFF, 0x0, 0xFF, 0xFF, 0x0, 0x0, 
        0xFF, 0xFF, 0xFF, 0x0, 0xFF, 0xFF, 0x0, 0xF, 0xFF, 0xF0, 
        0x0, 0x0, 0xFF, 0x0, 0xFF, 0xF0, 0xF, 0xF0, 0x0, 0x0, 0xF0, 
        0xFF, 0xFF, 0xFF, 0xF0, 0xF0, 0x0, 0x0, 0xF0, 0xFF, 0xFF, 
        0xFF, 0xF0, 0xF0, 0x0, 0x0, 0xF, 0xFF, 0xFF, 0xFF, 0xFF, 
        0x0, 0x0, 0x0, 0xF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0, 0x0, 0x0, 
        0xF0, 0xFF, 0xFF, 0xFF, 0xF0, 0xF0, 0x0, 0x0, 0xF0, 0xFF, 
        0xFF, 0xFF, 0xF0, 0xF0, 0x0, 0x0, 0xFF, 0x0, 0xFF, 0xF0, 
        0xF, 0xF0, 0x0, 0x0, 0xFF, 0xFF, 0x0, 0xF, 0xFF, 0xF0, 0x0, 
        0x0};

    private byte[] xImage = new byte[]{
        0x42, 0x4D, 0xC6, 0x0, 0x0, 0x0, 0x0, 
        0x0, 0x0, 0x0, 0x76, 0x0, 0x0, 0x0, 0x28, 0x0, 0x0, 0x0, 
        0xB, 0x0, 0x0, 0x0, 0xA, 0x0, 0x0, 0x0, 0x1, 0x0, 0x4, 0x0, 
        0x0, 0x0, 0x0, 0x0, 0x50, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
        0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 
        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x80, 0x0, 0x0, 0x80, 
        0x0, 0x0, 0x0, 0x80, 0x80, 0x0, 0x80, 0x0, 0x0, 0x0, 0x80, 
        0x0, 0x80, 0x0, 0x80, 0x80, 0x0, 0x0, 0xC0, 0xC0, 0xC0, 0x0,
        0x80, 0x80, 0x80, 0x0, 0x0, 0x0, 0xFF, 0x0, 0x0, 0xFF, 0x0, 
        0x0, 0x0, 0xFF, 0xFF, 0x0, 0xFF, 0x0, 0x0, 0x0, 0xFF, 0x0, 
        0xFF, 0x0, 0xFF, 0xFF, 0x0, 0x0, 0xFF, 0xFF, 0xFF, 0x0, 
        0xF0, 0xFF, 0xFF, 0xFF, 0xF0, 0xF0, 0x0, 0x0, 0xFF, 0xF, 
        0xFF, 0xFF, 0xF, 0xF0, 0x0, 0x0, 0xFF, 0xF0, 0xFF, 0xF0, 
        0xFF, 0xF0, 0x0, 0x0, 0xFF, 0xFF, 0xF, 0xF, 0xFF, 0xF0, 0x0,
        0x0, 0xFF, 0xFF, 0xF, 0xF, 0xFF, 0xF0, 0x0, 0x0, 0xFF, 0xFF,
        0xF, 0xF, 0xFF, 0xF0, 0x0, 0x0, 0xFF, 0xF0, 0xFF, 0xF0, 
        0xFF, 0xF0, 0x0, 0x0, 0xFF, 0xF, 0xFF, 0xFF, 0xF, 0xF0, 0x0,
        0x0, 0xF0, 0xFF, 0xFF, 0xFF, 0xF0, 0xF0, 0x0, 0x0, 0xFF, 
        0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x0, 0x0};

    private byte[] blankImage = new byte[] {
        0x42, 0x4D, 0xC6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x76, 
        0x0, 0x0, 0x0, 0x28, 0x0, 0x0, 0x0, 0xB, 0x0, 0x0, 0x0, 0xA,
        0x0, 0x0, 0x0, 0x1, 0x0, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x50,
        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10,
        0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
        0x0, 0x80, 0x0, 0x0, 0x80, 0x0, 0x0, 0x0, 0x80, 0x80, 0x0, 
        0x80, 0x0, 0x0, 0x0, 0x80, 0x0, 0x80, 0x0, 0x80, 0x80, 0x0, 
        0x0, 0xC0, 0xC0, 0xC0, 0x0, 0x80, 0x80, 0x80, 0x0, 0x0, 0x0,
        0xFF, 0x0, 0x0, 0xFF, 0x0, 0x0, 0x0, 0xFF, 0xFF, 0x0, 0xFF, 
        0x0, 0x0, 0x0, 0xFF, 0x0, 0xFF, 0x0, 0xFF, 0xFF, 0x0, 0x0, 
        0xFF, 0xFF, 0xFF, 0x0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 
        0x0, 0x0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x0, 0x0, 
        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x0, 0x0, 0xFF, 0xFF, 
        0xFF, 0xFF, 0xFF, 0xF0, 0x0, 0x0, 0xFF, 0xFF, 0xFF, 0xFF, 
        0xFF, 0xF0, 0x0, 0x0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 
        0x0, 0x0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x0, 0x0, 
        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x0, 0x0, 0xFF, 0xFF, 
        0xFF, 0xFF, 0xFF, 0xF0, 0x0, 0x0, 0xFF, 0xFF, 0xFF, 0xFF, 
        0xFF, 0xF0, 0x0, 0x0};
    #endregion

    private Bitmap blank;
    private Bitmap x;
    private Bitmap o;
    private string xString = "X's turn";
    private string oString = "O's turn";
    private string gameOverString = "Game Over";
    private int bitmapPadding = 6;

    private void InitializeDataGridView(object sender,
        EventArgs e)
    {
        this.Panel1.SuspendLayout();
        this.SuspendLayout();

        ConfigureForm();
        SizeGrid();
        CreateColumns();
        CreateRows();

        this.Panel1.ResumeLayout(false);
        this.ResumeLayout(false);
    }

    private void ConfigureForm()
    {
        AutoSize = true;
        turn.Size = new System.Drawing.Size(75, 34);
        turn.TextAlign = ContentAlignment.MiddleLeft;
        turn.Text = xString;

        Panel1.Location = new System.Drawing.Point(0, 8);
        Panel1.Size = new System.Drawing.Size(120, 196);
        Panel1.FlowDirection = FlowDirection.TopDown;

        ClientSize = new System.Drawing.Size(355, 200);
        Controls.Add(this.Panel1);
        Text = "TicTacToe";

        dataGridView1 = new System.Windows.Forms.DataGridView();
        dataGridView1.Location = new Point(120, 0);
        dataGridView1.AllowUserToAddRows = false;
        dataGridView1.CellClick += new
            DataGridViewCellEventHandler(dataGridView1_CellClick);
        dataGridView1.CellMouseEnter += new
            DataGridViewCellEventHandler(dataGridView1_CellMouseEnter);
        dataGridView1.CellMouseLeave += new
            DataGridViewCellEventHandler(dataGridView1_CellMouseLeave);

        Controls.Add(dataGridView1);
    }

    private void SetupButtons()
    {
        Button1.AutoSize = true;
        SetupButton(Button1, "Restart", new EventHandler(Reset));
        Panel1.Controls.Add(turn);
        SetupButton(Button2, "Increase Cell Size", new EventHandler(MakeCellsLarger));
        SetupButton(Button3, "Stretch Images", new EventHandler(Stretch));
        SetupButton(Button4, "Zoom Images", new EventHandler(ZoomToImage));
        SetupButton(Button5, "Normal Images", new EventHandler(NormalImage));
    }

    private void SetupButton(Button button, string buttonLabel, EventHandler handler)
    {
        Panel1.Controls.Add(button);
        button.Text = buttonLabel;
        button.AutoSize = true;
        button.Click += handler;
    }

    private void CreateColumns()
    {
        DataGridViewImageColumn imageColumn;
        int columnCount = 0;
        do
        {
            Bitmap unMarked = blank;
            imageColumn = new DataGridViewImageColumn();

            //Add twice the padding for the left and 
            //right sides of the cell.
            imageColumn.Width = x.Width + 2 * bitmapPadding + 1;

            imageColumn.Image = unMarked;
            dataGridView1.Columns.Add(imageColumn);
            columnCount = columnCount + 1;
        }
        while (columnCount < 3);
    }

    private void CreateRows()
    {
        dataGridView1.Rows.Add();
        dataGridView1.Rows.Add();
        dataGridView1.Rows.Add();
    }

    private void SizeGrid()
    {
        dataGridView1.ColumnHeadersVisible = false;
        dataGridView1.RowHeadersVisible = false;
        dataGridView1.AllowUserToResizeColumns = false;;
        dataGridView1.AllowUserToResizeRows = false;
        dataGridView1.BorderStyle = BorderStyle.None;

        //Add twice the padding for the top of the cell 
        //and the bottom.
        dataGridView1.RowTemplate.Height = x.Height +
            2 * bitmapPadding + 1;

        dataGridView1.AutoSize = true;
    }

    private void Reset(object sender, System.EventArgs e)
    {
        dataGridView1.Dispose();
        InitializeDataGridView(null, null);
    }

    private void dataGridView1_CellClick(object sender,
        DataGridViewCellEventArgs e)
    {

        if (turn.Text.Equals(gameOverString)) { return; }

        DataGridViewImageCell cell = (DataGridViewImageCell)
            dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex];

        if (cell.Value == blank)
        {
            if (IsOsTurn())
            {
                cell.Value = o;
            }
            else
            {
                cell.Value = x;
            }
            ToggleTurn();
        }
        if (IsAWin())
        {
            turn.Text = gameOverString;
        }
    }

    private void dataGridView1_CellMouseEnter(object sender,
        DataGridViewCellEventArgs e)
    {
        Bitmap markingUnderMouse = (Bitmap)dataGridView1.
               Rows[e.RowIndex].
               Cells[e.ColumnIndex].Value;

        if (markingUnderMouse == blank)
        {
            dataGridView1.Cursor = Cursors.Default;
        }
        else if (markingUnderMouse == o || markingUnderMouse == x)
        {
            dataGridView1.Cursor = Cursors.No;
            ToolTip(e, true);
        }
    }

    private void ToolTip(DataGridViewCellEventArgs e, bool showTip)
    {
        DataGridViewImageCell cell = (DataGridViewImageCell)
            dataGridView1
            .Rows[e.RowIndex].Cells[e.ColumnIndex];
        DataGridViewImageColumn imageColumn =
            (DataGridViewImageColumn)
            dataGridView1.Columns[cell.ColumnIndex];

        if (showTip)
        {
            cell.ToolTipText = imageColumn.Description;
        }
        else { cell.ToolTipText = String.Empty; }
    }

    private void dataGridView1_CellMouseLeave(object sender,
        DataGridViewCellEventArgs e)
    {
        ToolTip(e, false);
        dataGridView1.Cursor = Cursors.Default;
    }

    private void Stretch(object sender, EventArgs e)
    {
        foreach (DataGridViewImageColumn column in
            dataGridView1.Columns)
        {
            column.ImageLayout = DataGridViewImageCellLayout.Stretch;
            column.Description = "Stretched";
        }
    }

    private void ZoomToImage(object sender, EventArgs e)
    {

        foreach (DataGridViewImageColumn column in
            dataGridView1.Columns)
        {
            column.ImageLayout = DataGridViewImageCellLayout.Zoom;
            column.Description = "Zoomed";
        }
    }

    private void NormalImage(object sender, EventArgs e)
    {

        foreach (DataGridViewImageColumn column in
            dataGridView1.Columns)
        {
            column.ImageLayout = DataGridViewImageCellLayout.Normal;
            column.Description = "Normal";
        }
    }

    private void MakeCellsLarger(object sender, EventArgs e)
    {
        foreach (DataGridViewImageColumn column in
            dataGridView1.Columns)
        {
            column.Width = column.Width * 2;
        }
        foreach (DataGridViewRow row in dataGridView1.Rows)
        {
            if (row.IsNewRow) break;
            row.Height = (int)(row.Height * 1.5);
        }
    }

    private bool IsAWin()
    {
        if (ARowIsSame() || AColumnIsSame() || ADiagonalIsSame())
            return true;
        else return false;
    }

    private bool ARowIsSame()
    {
        Bitmap marking = null;

        foreach (DataGridViewRow row in dataGridView1.Rows)
        {
            if (row.IsNewRow) break;
            marking = (Bitmap)row.Cells[0].Value;
            if (marking != blank)
            {
                if (marking == row.Cells[1].Value &&
                    marking == row.Cells[2].Value) return true;
            }
        }
        return false;
    }

    private bool AColumnIsSame()
    {
        int columnIndex = 0;
        Bitmap marking;
        do
        {
            marking = (Bitmap)
                dataGridView1.Rows[0].Cells[columnIndex].Value;
            if (marking != blank)
            {
                if (marking == (Bitmap)dataGridView1.Rows[1]
                    .Cells[columnIndex].Value
                    && marking == (Bitmap)dataGridView1.Rows[2].
                    Cells[columnIndex].Value) return true;
            }
            columnIndex = columnIndex + 1;
        }
        while (columnIndex < dataGridView1.Columns.GetColumnCount(
            DataGridViewElementStates.Visible));
        return false;
    }

    private bool ADiagonalIsSame()
    {
        if (LeftToRightDiagonalIsSame()) { return true; }
        if (RightToLeftDiagonalIsSame()) { return true; }
        return false;
    }

    private bool LeftToRightDiagonalIsSame()
    {
        return IsDiagonalSame(0, 2);
    }

    private bool RightToLeftDiagonalIsSame()
    {
        return IsDiagonalSame(2, 0);
    }

    private bool IsDiagonalSame(int startingColumn, int lastColumn)
    {
        Bitmap marking = (Bitmap)dataGridView1.Rows[0]
            .Cells[startingColumn].Value;

        if (marking == blank) return false;
        if (marking == dataGridView1.Rows[1].Cells[1]
            .Value && marking == dataGridView1.Rows[2]
            .Cells[lastColumn].Value) return true;

        return false;
    }

    private void ToggleTurn()
    {
        if (turn.Text.Equals(xString)) { turn.Text = oString; }
        else { turn.Text = xString; }
    }

    private bool IsOsTurn()
    {
        if (turn.Text.Equals(oString)) return true;
        return false;
    }

    [STAThread]
    public static void Main()
    {
        Application.Run(new TicTacToe());
    }
}
Imports System.IO
Imports System.Windows.Forms
Imports System.Drawing
Public Class TicTacToe
    Inherits System.Windows.Forms.Form

    Friend WithEvents dataGridView1 As DataGridView
    Friend WithEvents Button1 As Button = New Button()
    Friend WithEvents turn As Label = New Label()
    Friend WithEvents Button2 As Button = New Button()
    Friend WithEvents Button3 As Button = New Button()
    Friend WithEvents Button4 As Button = New Button()
    Friend WithEvents Button5 As Button = New Button()
    Friend WithEvents Panel1 As FlowLayoutPanel = New FlowLayoutPanel()

#Region "bitmaps"
    Private oImage As Byte() = { _
        &H42, &H4D, &HC6, &H0, &H0, &H0, &H0, &H0, _
        &H0, &H0, &H76, &H0, &H0, &H0, &H28, &H0, _
        &H0, &H0, &HB, &H0, &H0, &H0, &HA, &H0, _
        &H0, &H0, &H1, &H0, &H4, &H0, &H0, &H0, _
        &H0, &H0, &H50, &H0, &H0, &H0, &H0, &H0, _
        &H0, &H0, &H0, &H0, &H0, &H0, &H10, &H0, _
        &H0, &H0, &H10, &H0, &H0, &H0, &H0, &H0, _
        &H0, &H0, &H0, &H0, &H80, &H0, &H0, &H80, _
        &H0, &H0, &H0, &H80, &H80, &H0, &H80, &H0, _
        &H0, &H0, &H80, &H0, &H80, &H0, &H80, &H80, _
        &H0, &H0, &HC0, &HC0, &HC0, &H0, &H80, &H80, _
        &H80, &H0, &H0, &H0, &HFF, &H0, &H0, &HFF, _
        &H0, &H0, &H0, &HFF, &HFF, &H0, &HFF, &H0, _
        &H0, &H0, &HFF, &H0, &HFF, &H0, &HFF, &HFF, _
        &H0, &H0, &HFF, &HFF, &HFF, &H0, &HFF, &HFF, _
        &H0, &HF, &HFF, &HF0, &H0, &H0, &HFF, &H0, _
        &HFF, &HF0, &HF, &HF0, &H0, &H0, &HF0, &HFF, _
        &HFF, &HFF, &HF0, &HF0, &H0, &H0, &HF0, &HFF, _
        &HFF, &HFF, &HF0, &HF0, &H0, &H0, &HF, &HFF, _
        &HFF, &HFF, &HFF, &H0, &H0, &H0, &HF, &HFF, _
        &HFF, &HFF, &HFF, &H0, &H0, &H0, &HF0, &HFF, _
        &HFF, &HFF, &HF0, &HF0, &H0, &H0, &HF0, &HFF, _
        &HFF, &HFF, &HF0, &HF0, &H0, &H0, &HFF, &H0, _
        &HFF, &HF0, &HF, &HF0, &H0, &H0, &HFF, &HFF, _
        &H0, &HF, &HFF, &HF0, &H0, &H0}

    Private xImage As Byte() = { _
        &H42, &H4D, &HC6, &H0, &H0, &H0, &H0, &H0, _
        &H0, &H0, &H76, &H0, &H0, &H0, &H28, &H0, _
        &H0, &H0, &HB, &H0, &H0, &H0, &HA, &H0, _
        &H0, &H0, &H1, &H0, &H4, &H0, &H0, &H0, _
        &H0, &H0, &H50, &H0, &H0, &H0, &H0, &H0, _
        &H0, &H0, &H0, &H0, &H0, &H0, &H10, &H0, _
        &H0, &H0, &H10, &H0, &H0, &H0, &H0, &H0, _
        &H0, &H0, &H0, &H0, &H80, &H0, &H0, &H80, _
        &H0, &H0, &H0, &H80, &H80, &H0, &H80, &H0, _
        &H0, &H0, &H80, &H0, &H80, &H0, &H80, &H80, _
        &H0, &H0, &HC0, &HC0, &HC0, &H0, &H80, &H80, _
        &H80, &H0, &H0, &H0, &HFF, &H0, &H0, &HFF, _
        &H0, &H0, &H0, &HFF, &HFF, &H0, &HFF, &H0, _
        &H0, &H0, &HFF, &H0, &HFF, &H0, &HFF, &HFF, _
        &H0, &H0, &HFF, &HFF, &HFF, &H0, &HF0, &HFF, _
        &HFF, &HFF, &HF0, &HF0, &H0, &H0, &HFF, &HF, _
        &HFF, &HFF, &HF, &HF0, &H0, &H0, &HFF, &HF0, _
        &HFF, &HF0, &HFF, &HF0, &H0, &H0, &HFF, &HFF, _
        &HF, &HF, &HFF, &HF0, &H0, &H0, &HFF, &HFF, _
        &HF, &HF, &HFF, &HF0, &H0, &H0, &HFF, &HFF, _
        &HF, &HF, &HFF, &HF0, &H0, &H0, &HFF, &HF0, _
        &HFF, &HF0, &HFF, &HF0, &H0, &H0, &HFF, &HF, _
        &HFF, &HFF, &HF, &HF0, &H0, &H0, &HF0, &HFF, _
        &HFF, &HFF, &HF0, &HF0, &H0, &H0, &HFF, &HFF, _
        &HFF, &HFF, &HFF, &HF0, &H0, &H0}

    Private blankImage As Byte() = { _
        &H42, &H4D, &HC6, &H0, &H0, &H0, &H0, &H0, _
        &H0, &H0, &H76, &H0, &H0, &H0, &H28, &H0, _
        &H0, &H0, &HB, &H0, &H0, &H0, &HA, &H0, _
        &H0, &H0, &H1, &H0, &H4, &H0, &H0, &H0, _
        &H0, &H0, &H50, &H0, &H0, &H0, &H0, &H0, _
        &H0, &H0, &H0, &H0, &H0, &H0, &H10, &H0, _
        &H0, &H0, &H10, &H0, &H0, &H0, &H0, &H0, _
        &H0, &H0, &H0, &H0, &H80, &H0, &H0, &H80, _
        &H0, &H0, &H0, &H80, &H80, &H0, &H80, &H0, _
        &H0, &H0, &H80, &H0, &H80, &H0, &H80, &H80, _
        &H0, &H0, &HC0, &HC0, &HC0, &H0, &H80, &H80, _
        &H80, &H0, &H0, &H0, &HFF, &H0, &H0, &HFF, _
        &H0, &H0, &H0, &HFF, &HFF, &H0, &HFF, &H0, _
        &H0, &H0, &HFF, &H0, &HFF, &H0, &HFF, &HFF, _
        &H0, &H0, &HFF, &HFF, &HFF, &H0, &HFF, &HFF, _
        &HFF, &HFF, &HFF, &HF0, &H0, &H0, &HFF, &HFF, _
        &HFF, &HFF, &HFF, &HF0, &H0, &H0, &HFF, &HFF, _
        &HFF, &HFF, &HFF, &HF0, &H0, &H0, &HFF, &HFF, _
        &HFF, &HFF, &HFF, &HF0, &H0, &H0, &HFF, &HFF, _
        &HFF, &HFF, &HFF, &HF0, &H0, &H0, &HFF, &HFF, _
        &HFF, &HFF, &HFF, &HF0, &H0, &H0, &HFF, &HFF, _
        &HFF, &HFF, &HFF, &HF0, &H0, &H0, &HFF, &HFF, _
        &HFF, &HFF, &HFF, &HF0, &H0, &H0, &HFF, &HFF, _
        &HFF, &HFF, &HFF, &HF0, &H0, &H0, &HFF, &HFF, _
        &HFF, &HFF, &HFF, &HF0, &H0, &H0}
#End Region

    Private blank As Bitmap = New Bitmap( _
        New MemoryStream(blankImage))
    Private x As Bitmap = New Bitmap(New MemoryStream(xImage))
    Private o As Bitmap = New Bitmap(New MemoryStream(oImage))
    Private xString As String = "X's turn"
    Private oString As String = "O's turn"
    Private gameOverString As String = "Game Over"
    Private bitmapPadding As Integer = 6

    Private Sub InitializeDataGridView(ByVal sender As Object, _
        ByVal e As EventArgs) Handles Me.Load
        SuspendLayout()
        Panel1.SuspendLayout()

        ConfigureForm()
        SizeGrid()
        CreateColumns()
        CreateRows()

        ResumeLayout(False)
        Panel1.ResumeLayout(False)
    End Sub

    Private Sub ConfigureForm()
        AutoSize = True
        turn.Size = New System.Drawing.Size(75, 34)
        turn.TextAlign = ContentAlignment.MiddleLeft
        turn.Text = xString

        Panel1.FlowDirection = FlowDirection.TopDown
        Panel1.Location = New System.Drawing.Point(0, 8)
        Panel1.Size = New System.Drawing.Size(120, 196)

        ClientSize = New System.Drawing.Size(355, 200)
        Controls.Add(Me.Panel1)
        Text = "TicTacToe"

        dataGridView1 = New System.Windows.Forms.DataGridView
        dataGridView1.Location = New Point(120, 0)
        dataGridView1.AllowUserToAddRows = False
        Controls.Add(dataGridView1)
        SetupButtons()
    End Sub

    Private Sub SetupButtons()
        SetupButton(Button1, "Restart")
        Panel1.Controls.Add(Me.turn)
        SetupButton(Button2, "Increase Cell Size")
        SetupButton(Button3, "Stretch Images")
        SetupButton(Button4, "Zoom Images")
        SetupButton(Button5, "Normal Images")
    End Sub

    Private Sub SetupButton(ByVal button As Button, _
        ByVal buttonLabel As String)

        Panel1.Controls.Add(button)
        button.Text = buttonLabel
        button.AutoSize = True

    End Sub

    Private Sub CreateColumns()

        Dim imageColumn As DataGridViewImageColumn
        Dim columnCount As Integer = 0
        Do
            Dim unMarked As Bitmap = blank
            imageColumn = New DataGridViewImageColumn()

            ' Add twice the padding for the left and 
            ' right sides of the cell.
            imageColumn.Width = x.Width + 2 * bitmapPadding + 1

            imageColumn.Image = unMarked
            imageColumn.ImageLayout = DataGridViewImageCellLayout.NotSet
            imageColumn.Description = "default image layout"
            dataGridView1.Columns.Add(imageColumn)
            columnCount = columnCount + 1
        Loop While columnCount < 3
    End Sub

    Private Sub CreateRows()
        dataGridView1.Rows.Add()
        dataGridView1.Rows.Add()
        dataGridView1.Rows.Add()
    End Sub

    Private Sub SizeGrid()
        dataGridView1.ColumnHeadersVisible = False
        dataGridView1.RowHeadersVisible = False
        dataGridView1.AllowUserToResizeColumns = False
        dataGridView1.AllowUserToResizeRows = False
        dataGridView1.BorderStyle = BorderStyle.None

        ' Add twice the padding for the top and bottom of the cell. 
        dataGridView1.RowTemplate.Height = x.Height + _
            2 * bitmapPadding + 1

        dataGridView1.AutoSize = True
    End Sub

    Private Sub reset(ByVal sender As Object, _
        ByVal e As EventArgs) _
        Handles Button1.Click

        dataGridView1.Dispose()
        InitializeDataGridView(Nothing, Nothing)
    End Sub

    Private Sub dataGridView1_CellClick(ByVal sender As Object, _
        ByVal e As DataGridViewCellEventArgs) _
        Handles dataGridView1.CellClick

        If turn.Text.Equals(gameOverString) Then Return

        Dim cell As DataGridViewImageCell = _
            CType(dataGridView1.Rows(e.RowIndex). _
                Cells(e.ColumnIndex), DataGridViewImageCell)
        If (cell.Value Is blank) Then
            If IsOsTurn() Then
                cell.Value = o
            Else
                cell.Value = x
            End If
            ToggleTurn()
            ToolTip(e)
        End If
        If IsAWin() Then
            turn.Text = gameOverString
        End If
    End Sub

    Private Sub dataGridView1_CellMouseEnter(ByVal sender As Object, _
        ByVal e As DataGridViewCellEventArgs) _
        Handles dataGridView1.CellMouseEnter

        Dim markingUnderMouse As Bitmap = _
            CType(dataGridView1.Rows(e.RowIndex). _
                Cells(e.ColumnIndex).Value, Bitmap)

        If markingUnderMouse Is blank Then
            dataGridView1.Cursor = Cursors.Default
        ElseIf markingUnderMouse Is o OrElse markingUnderMouse Is x Then
            dataGridView1.Cursor = Cursors.No
            ToolTip(e)
        End If
    End Sub

    Private Sub ToolTip( _
        ByVal e As DataGridViewCellEventArgs)

        Dim cell As DataGridViewImageCell = _
            CType(dataGridView1.Rows(e.RowIndex). _
            Cells(e.ColumnIndex), DataGridViewImageCell)
        Dim imageColumn As DataGridViewImageColumn = _
            CType(dataGridView1.Columns(cell.ColumnIndex), _
            DataGridViewImageColumn)

        cell.ToolTipText = imageColumn.Description
    End Sub

    Private Sub dataGridView1_CellMouseLeave(ByVal sender As Object, _
        ByVal e As DataGridViewCellEventArgs) _
        Handles dataGridView1.CellMouseLeave

        dataGridView1.Cursor = Cursors.Default
    End Sub

    Private Sub Stretch(ByVal sender As Object, _
        ByVal e As EventArgs) Handles Button3.Click

        For Each column As DataGridViewImageColumn _
            In dataGridView1.Columns
            column.ImageLayout = DataGridViewImageCellLayout.Stretch
            column.Description = "Stretched image layout"
        Next
    End Sub

    Private Sub ZoomToImage(ByVal sender As Object, _
        ByVal e As EventArgs) Handles Button4.Click

        For Each column As DataGridViewImageColumn _
            In dataGridView1.Columns
            column.ImageLayout = DataGridViewImageCellLayout.Zoom
            column.Description = "Zoomed image layout"
        Next
    End Sub

    Private Sub NormalImage(ByVal sender As Object, _
        ByVal e As EventArgs) Handles Button5.Click

        For Each column As DataGridViewImageColumn _
            In dataGridView1.Columns
            column.ImageLayout = DataGridViewImageCellLayout.Normal
            column.Description = "Normal image layout"
        Next
    End Sub

    Private Sub MakeCellsLarger(ByVal sender As Object, _
        ByVal e As EventArgs) Handles Button2.Click

        For Each column As DataGridViewImageColumn _
            In dataGridView1.Columns
            column.Width = column.Width * 2
        Next
        For Each row As DataGridViewRow In dataGridView1.Rows
            If row.IsNewRow Then Continue For
            row.Height = CInt(row.Height * 1.5)
        Next
    End Sub

    Private Function IsAWin() As Boolean
        If ARowIsSame() OrElse AColumnIsSame() OrElse ADiagonalIsSame() Then
            Return True
        Else 
            Return False
        End If
    End Function

    Private Function ARowIsSame() As Boolean
        Dim marking As Bitmap = Nothing
        If marking Is blank Then Return False
        For Each row As DataGridViewRow In dataGridView1.Rows
            If row.IsNewRow Then Continue For
            marking = CType(row.Cells(0).Value, Bitmap)
            If marking IsNot blank Then
                If marking Is row.Cells(1).Value AndAlso _
                    marking Is row.Cells(2).Value Then Return True
            End If
        Next
        Return False
    End Function

    Private Function AColumnIsSame() As Boolean

        Dim columnIndex As Integer = 0
        Dim marking As Bitmap
        Do
            marking = CType(dataGridView1.Rows(0).Cells(columnIndex).Value, _
                Bitmap)
            If marking IsNot blank Then
                If marking Is _
                    dataGridView1.Rows(1).Cells(columnIndex).Value _
                    AndAlso marking Is _
                    dataGridView1.Rows(2).Cells(columnIndex).Value _
                    Then Return True
            End If
            columnIndex = columnIndex + 1
        Loop While columnIndex < _
            dataGridView1.Columns.GetColumnCount( _
            DataGridViewElementStates.Visible)
        Return False
    End Function

    Private Function ADiagonalIsSame() As Boolean

        If LeftToRightDiagonalIsSame() Then Return True
        If RightToLeftDiagonalIsSame() Then Return True
        Return False
    End Function

    Private Function LeftToRightDiagonalIsSame() As Boolean
        Return IsDiagonalSame(0, 2)
    End Function

    Private Function RightToLeftDiagonalIsSame() As Boolean
        Return IsDiagonalSame(2, 0)
    End Function

    Private Function IsDiagonalSame(ByVal startingColumn As Integer, _
        ByVal lastColumn As Integer) As Boolean

        Dim marking As Bitmap = CType( _
            dataGridView1.Rows(0).Cells(startingColumn).Value, Bitmap)
        If marking Is blank Then Return False
        If marking Is dataGridView1.Rows(1).Cells(1).Value AndAlso _
            marking Is dataGridView1.Rows(2).Cells(lastColumn).Value _
            Then Return True
    End Function

    Private Sub ToggleTurn()
        If turn.Text.Equals(xString) Then turn.Text = oString _
        Else turn.Text = xString
    End Sub

    Private Function IsOsTurn() As Boolean
        If turn.Text.Equals(oString) Then Return True _
        Else  : Return False
    End Function

    <STAThread> Public Shared Sub Main()
        Application.Run(New TicTacToe())
    End Sub

End Class

Remarks

The DataGridViewImageColumn class is a specialized type of the DataGridViewColumn class used to logically host cells that display images. A DataGridViewImageColumn has an associated DataGridViewImageCell in every DataGridViewRow that intersects it. Each cell is capable of containing an Image or an Icon, depending on the value of the DataGridViewImageCell.ValueIsIcon property. Displaying icons is useful to accommodate images with transparency.

By default, empty cells display a default error graphic. To prevent this graphic from appearing for cell values equal to null or DBNull.Value, set the DataGridViewCellStyle.NullValue property of the cell style object returned by the DefaultCellStyle property to null before adding rows to the control. This does not affect the row for new records, however. To prevent the error graphic from appearing in the row for new records when the control AllowUserToAddRows property value is true, you must also either explicitly set the cell value to null in a handler for the control RowsAdded event or set the column CellTemplate property to an instance of a DataGridViewImageCell-derived type with an overridden DefaultNewRowValue property that returns null.

The default sort mode for this column type is NotSortable.

Notes to Inheritors

When you derive from DataGridViewImageColumn and add new properties to the derived class, be sure to override the Clone() method to copy the new properties during cloning operations. You should also call the base class's Clone() method so that the properties of the base class are copied to the new cell.

Constructors

DataGridViewImageColumn()

Initializes a new instance of the DataGridViewImageColumn class, configuring it for use with cell values of type Image.

DataGridViewImageColumn(Boolean)

Initializes a new instance of the DataGridViewImageColumn class, optionally configuring it for use with Icon cell values.

Properties

AutoSizeMode

Gets or sets the mode by which the column automatically adjusts its width.

(Inherited from DataGridViewColumn)
CellTemplate

Gets or sets the template used to create new cells.

CellType

Gets the run-time type of the cell template.

(Inherited from DataGridViewColumn)
ContextMenuStrip

Gets or sets the shortcut menu for the column.

(Inherited from DataGridViewColumn)
DataGridView

Gets the DataGridView control associated with this element.

(Inherited from DataGridViewElement)
DataPropertyName

Gets or sets the name of the data source property or database column to which the DataGridViewColumn is bound.

(Inherited from DataGridViewColumn)
DefaultCellStyle

Gets or sets the column's default cell style.

DefaultHeaderCellType

Gets or sets the run-time type of the default header cell.

(Inherited from DataGridViewBand)
Description

Gets or sets a string that describes the column's image.

Displayed

Gets a value indicating whether the band is currently displayed onscreen.

(Inherited from DataGridViewBand)
DisplayIndex

Gets or sets the display order of the column relative to the currently displayed columns.

(Inherited from DataGridViewColumn)
DividerWidth

Gets or sets the width, in pixels, of the column divider.

(Inherited from DataGridViewColumn)
FillWeight

Gets or sets a value that represents the width of the column when it is in fill mode relative to the widths of other fill-mode columns in the control.

(Inherited from DataGridViewColumn)
Frozen

Gets or sets a value indicating whether a column will move when a user scrolls the DataGridView control horizontally.

(Inherited from DataGridViewColumn)
HasDefaultCellStyle

Gets a value indicating whether the DefaultCellStyle property has been set.

(Inherited from DataGridViewBand)
HeaderCell

Gets or sets the DataGridViewColumnHeaderCell that represents the column header.

(Inherited from DataGridViewColumn)
HeaderCellCore

Gets or sets the header cell of the DataGridViewBand.

(Inherited from DataGridViewBand)
HeaderText

Gets or sets the caption text on the column's header cell.

(Inherited from DataGridViewColumn)
Icon

Gets or sets the icon displayed in the cells of this column when the cell's Value property is not set and the cell's ValueIsIcon property is set to true.

Image

Gets or sets the image displayed in the cells of this column when the cell's Value property is not set and the cell's ValueIsIcon property is set to false.

ImageLayout

Gets or sets the image layout in the cells for this column.

Index

Gets the relative position of the band within the DataGridView control.

(Inherited from DataGridViewBand)
InheritedAutoSizeMode

Gets the sizing mode in effect for the column.

(Inherited from DataGridViewColumn)
InheritedStyle

Gets the cell style currently applied to the column.

(Inherited from DataGridViewColumn)
IsDataBound

Gets a value indicating whether the column is bound to a data source.

(Inherited from DataGridViewColumn)
IsRow

Gets a value indicating whether the band represents a row.

(Inherited from DataGridViewBand)
MinimumWidth

Gets or sets the minimum width, in pixels, of the column.

(Inherited from DataGridViewColumn)
Name

Gets or sets the name of the column.

(Inherited from DataGridViewColumn)
ReadOnly

Gets or sets a value indicating whether the user can edit the column's cells.

(Inherited from DataGridViewColumn)
Resizable

Gets or sets a value indicating whether the column is resizable.

(Inherited from DataGridViewColumn)
Selected

Gets or sets a value indicating whether the band is in a selected user interface (UI) state.

(Inherited from DataGridViewBand)
Site

Gets or sets the site of the column.

(Inherited from DataGridViewColumn)
SortMode

Gets or sets the sort mode for the column.

(Inherited from DataGridViewColumn)
State

Gets the user interface (UI) state of the element.

(Inherited from DataGridViewElement)
Tag

Gets or sets the object that contains data to associate with the band.

(Inherited from DataGridViewBand)
ToolTipText

Gets or sets the text used for ToolTips.

(Inherited from DataGridViewColumn)
ValuesAreIcons

Gets or sets a value indicating whether cells in this column display Icon values.

ValueType

Gets or sets the data type of the values in the column's cells.

(Inherited from DataGridViewColumn)
Visible

Gets or sets a value indicating whether the column is visible.

(Inherited from DataGridViewColumn)
Width

Gets or sets the current width of the column.

(Inherited from DataGridViewColumn)

Methods

Clone()

Creates an exact copy of this column.

Dispose()

Releases all resources used by the DataGridViewBand.

(Inherited from DataGridViewBand)
Dispose(Boolean)

Releases the unmanaged resources used by the DataGridViewBand and optionally releases the managed resources.

(Inherited from DataGridViewColumn)
Equals(Object)

Determines whether the specified object is equal to the current object.

(Inherited from Object)
GetHashCode()

Serves as the default hash function.

(Inherited from Object)
GetPreferredWidth(DataGridViewAutoSizeColumnMode, Boolean)

Calculates the ideal width of the column based on the specified criteria.

(Inherited from DataGridViewColumn)
GetType()

Gets the Type of the current instance.

(Inherited from Object)
MemberwiseClone()

Creates a shallow copy of the current Object.

(Inherited from Object)
OnDataGridViewChanged()

Called when the band is associated with a different DataGridView.

(Inherited from DataGridViewBand)
RaiseCellClick(DataGridViewCellEventArgs)

Raises the CellClick event.

(Inherited from DataGridViewElement)
RaiseCellContentClick(DataGridViewCellEventArgs)

Raises the CellContentClick event.

(Inherited from DataGridViewElement)
RaiseCellContentDoubleClick(DataGridViewCellEventArgs)

Raises the CellContentDoubleClick event.

(Inherited from DataGridViewElement)
RaiseCellValueChanged(DataGridViewCellEventArgs)

Raises the CellValueChanged event.

(Inherited from DataGridViewElement)
RaiseDataError(DataGridViewDataErrorEventArgs)

Raises the DataError event.

(Inherited from DataGridViewElement)
RaiseMouseWheel(MouseEventArgs)

Raises the MouseWheel event.

(Inherited from DataGridViewElement)
ToString()

Gets a string that describes the column.

Events

Disposed

Occurs when the DataGridViewColumn is disposed.

(Inherited from DataGridViewColumn)

Applies to

See also