2

DataGridView に時間のリストを表示していますが、営業時間外の時間に影を付けたいと考えています。CellPainting を使用してこれを実行しようとしていますが、奇妙な結果が得られます。誰かが私がここで間違っていることを説明してもらえますか?

private void dgvItemView_CellPainting(object sender, DataGridViewCellPaintingEventArgs e)
{
    switch (_formType)
    {
        case FormType.DayView:
            TimeSpan openTime = iFlow.Properties.Settings.Default.BusinessHourOpen;
            TimeSpan closeTime = iFlow.Properties.Settings.Default.BusinessHourClose;

            DataGridViewCell cell = this.dgvItemView[e.ColumnIndex, e.RowIndex];

            if (cell.RowIndex < openTime.Hours || cell.RowIndex > closeTime.Hours)
            {
                e.Graphics.FillRectangle(new SolidBrush(Color.FromArgb(25, Color.Red)), e.ClipBounds);
            }
            break;
    }
}

ただし、このコードは次のようにグラデーション効果をもたらします。

形

私は本当に理解していません。上下にスクロールすると、どれだけスクロールするかに応じて、シェーディングも消えて再表示されます。

だから誰かが私がここで間違っていることを説明してもらえますか? また、営業時間が 08:45 から 17:30 などの時間外の場合に備えて、部分ブロックをペイントする必要があるため、セルの BackColor を変更してこれを実現することはできません。

4

1 に答える 1

2

e.ClipBoundsの可視部分全体を指しますDataGridView
基本的に行っていることは、表示領域全体に複数の透明なレイヤーをペイントするDataGridViewことであり、スクロールするとグラデーション効果が得られます。

e.CellBounds代わりに使用する必要があります。

あなたの問題とは関係のない別の問題は、から GDI ハンドルをリークしていることですSolidBrush。塗装後の、またはさらに良いことに、ステートメントを次のように使用しDispose()ます。SolidBrushusing

using (var sb = new SolidBrush(Color.FromArgb(25, Color.Red)))
{
    e.Graphics.FillRectangle(sb , e.CellBounds);
}

編集:

システムが作品の上にペイントするのを防ぐために、ペイント後も設定e.Handledする必要があります。true

MSDNから:

セルを手動で描画する場合は、HandledEventArgs.Handled プロパティを true に設定します。HandledEventArgs.Handled を true に設定しない場合、セルはカスタマイズを上書きします。

于 2013-01-01T18:13:25.690 に答える