gridView.FirstDisplayedScrollingRowIndex = gridView.SelectedRows[0].Index;
blowing up with:
No room is available to display rows
DataGridView is customized control in the unbound mode. datagridview.FirstDisplayedScrollingRowIndex is not set in a specific datagridview based event.
Rows are added to the datagridview via gatagridview.Rows.Add method on DataSet.EndMerge then cells are styled and formatted row by row. Last selected row is cleared and restored and scroll bar position restored to the first visible row.
Trying find out what this exception actually means.
if (gridView.Rows.Count > 0)
{
gridView.ClearSelection();
T value = GetItemByRow(gridView.Rows[0]);
bool isVisible = filter.ShouldShow(value);
gridView.Rows[0].Selected = true;
if (!isVisible)
{
gridView.Rows[0].Visible = true;
gridView.FirstDisplayedScrollingRowIndex = gridView.SelectedRows[0].Index;
gridView.Rows[0].Visible = false;
}
else
{
gridView.FirstDisplayedScrollingRowIndex = gridView.SelectedRows[0].Index;
}
}
When the grid is automatically sized to be 0 height (or probably width) and you set
dataGridView.FirstDisplayedScrollingRowIndex = 0;
the exception will be thrown. Our grid has set Dock = Fill and in some cases was sized to be invisible.
Our fix was to set a MinimumSize to 100/50, and we never saw the exception again. Even if the grid is not within the window (and thus invisible) the exception will now not be thrown.
When are row is present in the grid but not visible setting it to be first row will make it throw this exception.
Related
I have a gridview that display grade, but i don't want to display in one line. What i have tried is like this picture it became wrap text.
the code
gridView_Attendees.Columns["grade"].Caption = "Grade";
gridView_Attendees.Columns["grade"].Width = 150;
gridView_Attendees.Columns["grade"].OptionsFilter.AutoFilterCondition = AutoFilterCondition.Contains;
gridView_Attendees.OptionsView.RowAutoHeight = true;
gridView_Attendees.Columns["grade"].AppearanceCell.TextOptions.WordWrap = WordWrap.Wrap;
RepositoryItemMemoEdit memoEdit = new RepositoryItemMemoEdit();
memoEdit.ReadOnly = true;
memoEdit.AutoHeight = true;
memoEdit.WordWrap = true;
gridView_Attendees.GridControl.RepositoryItems.Add(memoEdit);
gridView_Attendees.Columns["grade"].ColumnEdit = memoEdit;
what i want is add new line to break into 2 lines, precisely before text Technique. like this pic
To achieve your goal, assign MemoEdit editor as a cell in-place editor
and set the View's OptionsView.RowAutoHeight property to True.
You have already used this approach but it does not work as you want so you can emulate the desired behavior by handling the GridView.CustomDrawCell event: draw the multi-line text and set the e.Handled property to true to prevent the default painting of the grid's cell's content. In this case, you need to increase the grid's row height. To do it, set the GridView.RowHeight property or handle the GridView.CalcRowHeight event , to set the individual height for the every grid's row (in this case, the GridView.OptionsView.RowAutoHeight property should be set to false).
References:
Display multi-line text in gridview cell
Multi line text indentation in XtraGrid memoedit cell
gridview cell display multiline text
I would like to display something if the data grid View is long and showing a scroll bar but don't know how to check if the scroll bar is visible. I can't simply add the rows since some may be not visible. I can't use an event since my code is already in an event.
you can try this out:
foreach (var scroll in dataGridView1.Controls.OfType<VScrollBar>())
{
//your checking here
//specifically... if(scroll.Visible)
}
I prefer this one :
//modif is a modifier for the adjustment of the Client size of the DGV window
//getDGVWidth() is a custom method to get needed width of the DataGridView
int modif = 0;
if (DataGridView.Controls.OfType<VScrollBar>().First().Visible)
{
modif = SystemInformation.VerticalScrollBarWidth;
}
this.ClientSize = new Size(getDGVWidth() + modif, [wantedSizeOfWindow]);
so the only Boolean condition you need is:
if (DataGridView.Controls.OfType<VScrollBar>().First().Visible)
{
//want you want to do
}
The DataGridView's Scrollbars Property can be questioned using the ScrollBars Enumeration by masking it with the one you are interested in like this:
if ((dataGridView1.ScrollBars & ScrollBars.Vertical) != ScrollBars.None) ...
Note, that the two 'ScrollBars' are different things here!
The answer from terrybozzio works only if you use the System.Linq namespace.
A solution without using System.Linq is shown below:
foreach (var Control in dataGridView1.Controls)
{
if (Control.GetType() == typeof(VScrollBar))
{
//your checking here
//specifically... if (((VScrollBar)Control).Visible)
}
}
To determine if the vertical scrollbar is present, you need to check how tall your visible rows are and compare against the datagridview height.
if(dgv1.Height > dgv1.Rows.GetRowsHeight(DataGridViewElementStates.Visible))
{
// Scrollbar not visible
}
else
{
// Scrollbar visible
}
Though to be more exact you may need to include a check of column widths as the presence of a horizontal scrollbar could create a vertical scrollbar that otherwise isn't there.
I have an Infragistics UltraGrid control. When I hover over a cell in the grid, it displays the contents of the cell as a tooltip for about 5 seconds. I want to increase this timeframe. I tried to override that property(AutoPopupDelay) but it still does not work.
Try the following code as discussed on the Infragistics forum. You'll want to replace the ToolTipText with the cell's value, but I assume your code already does that.
C#:
UltraGrid1.DisplayLayout.Override.TipStyleCell = TipStyle.Hide;
if (e.Element.GetAncestor(typeof(RowUIElement)) != null) {
if (object.ReferenceEquals(e.Element.GetType, typeof(RowAutoPreviewUIElement))) {
ToolTipInfo.ToolTipTitle = "Row Warnings";
ToolTipInfo.ToolTipText = "Your cell value";
UltraToolTipManager1.SetUltraToolTip(UltraGrid1, ToolTipInfo);
UltraToolTipManager1.ShowToolTip(UltraGrid1);
}
}
VB.NET:
UltraGrid1.DisplayLayout.Override.TipStyleCell = TipStyle.Hide
If e.Element.GetAncestor(GetType(RowUIElement)) IsNot Nothing Then
If e.Element.GetType Is GetType(RowAutoPreviewUIElement) Then
ToolTipInfo.ToolTipTitle = "Row Warnings"
ToolTipInfo.ToolTipText = "Your cell value"
UltraToolTipManager1.SetUltraToolTip(UltraGrid1, ToolTipInfo)
UltraToolTipManager1.ShowToolTip(UltraGrid1)
End If
End If
I have a column that holds Checkboxes.
My main problem is that when I call this function:
dataGrid.AutoResizeColumn(0, DataGridViewAutoSizeColumnMode.DisplayedCells);
It stretches the checkbox column too, and I want that column to stay in 25 in width.
How can I do that? (only checkbox column not stretched)
Here is some more code, showing what I want to happen:
dataGrid.AutoResizeColumn(0, DataGridViewAutoSizeColumnMode.DisplayedCells);
dataGrid.AutoResizeColumn(1, DataGridViewAutoSizeColumnMode.Fill);
dataGrid.AutoResizeColumn(2, DataGridViewAutoSizeColumnMode.Fill);
dataGrid.AutoResizeColumn(3, DataGridViewAutoSizeColumnMode.DisplayedCells);
dataGrid.AutoResizeColumn(4, DataGridViewAutoSizeColumnMode.Fill);
dataGrid.AutoResizeColumn(5, DataGridViewAutoSizeColumnMode.Fill);
But the fill gives me an error.
What you are asking doesn't quite make sense, since the method you show AutoResizeColumn take as its first parameter the column index to resize - if you call this method with the index of the checkbox column then your are explicitly telling the grid to resize that column. If you don't want the resize, don't do that!
If you set the resize mode the next level up for the grid, you do it like this:
dataGridView1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.DisplayedCells;
Now with this method of setting the sizing mode then yes, the checkbox will change when you might want it to.
The answer to that is to use either the designer or the method you mention above, and set the checkbox columns autosize mode to None
If you absolutely must loop over the columns setting their AutoResize mode, then the only option you have is to check if you have the checkbox column in the loop and apply a different more.
This is in answer to your comment - the error you will be seeing is an ArgumentException being thrown by the AutoResizeColumn method. This is all documented on the MSDN page for the AutoResizeColumn method. You cannot specify a AutoSize mode of None or Fill.
It sounds like what you want to do is something like:
// If column 3 is the checkbox column, we set its resize mode to none:
dataGridView1.Columns[3].AutoSizeMode = DataGridViewAutoSizeColumnMode.None;
// Then we set the width:
dataGridView1.Columns[3].Width = 25;
// Finally we set the rest of the grid to fill or what ever resizing you need:
dataGridView1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;
you can define in datagridview_cellpainting event
private void gvDocumentList_CellPainting(object sender, DataGridViewCellPaintingEventArgs e)
{
if (e.ColumnIndex == gvDocumentList.Columns["checkbox column name"].Index && e.RowIndex >= 0)
{
e.PaintBackground(e.ClipBounds, true);
Rectangle rectRadioButton = new Rectangle();
rectRadioButton.Width = 14;
rectRadioButton.Height = 14;
rectRadioButton.X = e.CellBounds.X + (e.CellBounds.Width - rectRadioButton.Width) / 2;
rectRadioButton.Y = e.CellBounds.Y + (e.CellBounds.Height - rectRadioButton.Height) / 2;
e.Paint(e.ClipBounds, DataGridViewPaintParts.Focus);
e.Handled = true;
}
}
In my C# winforms app, I have a datagrid. When the datagrid reloads, I want to set the scrollbar back to where the user had it set. How can I do this?
EDIT: I'm using the old winforms DataGrid control, not the newer DataGridView
You don't actually interact directly with the scrollbar, rather you set the FirstDisplayedScrollingRowIndex. So before it reloads, capture that index, once it's reloaded, reset it to that index.
EDIT: Good point in the comment. If you're using a DataGridView then this will work. If you're using the old DataGrid then the easiest way to do that is to inherit from it. See here: Linkage
The DataGrid has a protected GridVScrolled method that can be used to scroll the grid to a specific row. To use it, derive a new grid from the DataGrid and add a ScrollToRow method.
C# code
public void ScrollToRow(int theRow)
{
//
// Expose the protected GridVScrolled method allowing you
// to programmatically scroll the grid to a particular row.
//
if (DataSource != null)
{
GridVScrolled(this, new ScrollEventArgs(ScrollEventType.LargeIncrement, theRow));
}
}
Yep, definitely FirstDisplayedScrollingRowIndex. You'll need to capture this value after some user interaction, and then after the grid reloads you'll want to set it back to the old value.
For instance, if the reload is triggered by the click of a button, then in the button click handler, you might want to have as your first line a command that places this value into a variable:
// Get current user scroll position
int scrollPosition = myGridView.FirstDisplayedScrollingRowIndex;
// Do some work
...
// Rebind the grid and reset scrolling
myGridView.DataBind;
myGridView.FirstDisplayedScrollingRowIndex = scrollPosition;
Store your vertical and horizontal scroll values into some variable and reset them.
int v= dataGridView1.VerticalScrollingOffset ;
int h= dataGridView1.HorizontalScrollingOffset ;
//...reload
dataGridView1.VerticalScrollingOffset = v;
dataGridView1.HorizontalScrollingOffset =h;
you can save scroll position with next code
int Scroll;
void DataGridView1Scroll(object sender, ScrollEventArgs e)
{
Scroll = dataGridView1.VerticalScrollingOffset;
}
and you can set scroll of dgv to same position after refresing, load dgv... with next code:
PropertyInfo verticalOffset = dataGridView1.GetType().GetProperty("VerticalOffset", BindingFlags.NonPublic |
BindingFlags.Instance);
verticalOffset.SetValue(this.dataGridView1, Scroll, null);
Just posted the answer on the link given by BFree
The DataGrid has a protected GridVScrolled method that can be used to scroll the grid to a specific row. To use it, derive a new grid from the DataGrid and add a ScrollToRow method.
C# code
public void ScrollToRow(int theRow)
{
//
// Expose the protected GridVScrolled method allowing you
// to programmatically scroll the grid to a particular row.
//
if (DataSource != null)
{
GridVScrolled(this, new ScrollEventArgs(ScrollEventType.LargeIncrement, theRow));
}
}
VB.NET code
Public Sub ScrollToRow(ByVal theRow As Integer)
'
' Expose the protected GridVScrolled method allowing you
' to programmatically scroll the grid to a particular row.
'
On Error Resume Next
If Not DataSource Is Nothing Then
GridVScrolled(Me, New ScrollEventArgs(ScrollEventType.LargeIncrement, theRow))
End If
End Sub
I used the answer by #BFree, but also needed to capture the first visible row in the DataGrid:
int indexOfTopMostRow = HitTest(dataGrid.RowHeaderWidth + 10,
dataGrid.PreferredRowHeight + 10).Row;
Even though this is an old question, Many of the solutions above did not work for me. What worked ultimately was:
if(gridEmployees.FirstDisplayedScrollingRowIndex != -1) gridEmployees.FirstDisplayedScrollingRowIndex = 0;