Jak vymalovat obrázek do řádku bez použití ikony vlastní cestou

⚠️ Pozor: obrázky z tohoto příspěvku se ztratily při výpadku v roce 2016. Chybějící obrázky nahradí automaticky vtipným placeholderem plugin Broken Image Placeholder.

Opět jsem nad tím strávil pár hodin různým zkoušením a tak bych se s vámi chtěl podělit o způsob, který mi funguje. Jako vždy je to tak jednoduché když už člověk ví jak na to, praktičtější ale určitě více než tyto moje slova bude těch pár řádků kódu:
Prvně musíme vytvořit buňku:

C#
class DataGridViewFavoriteCell : DataGridViewImageCell
{
    public DataGridViewFavoriteCell()
    {
        //-Nastavím výchozí typ, který bude vracet metoda GetFormattedValue
        ValueType = typeof(Bitmap);
    }
    protected override object GetFormattedValue(object value, int rowIndex, ref DataGridViewCellStyle cellStyle, System.ComponentModel.TypeConverter valueTypeConverter, System.ComponentModel.TypeConverter formattedValueTypeConverter, DataGridViewDataErrorContexts context)
    {
        //-Vrátím výchozí obrázek, který mohu používat v metodě Paint
        return Bitmaps.ci.FavoritePng;
    }
    protected override void Paint(System.Drawing.Graphics graphics, System.Drawing.Rectangle clipBounds, System.Drawing.Rectangle cellBounds, int rowIndex, DataGridViewElementStates elementState, object value, object formattedValue, string errorText, DataGridViewCellStyle cellStyle, DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts)
    {
        Image imgFavorites = null;
        Point locFavorites = Point.Empty;
        //-Moje vlastní metoda na výpočet souřadnic na které zakreslit, výpočet velikosti obrázku a také zmenšení obrázku na požadovanou velikost. Je vhodné nastavit neměnnost šířky a výšky řádku pokud je řádků hodně, obrázek načíst jen jednou a pak jen počítat jeho souřadnice
        Listing.CalculatePoint(cellBounds, Bitmaps.ci.FavoritePng, ImageFormats.Png, out locFavorites, out imgFavorites);
        //-Vymaluji samotný obrázek. Je nutno nejdříve vymalovat pozadí, protože jinak se použije to co má aplikace pod ním
        graphics.FillRectangle(Brushes.White, cellBounds);
        graphics.DrawImage(imgFavorites, locFavorites);
        Debug.Print(locFavorites.ToString());
        //-Vymaluji okraje řádku
        base.Paint(graphics, clipBounds, cellBounds, rowIndex, elementState, value, formattedValue, errorText, cellStyle, advancedBorderStyle, paintParts);
    }
}

Poté sloupec:

C#
class DataGridViewFavoriteColumn : DataGridViewImageColumn
{
    public DataGridViewFavoriteColumn()
    {
        this.CellTemplate = new DataGridViewFavoriteCell();
        this.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter;
        this.ValueType = typeof(Bitmap);
    }
}

Který nakonec dáme do DataGridView:

C#
dataGridView1.Columns.RemoveAt(0);
//-Tímto způsobem jsem se to taky pokoušel dělat jak s true, tak i false ale nepochodil jsem
//dataGridView1.Columns.Insert(0, new DataGridViewImageColumn(true));
dataGridView1.Columns.Insert(0, new DataGridViewFavoriteColumn());

Takže konečný výsledek je třeba takový, s tím že si v dalších událostech(třeba OnCellClick) přetypovat na typ vaší vlastní buňky, nastavit třeba příznak opačný a vyvolat překreslení. Máte tak interaktivní buňku s obrázkem:

Vlastni vymalovana bunka

Leave a Reply

Your email address will not be published. Required fields are marked *