23 августа 2010 г.

.Net Compact Framework: Изменения цвета фона определенных строк DataGrid'а

// Для подсветки необходимых строк в датагриде создал класс,
// по примеру показанному здесь

class DataGridCustomColumnRowColor : DataGridTextBoxColumn
{
    #region Privates
    private DataGrid _owner = null;
    private StringFormat _stringFormat = null;
    private Color _customRowBackColor = SystemColors.Window; // Back color for odd numbered rows
    private SolidBrush _customBrush = null;
    #endregion

    #region Public properties
    public Color CustomRowBackColor
    {
        get
        {
            return _customRowBackColor;
        }
        set
        {
            if (_customRowBackColor != value) // Setting new color?
            {
                if (this._customBrush != null) // See if got brush
                {
                    this._customBrush.Dispose(); // Yes, get rid of it.
                }

                this._customRowBackColor = value; // Set new color

                this._customBrush = new SolidBrush(value); // Create new brush.

                Invalidate();
            }
        }
    }

    public StringFormat StringFormat
    {
        get
        {
            if (null == _stringFormat) // No format yet?
            {
                _stringFormat = new StringFormat(); // Create one.

                this.Alignment = HorizontalAlignment.Left; // And set default aligment.
            }

            return _stringFormat; // Return our format
        }
    }

    public DataGrid Owner
    {
        get
        {
            if (null == _owner)
            {
                throw new InvalidOperationException("DataGrid owner of this ColumnStyle must be set prior to this operation.");
            }
            return _owner;
        }
        set
        {
            if (null != _owner)
            {
                throw new InvalidOperationException("DataGrid owner of this ColumnStyle is already set.");
            }

            _owner = value;
        }
    }

    public virtual HorizontalAlignment Alignment
    {
        get
        {
            return (this.StringFormat.Alignment == StringAlignment.Center) ? HorizontalAlignment.Center :
                   (this.StringFormat.Alignment == StringAlignment.Far) ? HorizontalAlignment.Right : HorizontalAlignment.Left;
        }
        set
        {
            if (this.Alignment != value) // New aligment?
            {
                this.StringFormat.Alignment = (value == HorizontalAlignment.Center) ? StringAlignment.Center :
                                              (value == HorizontalAlignment.Right) ? StringAlignment.Far : StringAlignment.Near;
                // Set it.
                Invalidate(); // Aligment just changed, repaint.
            }
        }
    }
    #endregion

    protected override void Paint(Graphics g, Rectangle bounds, CurrencyManager source, int rowNum, Brush backBrush, Brush foreBrush, bool alignToRight)
    {
        RectangleF textBounds; // Bounds of text
        Object cellData; // Object to show in the cell

        DrawBackground(g, bounds, rowNum, backBrush); // Draw cell background

        bounds.Inflate(-2, -2); // Shrink cell by couple pixels for text.

        textBounds = new RectangleF(bounds.X, bounds.Y, bounds.Width, bounds.Height);
        // Set text bounds.
        cellData = this.PropertyDescriptor.GetValue(source.List[rowNum]); // Get data for this cell from data source.

        g.DrawString(FormatText(cellData), this.Owner.Font, foreBrush, textBounds, this.StringFormat);
        // Render contents
    }


    protected virtual void DrawBackground(Graphics g, Rectangle bounds, int rowNum, Brush backBrush)
    {
        Brush background = backBrush; // Use default brush by... hmm... default.

        DataTable datatab = (DataTable)Owner.DataSource;

        if ((null != background) && (Boolean)datatab.Rows[rowNum]["_CustomColor"] && !Owner.IsSelected(rowNum))
        { // If have alternating brush, row is odd and not selected...
            background = _customBrush; // Then use alternating brush.
        }

        g.FillRectangle(background, bounds); // Draw cell background
    }

    protected virtual String FormatText(Object cellData)
    {
        String cellText; // Formatted text.

        if ((null == cellData) || (DBNull.Value == cellData)) // See if data is null
        {
            cellText = this.NullText; // It's null, so set it to NullText.
        }
        else if (cellData is IFormattable) // Is data IFormattable?
        {
            cellText = ((IFormattable)cellData).ToString(this.Format, this.FormatInfo);
            // Yes, format it.
        }
        else if (cellData is IConvertible) // May be it's IConvertible?
        {
            cellText = ((IConvertible)cellData).ToString(this.FormatInfo); // We'll take that, no problem.
        }
        else
        {
            cellText = cellData.ToString(); // At this point we'll give up and simply call ToString()
        }

        return cellText;
    }
    protected void Invalidate()
    {
        if (this.Owner != null) // Got parent?
        {
            this.Owner.Invalidate(); // Repaint it.
        }
    }
}

//Пример использования

//Создаем таблицу
DataTable myDataTable = new DataTable();

//Добаляем необходимые нам колонки
...

//добавляем колонку с именем "_CustomColor", которая будет служить флагом,
//если значение в этой колонке - true, тогда надо подсвечивать эту строку
myDataTable.Columns.Add("_CustomColor", System.Type.GetType("System.Boolean"));
...

//Заполняем таблицу значениями
DataRow myDataRow = myDataTable.NewRow();
...
myDataRow["_CustomColor"] = true/false;
...
myDataTable.Rows.Add(myDataRow);

//Указываем DataSource грида
myDataGrid.DataSource = myDataTable;
...

//Создаем TableStyle
DataGridTableStyle myTbStyle = new DataGridTableStyle();
//Cоздаем цвет подсветки
Color myCustomColor = System.Drawing.Color.Red;

//Добавляем колонки в DataGrid, все добавляемые колонки должны быть нашего класса
DataGridCustomColumnRowColor myDataGridCustomColumn1 = new DataGridCustomColumnRowColor();
...
//Указываем датагрид
myDataGridCustomColumn1.Owner = myDataGrid;
//Указывем наш цвет
myDataGridCustomColumn1.CustomRowBackColor = myCustomColor;
...

myTbStyle.GridColumnStyles.Add(myDataGridCustomColumn1);
//Так повторяем дял каждой колонки

//После всего добвляем стиль в DataGrid
myDataGrid.TableStyles.Add(myTbStyle);

1 комментарий: