C++, RAD STUDIO IDE.
Сделай так, чтобы длина строки в TDBGrid автоматически подгонялась под размер текста.

Код:

``` cpp
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop
#include <stdio.h>
#include <string.h>
#include <windows.h>
#include "Unit108.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm108 *Form108;
TADOConnection *ADOConnection1;
TADOQuery *ADOQuery1;
TDBGrid *DBGrid1;
TDataSource *DataSource1;

//---------------------------------------------------------------------------
__fastcall TForm108::TForm108(TComponent* Owner)
	: TForm(Owner)
{

}
//---------------------------------------------------------------------------

void __fastcall TForm108::FormCreate(TObject *Sender)
{
	// создание базы данных / таблицы, если их ещё не существует
	String s;
	s = "CREATE DATABASE IF NOT EXISTS `catalog`";
	ADOQuery1->SQL->Text = s;
	ADOQuery1->ExecSQL();
	s = "CREATE TABLE IF NOT EXISTS `catalog`.`products` (`ID` INT NOT NULL AUTO_INCREMENT, `name` VARCHAR(255) CHARACTER SET utf8mb4 NOT NULL, `price` FLOAT(8, 2) NOT NULL, `description` TEXT CHARACTER SET utf8mb4 NOT NULL, `image` LONGBLOB NOT NULL, PRIMARY KEY (`ID`))";
	ADOQuery1->SQL->Text = s;
	ADOQuery1->ExecSQL();

	ADOQuery1->Close();
    ADOQuery1->SQL->Text = "SELECT * FROM `catalog`.`products`";
	ADOQuery1->Open();
}
//---------------------------------------------------------------------------

void __fastcall TForm108::Button2Click(TObject *Sender)
{
	if (Edit1->Text.IsEmpty() || Edit2->Text.IsEmpty() || Memo1->Lines->Text.IsEmpty())
	{
		ShowMessage("Пожалуйста, заполните все поля!");
        return;
	}

    if (OpenPictureDialog1->FileName.IsEmpty())
    {
		ShowMessage("Пожалуйста, загрузите изображение!");
        return;
    }
try
{
	TFileStream *fs = new TFileStream(OpenPictureDialog1->FileName, fmOpenRead);
    try
    {
        // Указываем параметры для запроса
		ADOQuery1->SQL->Text = "INSERT INTO `catalog`.`products` (`name`, `price`, `description`, `image`) VALUES (:name, :price, :description, :image)";
        ADOQuery1->Parameters->ParamByName("name")->Value = Edit1->Text;
		ADOQuery1->Parameters->ParamByName("price")->Value = StrToFloat(Edit2->Text);
		ADOQuery1->Parameters->ParamByName("description")->Value = Memo1->Lines->Text;
		ADOQuery1->Parameters->ParamByName("name")->DataType = ftWideString;      //
		ADOQuery1->Parameters->ParamByName("description")->DataType = ftWideString; //

        // Создаем поток для передачи изображения в базу данных
		TMemoryStream *stream = new TMemoryStream();
        try
		{
			stream->CopyFrom(fs, 0);
            stream->Position = 0;
            ADOQuery1->Parameters->ParamByName("image")->LoadFromStream(stream, ftBlob);

			ADOQuery1->ExecSQL();
		}
        __finally
        {
            delete stream;
        }
    }
	__finally
	{
		delete fs;
	}

    // Очистка полей ввода
    Edit1->Text="К";
	Edit2->Text="0";
	Memo1->Lines->Text="Описание";

    // Очистка изображения
    Image1->Picture->Assign(NULL);

	// Обновление данных в таблице
    ADOQuery1->Close();
    ADOQuery1->SQL->Text = "SELECT * FROM `catalog`.`products`";
	ADOQuery1->Open();
}
catch (Exception &e)
{
    ShowMessage("Ошибка при добавлении товара: " + e.Message);
}
}
//---------------------------------------------------------------------------

void __fastcall TForm108::Button3Click(TObject *Sender)
{
	if (OpenPictureDialog1->Execute())
	{
		Image1->Picture->LoadFromFile(OpenPictureDialog1->FileName);
	}
}
//---------------------------------------------------------------------------

void __fastcall TForm108::Button1Click(TObject *Sender)
{
    int id = ADOQuery1->FieldByName("ID")->AsInteger;
    if (OpenPictureDialog1->Execute())
    {
        TFileStream *fs = new TFileStream(OpenPictureDialog1->FileName, fmOpenRead);
        TMemoryStream *stream = new TMemoryStream();
        try
        {
            fs->Position = 0; // сброс позиции в потоке
            stream->CopyFrom(fs, 0); // скопировать содержимое потока fs в stream
            stream->Position = 0;

            ADOQuery1->SQL->Text = "UPDATE `catalog`.`products` SET `image` = :image WHERE `ID` = :ID";
            ADOQuery1->Parameters->ParamByName("ID")->Value = id;
            ADOQuery1->Parameters->ParamByName("image")->LoadFromStream(stream, ftBlob);
            ADOQuery1->ExecSQL();
        }
        __finally
        {
            if (stream != NULL) {
                delete stream;
            }
            if (fs != NULL) {
                delete fs;
            }
        }
        ADOQuery1->Close();
        ADOQuery1->SQL->Text = "SELECT * FROM `catalog`.`products`";
        ADOQuery1->Open();

        Image1->Picture->Assign(NULL);
    }
}
//---------------------------------------------------------------------------
void __fastcall TForm108::Edit2KeyPress(TObject *Sender, System::WideChar &Key)
{
    String dict="0123456789,";

	if (dict.Pos(Key)>0)
	{
		Key=Key;
	}

	else if (Key==8)
	{
		Key=8;
	}

	else
	{
		Key=0;
	}
}
//---------------------------------------------------------------------------
void __fastcall TForm108::Edit1Click(TObject *Sender)
{
    // Выделяем весь текст в поле
    TEdit* ed = dynamic_cast<TEdit*>(Sender); // приводим Sender к типу TEdit
    if (ed != NULL) {
        ed->SelectAll();
    }
}
//---------------------------------------------------------------------------
void __fastcall TForm108::Edit2Click(TObject *Sender)
{
    // Выделяем весь текст в поле
    TEdit* ed = dynamic_cast<TEdit*>(Sender); // приводим Sender к типу TEdit
    if (ed != NULL) {
        ed->SelectAll();
    }
}
//---------------------------------------------------------------------------
void __fastcall TForm108::Memo1Click(TObject *Sender)
{
    // Выделяем весь текст в поле
    TMemo* memo = dynamic_cast<TMemo*>(Sender); // приводим Sender к типу TMemo
    if (memo != NULL) {
        memo->SelectAll();
    }
}
//---------------------------------------------------------------------------

void __fastcall TForm108::Button4Click(TObject *Sender)
{
    // Получаем номер выделенной строки
    int row = DBGrid1->DataSource->DataSet->RecNo;

    // Переходим к соответствующей строке в ADOQuery
	ADOQuery1->First(); // переходим к первой строке
	for (int i = 1; i < row; i++) {  // идем по каждой строке до нужной
		ADOQuery1->Next();
    }

	// Получаем значение поля ID текущей строки
    int id = ADOQuery1->FieldByName("ID")->AsInteger;

    // Показываем диалоговое окно и ждем подтверждения
    int dialog_answer = MessageDlg("Вы действительно хотите удалить товар?", mtConfirmation, TMsgDlgButtons() << mbYes << mbNo, 0);

	// Если пользователь подтвердил удаление, то выполняем удаление товара
	if (dialog_answer == mrYes) {

        // Выполняем SQL-запрос на удаление товара
        ADOQuery1->SQL->Text = "DELETE from `catalog`.`products` WHERE `ID` = :ID";
        ADOQuery1->Parameters->ParamByName("ID")->Value = id;
        ADOQuery1->ExecSQL();

        // Обновляем данные в TDBGrid
        ADOQuery1->Close();
        ADOQuery1->SQL->Text = "SELECT * FROM `catalog`.`products`";
        ADOQuery1->Open();

    }
    // Если пользователь не подтвердил удаление, то ничего не делаем
    else if (dialog_answer == mrNo) {
        return;
    }
}
//---------------------------------------------------------------------------
``` cpp