|
when i compiled it to dll in c# and add reference in vb.net i gotta some errors
DirectCast(DataGridView1.Item(1, 3), SpannedDataGridView.DataGridViewTextBoxCellEx).ColumnSpan = 3
erorros :
Unable to cast object of type 'System.Windows.Forms.DataGridViewTextBoxCell' to type 'SpannedDataGridView.DataGridViewTextBoxCellEx'.
How can i fixed it ??
pls kindly convert it from c# to vb.net project and send to my email: nimol.elixir@gmail.com ,,
pls help me, i'm very need it..
|
|
|
|
|
Hello Sergey,
i really like this project!
I try to speed up my DataGridViews by enabling Double-Buffering, but sadly the DataGridViewTextBoxCellEx doesn't work with this - spanned cells don't paint correctly.
I got thus far: using DataGridView.CreateGraphics() in Paint(...) should't be used, but still something is missing...
Any idea?
|
|
|
|
|
Hello.
Whould you show your code, which doesn't work correctly?
|
|
|
|
|
well, essentially i used the sample code from the zip
in DemoForm.cs i added:
SetDoubleBuffered(dataGridView1);
to the constructor
code for SetDoubleBuffered():
public static void SetDoubleBuffered(Control control)
{
typeof(Control).InvokeMember("DoubleBuffered",
BindingFlags.SetProperty | BindingFlags.Instance | BindingFlags.NonPublic,
null, control, new object[] { true }
);
}
(this has the same effect as deriving DataGridViewEx from DataGridView and setting this.Doublebuffered = true; in its contructor)
-> Effect: the spanned cells are incorrectly drawn, selection highlight is broken (use keyboard navigation for example)
i have a slightly adopted version of the sources, where i took some effort to overcome this, see
http://www.filedropper.com/spanneddatagridview[^]
(mainly changed some coding-style like braces)
best regards
|
|
|
|
|
Yes, you are right. DataGridView.CreateGraphics() in Paint() cause the problem. We should use buffer graphics, otherwise our painting will be corrupted, when buffer is applied. But using an instant graphics isn't a solution: we cant paint an expanded area.
I tried to use origin graphics and invalidate child cells in Paint(), this works, but hangs the app: Paint() is called very often. It's not good.
Now, I have not any good idea. I'm sorry.
|
|
|
|
|
Following code worked for me. But I don't know why. Smile | Replace your Paint method with this:
protected override void Paint(Graphics graphics, Rectangle clipBounds, Rectangle cellBounds, int rowIndex, DataGridViewElementStates cellState, object value, object formattedValue, string errorText, DataGridViewCellStyle cellStyle, DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts)
{
if (_ownerCell != null && _ownerCell.DataGridView == null)
{
_ownerCell = null;
}
if (DataGridView == null || (_ownerCell == null && _columnSpan == 1 && _rowSpan == 1))
{
base.Paint(graphics, clipBounds, cellBounds, rowIndex, cellState, value, formattedValue, errorText, cellStyle, advancedBorderStyle, paintParts);
return;
}
var ownerCell = this;
var columnIndex = ColumnIndex;
var columnSpan = _columnSpan;
var rowSpan = _rowSpan;
if (_ownerCell != null)
{
ownerCell = _ownerCell;
columnIndex = _ownerCell.ColumnIndex;
rowIndex = _ownerCell.RowIndex;
columnSpan = _ownerCell.ColumnSpan;
rowSpan = _ownerCell.RowSpan;
value = _ownerCell.GetValue(rowIndex);
errorText = _ownerCell.GetErrorText(rowIndex);
cellState = _ownerCell.State;
cellStyle = _ownerCell.GetInheritedStyle(null, rowIndex, true);
formattedValue = _ownerCell.GetFormattedValue(value, rowIndex, ref cellStyle, null, null, DataGridViewDataErrorContexts.Display);
}
if (CellsRegionContainsSelectedCell(columnIndex, rowIndex, columnSpan, rowSpan))
{
cellState |= DataGridViewElementStates.Selected;
}
RectangleF oldBounds = graphics.ClipBounds;
var cellBounds2 = DataGridViewCellExHelper.GetSpannedCellBoundsFromChildCellBounds(this, cellBounds, DataGridView.SingleVerticalBorderAdded(), DataGridView.SingleHorizontalBorderAdded());
clipBounds = DataGridViewCellExHelper.GetSpannedCellClipBounds(ownerCell, cellBounds2, DataGridView.SingleVerticalBorderAdded(), DataGridView.SingleHorizontalBorderAdded());
advancedBorderStyle = DataGridViewCellExHelper.AdjustCellBorderStyle(ownerCell);
using (var g = this.DataGridView.CreateGraphics())
{
g.SetClip(clipBounds);
ownerCell.NativePaint(g, clipBounds, cellBounds2, rowIndex, cellState, value, formattedValue, errorText, cellStyle, advancedBorderStyle, paintParts & ~DataGridViewPaintParts.Border);
if ((paintParts & DataGridViewPaintParts.Border) != DataGridViewPaintParts.None)
{
var leftTopCell = ownerCell;
var advancedBorderStyle2 = new DataGridViewAdvancedBorderStyle
{
Left = advancedBorderStyle.Left,
Top = advancedBorderStyle.Top,
Right = DataGridViewAdvancedCellBorderStyle.None,
Bottom = DataGridViewAdvancedCellBorderStyle.None
};
leftTopCell.PaintBorder(g, clipBounds, cellBounds2, cellStyle, advancedBorderStyle2);
var rightBottomCell = DataGridView[columnIndex + columnSpan - 1, rowIndex + rowSpan - 1] as DataGridViewSpannedTextBoxCell ?? this;
var advancedBorderStyle3 = new DataGridViewAdvancedBorderStyle
{
Left = DataGridViewAdvancedCellBorderStyle.None,
Top = DataGridViewAdvancedCellBorderStyle.None,
Right = advancedBorderStyle.Right,
Bottom = advancedBorderStyle.Bottom
};
rightBottomCell.PaintBorder(g, clipBounds, cellBounds2, cellStyle, advancedBorderStyle3);
}
}
graphics.SetClip(clipBounds);
ownerCell.NativePaint(graphics, clipBounds, cellBounds2, rowIndex, cellState, value, formattedValue, errorText, cellStyle, advancedBorderStyle, paintParts & ~DataGridViewPaintParts.Border);
if ((paintParts & DataGridViewPaintParts.Border) != DataGridViewPaintParts.None)
{
var leftTopCell = ownerCell;
var advancedBorderStyle2 = new DataGridViewAdvancedBorderStyle
{
Left = advancedBorderStyle.Left,
Top = advancedBorderStyle.Top,
Right = DataGridViewAdvancedCellBorderStyle.None,
Bottom = DataGridViewAdvancedCellBorderStyle.None
};
leftTopCell.PaintBorder(graphics, clipBounds, cellBounds2, cellStyle, advancedBorderStyle2);
var rightBottomCell = DataGridView[columnIndex + columnSpan - 1, rowIndex + rowSpan - 1] as DataGridViewSpannedTextBoxCell ?? this;
var advancedBorderStyle3 = new DataGridViewAdvancedBorderStyle
{
Left = DataGridViewAdvancedCellBorderStyle.None,
Top = DataGridViewAdvancedCellBorderStyle.None,
Right = advancedBorderStyle.Right,
Bottom = advancedBorderStyle.Bottom
};
rightBottomCell.PaintBorder(graphics, clipBounds, cellBounds2, cellStyle, advancedBorderStyle3);
}
graphics.SetClip(oldBounds);
}
|
|
|
|
|
I have some little-big problem with a spannedcolumn
Spanned over 4 cells, with
- datagridview autosizerowmode = allcells
- column.DefaultCellStyle.WrapMode = true
when the text (take a page of text for example) is inside the cell, it adds empty lines at the bottom for a certain amount.
if you don't use spaces it does not add the lines.
Any idea? or do you need more code?
|
|
|
|
|
Hi.
Yes, you're right, there is a problem. Here a code fixing the problem (not tested completely).
public class DataGridViewTextBoxCellEx: DataGridViewTextBoxCell, ISpannedCell
{
......
protected override Size GetPreferredSize(Graphics graphics, DataGridViewCellStyle cellStyle, int rowIndex, Size constraintSize)
{
var size = base.GetPreferredSize(graphics, cellStyle, rowIndex, constraintSize);
if (OwnerCell != null) return size;
var grid = DataGridView;
var height = size.Height - Enumerable.Range(RowIndex + 1, RowSpan - 1)
.Select(index => grid.Rows[index].Height)
.Sum();
return new Size(size.Width, height);
}
......
}
Place the method into DataGridViewTextBoxCellEx class (or other).
Later I publish this changes.
|
|
|
|
|
I'm sorry for misunderstanding your question in the previous reply.
This problem is a problem/feature of DataGridViewTextBoxCell (you may test it) which I use, so I cant fix it in the near future.
I hope, I've answered to the question correctly now.
|
|
|
|
|
Question 1 :
When you use the CellPainting event of the datagridview... to change the cell color depending on a value, this occurs correctly EXCEPT for the spanned cells... any idea?
Question 2 :
How to bind the grid to a datasource so that every cell is of type datagridtextboxcolumnEX? after a standard bind , these are regular datacolumns....?
Kindly regards
Gert De Busser
Belgium .
example Question 1 :
Private Sub grdResult_CellPainting(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellPaintingEventArgs) Handles grdResult.CellPainting
Try
If e.RowIndex >= 0 Then
If e.ColumnIndex = ResultaatKolom Then
If grdResult.Rows(e.RowIndex).Cells(ResultaatKolom).ReadOnly = False Then
e.CellStyle.BackColor = Color.Cornsilk
e.CellStyle.ForeColor = Color.Black
Else
e.CellStyle.BackColor = Color.White
e.CellStyle.ForeColor = Color.Black
End If
Else
e.CellStyle.BackColor = Color.White
e.CellStyle.ForeColor = Color.Black
End If
End If
Catch ex As Exception
MsgBox(ex.InnerException.ToString & ex.Message.ToString)
End Try
End Sub
Private Sub SetReadOnly()
Dim row As DataGridViewRow
For Each row In grdResult.Rows
Dim c As SpannedDataGridView.DataGridViewTextBoxCellEx
For Each c In row.Cells
If c.ColumnIndex = ResultaatKolom Then
If c.Value.ToString.Contains("0") Then
If AlleVeldenInvullen = True Then
c.ReadOnly = False
Else
c.ReadOnly = True
End If
DirectCast(c, SpannedDataGridView.DataGridViewTextBoxCellEx).ColumnSpan = 2
Else
c.ReadOnly = False
DirectCast(c, SpannedDataGridView.DataGridViewTextBoxCellEx).ColumnSpan = 1
End If
Else
c.ReadOnly = True
DirectCast(c, SpannedDataGridView.DataGridViewTextBoxCellEx).ColumnSpan = 1
End If
Next
grdResult.InvalidateRow(row.Index)
Next
grdResult.Refresh()
End Sub
|
|
|
|
|
Hi.
A for Q1: Use DataGridVeiw.CellFormatting event to set colors.
A for Q2: Set DataGridVeiw.AutoGenerateColumns = false before applying data source.
|
|
|
|
|
works perfect. Thx! cellformatting <> cellpainting ... sometimes strange.
|
|
|
|
|
It's practice from documentation.
|
|
|
|
|
Hi, first of all great work. I was checking your demo and when I set the first row to frozen it began to draw the cell overlaped, it seems that it looses the correct position of the cells.
Regards
|
|
|
|
|
Hi. Thank you very much!
Yes, you are right, it take place. But do you propose to froze whole spanned row when a part is frozen?
|
|
|
|
|
As a matter of fact yes, I believe that's probably one reason of the bug, however I believe it has something to do in the way the boundaries are calculated.
Well it is not a must to have frozen cells in my application, and definitely having merging cells is need it. Eather way I will try to see how this can be fix and if I had the solution I will post it here.
Thanks
|
|
|
|
|
It would be wonderful.
Thanks.
|
|
|
|
|
when i use right to left alignment, it becomes crazy DataGridView..
so how can i solve this ???
|
|
|
|
|
Thanks. I've fixed it and new release will be available soon. I'll tell you when it will.
|
|
|
|
|
New files are available now.
|
|
|
|
|
Great job! Thank you!
I've found one bug though. I use DataGridView without row and column header. In this case, if spanned cells are in the first row (ColumnSpan) or first column (RowSpan), they don't paint properly. Any ideas?
Gennadiy
|
|
|
|
|
Hi!
Thanks for the bug report. I've found out that cells of first row(column) of DataGridView without header row(column) have different height(width). So, they did not paint correctly: bottom(right) parts remained not painted. I've fixed it, and a new version is available now.
|
|
|
|
|
Thank you for quick reply. But your solution didn't work for me well. In my DataGridView data grid border width is 1pt, in your demo project border width is 2pt.
I've replaced your code
if (singleVerticalBorderAdded)
clipBounds.Width++;
if (singleHorizontalBorderAdded)
clipBounds.Height++;
with
if (singleVerticalBorderAdded)
{
clipBounds.Width += 2;
clipBounds.X--;
}
if (singleHorizontalBorderAdded)
{
clipBounds.Height += 2;
clipBounds.Y--;
}
and
if (singleVerticalBorderAdded)
spannedCellBounds.Width++;
if (singleHorizontalBorderAdded)
spannedCellBounds.Height++;
with
if (singleVerticalBorderAdded)
{
spannedCellBounds.Width ++;
spannedCellBounds.X--;
}
if (singleHorizontalBorderAdded)
{
spannedCellBounds.Height ++;
spannedCellBounds.Y--;
}
it works just fine.
|
|
|
|
|
Very interesting... But I can't detect the border you mean (what property, where did you get 1pt and 2pt), and I can't model the bug scenario. Would you please explain it, or/and bring some code.
|
|
|
|
|
I've found it! In my project DataGridView 's BorderStyle = FixedSingle , in yours BorderStyle = Fixed3D .
|
|
|
|
|