I have a DataGrid with a DataTable as DataGrid.ItemsSource.
So far everything works fine and the Data is shown in the DataGrid as i want it to be.
Now I want to hide some of the Columns of the DataGrid. And I have done this before and it worked fine but somehow I always get an Error saying
"System.ArgumentOutOfRangeException: "Index was out of range. Must be non-negative and less than the size of the collection."
I know what this means but I don't understand why this is happening.
Here's my code:
adapter.Fill(datatable);
NameDG.ItemsSource = datatable.DefaultView;
//Hide Column[1]
NameDG.Columns[1].Visibility = Visibility.Hidden;
The DataGrid has more then 10 Columns.
Thanks for help.
if you click the column name it's have a negative value specific value is -1 you need to validate it by using IF STATEMENT
use this event to prevent the error
private void dataGridView1_CellDoubleClick(object sender, DataGridViewCellEventArgs e)
{
int rowIndex = e.RowIndex;
if(rowIndex <= -1)
{
//Error
}
else
{
//Your Code
}
}
Just to close this thread I will answer the question myself after I found the solutions.
You can delet the Columns directly from the DataTable like for example through this (Thanks to Nobody)
datatable.Columns.Remove(datatable.Columns[0]);
or
Use the AutoGeneratedColumns event handler from the DataGrid
You can try
NameDG.Loaded += NameDG_Loaded;
void NameDG_Loaded(object sender, RoutedEventArgs e)
{
NameDG.Columns[1].Visibility = Visibility.Collapsed;
}
Related
My problem is that it will only display the contents of datagrid on textboxes when i click on the cells under Price column which has a Money DataType all others except for ItemNo is Varchar(100). Please help, thanks
private void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
DataGridViewRow row = this.dataGridView1.CurrentRow;
txtDsc.Text = row.Cells["Description"].Value.ToString();
txtQty.Text = row.Cells["Qty"].Value.ToString();
txtUnt.Text = row.Cells["Unit"].Value.ToString();
txtPrc.Text = row.Cells["Price"].Value.ToString();
txtRmr.Text = row.Cells["Remarks"].Value.ToString();
}
As the other answer pointed out the code seems to be working fine.
I suspect the event is not firing off. Try putting in a breakpoint and investigate that bit.
I am presuming you need CellClick instead of CellContentClick.
Refer CellContentClick event doesn't always work
Alternatively if you are trying to display the text box values based on the selection on the data grid view, use DataGridView.SelectionChanged Event
I'm not entirely sure why it is only populating when you click that cell; I recreated your code and it works just fine. I did manage to recreate it again using the following code:
private void myDGV_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
int row = myDGV.CurrentCell.RowIndex;
txtDsc.Text = myDGV.Row[row].Cells["Description"].Value.ToString();
txtQty.Text = myDGV.Row[row].Cells["Qty"].Value.ToString();
txtUnt.Text = myDGV.Row[row].Cells["Unit"].Value.ToString();
txtPrc.Text = myDGV.Row[row].Cells["Price"].Value.ToString();
txtRmr.Text = myDGV.Row[row].Cells["Remarks"].Value.ToString();
}
i have an combobox cell and i wanna convert to textbox cell after select item from the same combobox cell and convert to textbox but the problem when using
[1, DataGridView1.CurrentRow.Index] = new DataGridViewTextBoxCell()`
the cell not change until click on another cell although i'm using Datagridview1.refresh()
the first picture (when select from combobox then it should be changed )
the second picture ( after click an another cell )
DataGridViewComboBoxCells are notoriously obtuse when it comes to such a simple thing as simply and fully accepting a selected value..
This seems to work for me:
ComboBox editComboBox = null;
private void DataGridView1_EditingControlShowing(object sender,
DataGridViewEditingControlShowingEventArgs e)
{
if (e.Control is ComboBox && e.ColumnIndex == 1)
{
editComboBox = (ComboBox)e.Control;
editComboBox.SelectionChangeCommitted -= editComboBox_SelectionChangeCommitted;
editComboBox.SelectionChangeCommitted += editComboBox_SelectionChangeCommitted;
}
}
void editComboBox_SelectionChangeCommitted(object sender, EventArgs e)
{
DataGridView1[1, dataGridView5.CurrentRow.Index] = new DataGridViewTextBoxCell();
DataGridView1[1, dataGridView5.CurrentRow.Index].Value =
editComboBox.SelectedItem.ToString();
DataGridView1.EndEdit();
DataGridView1[1, dataGridView5.CurrentRow.Index]cell1.Selected = false;
editComboBox = null;
}
Note that calling EndEdit allegedly can raise an exception if no error handler is found. I don't have one and I still don't get an error. Not sure what the docs mean; maybe that it may raise an error if the data are in fact invalid..
Also note that with this design the user can not easily correct an edit, unless you provide a way to restore the dropdown..
I have added a DataGridViewComboBox to a bound DataGridView (grdBOOK), the DataGridViewComboBox will replace column 3 to allow for user selection. I'm struggling to set the default of the DataGridViewComboBox equal to the value of column 3 so user selection is not required if the value is correct.
I pulled the code below from the net, but I get an error:
DataGridViewComboBoxCell value is not valid.
I thought a ComboBox cell could be treated as a normal DataGridView cell, but (see code below) an error is generated when a string is added to the ComboBox column? I've trawled the net and SO for a few days but nothing works, any suggestions please?
public void BOOK_COMBO2()
{
DataGridViewComboBoxCell cb_cell = new DataGridViewComboBoxCell();
DataGridViewComboBoxColumn cb_col = new DataGridViewComboBoxColumn();
// Contract field
cb_col.Items.AddRange("YEARLY", "MONTHLY", "");
cb_col.FlatStyle = FlatStyle.Flat;
cb_col.HeaderText = "newCONTRACT";
cb_col.Width = 50;
cb_col.ValueType = typeof(string);
// Add ComboBox and test
grdBOOK.Columns.Insert(5, cb_col);
grdBOOK.Rows[14].Cells[4].Value = "zzz"; // No error adding string to normal dgv column
grdBOOK.Rows[14].Cells[5].Value = "xxx"; // Error adding string to dgvcombobx column
//copy old values to new combobox and set as default
foreach (DataGridViewRow item in grdBOOK.Rows)
{
item.Cells[5].Value = item.Cells[3].Value;
}
//hide original column
grdBOOK.Columns[3].Visible = false;
}
After more research on the net, IMHO using a ContextMenuStrip is a better method of achieving this. Link here. A ContextMenuStrip has better methods, events, properties etc. I hope this helps others looking for a solution.
private void dataGridView1_DataError(object sender,
DataGridViewDataErrorEventArgs e)
{
// If the data source raises an exception when a cell value is
// commited, display an error message.
if (e.Exception != null &&
e.Context == DataGridViewDataErrorContexts.Commit)
{
MessageBox.Show("");
}
}
private void Form1_Load(object sender, EventArgs e)
{ dataGridView1.DataError +=
dataGridView1_DataError;}
What I want to do is to change value of row's forth cell if cell number 3 is changed. I have an EditEnding method for my grid. That's my method below. I don't really know how to finish it
that's the grid definition:
<DataGrid x:Name="dataGrid1"... CellEditEnding="dataGrid1_EditEnding">
and the method:
private void dataGrid1_EditEnding(object sender, DataGridCellEditEndingEventArgs e)
{
// initializing DataRowView from my datagrid
DataRowView drv = (DataRowView)dataGrid1.CurrentItem;
// checking if there were any changes
if (drv.Row[3, DataRowVersion.Original] != drv.Row[3])
{
//set value to cell
}
}
Well, i did my stuff, just forget to post it here.
First I did it with EditEnding event, it looked like that:
private void dataGrid1_EditEnding(object sender, DataGridCellEditEndingEventArgs e)
{
DataRowView drv = (DataRowView)dataGrid1.CurrentItem;
if (drv.Row[3, DataRowVersion.Original] != drv.Row[3])
{
rowView.Row.SetField(4, /* my logic here */);
}
}
The problem was it was adding the value only on second edit. Then I changed my idea and added a RowChanged event to my DataTable, which was like that:
static void dtSP_RowChanged(object sender, DataRowChangeEventArgs e)
{
bool temp = false;
try
{
temp = e.Row[4, DataRowVersion.Original] == e.Row[4];
}
catch { }
if (temp && int.Parse(e.Row[3].ToString()) != -1)
{
e.Row[4] = (/* my logic */);
}
}
The method was going into infinity loop (it was noticing, that fourth row had changed).
And then i saw this:
http://www.windowsdevcenter.com/pub/a/dotnet/2003/05/26/datacolumn_expressions.html
I've ended with one line long code:
dtSP.Columns[4].Expression = "expression";
#blindmeis, I forgott to mention I use ADO.NET, sorry
do not edit the datagridrow - edit the underlying object in wpf!
this mean when the bound property to cell 3 is changed then do your changes to the property bound to cell 4. INotifyPropertyChanged will notify your grid and will show your changes
If you already have logic to calculate cell4 value when cell3 is changed, then when property binded to column 3 is changed you should call INotifyPropertyChanged of property binded to column 3 & 4.
Consider the following picture
I get the selected row values in the three textboxes shown in the figure when i click a cell using following code.
void dataGridView1_CellClick_1(object sender, DataGridViewCellEventArgs e) {
TBGRNo.Text = dataGridView1.Rows[e.RowIndex].Cells[0].Value.ToString();
TBSName.Text = dataGridView1.Rows[e.RowIndex].Cells[1].Value.ToString();
TBFName.Text = dataGridView1.Rows[e.RowIndex].Cells[2].Value.ToString();
}
My Question is: how will I do the same thing in DevExpress XtraGrid control??
Here is the way that I've followed,
int[] selRows = ((GridView)gridControl1.MainView).GetSelectedRows();
DataRowView selRow = (DataRowView)(((GridView)gridControl1.MainView).GetRow(selRows[0]));
txtName.Text = selRow["name"].ToString();
Also you can iterate through selected rows using the selRows array. Here the code describes how to get data only from first selected row. You can insert these code lines to click event of the grid.
You can do this in a number of ways. You can use databinding (typical initialized after InitializeComponent();)
textBox1.DataBindings.Add(new Binding("Text", yourBindingSource,
"TableName.ColumnName", true, DataSourceUpdateMode.OnPropertyChanged));
or use a DataLayoutControl (if you are going to use textbox for editing, I really recommend spending some time to learn how to use this component.
or in FocusedRowChanged by assigning from one of these methods:
textBox1.Text = gridView1.GetDataRow(e.FocusedRowHandle)["Name"].ToString();
textBox1.Text = gridView1.GetFocusedDataRow()["Name"].ToString();
textBox1.Text = (gridView1.GetFocusedRow() as DataRowView).Row["Name"].ToString();
textBox1.Text = gridView1.GetFocusedRowCellValue("Name").ToString();
I found the solution as follows:
private void gridView1_RowCellClick(object sender, DevExpress.XtraGrid.Views.Grid.RowCellClickEventArgs e)
{
TBGRNo.Text = gridView1.GetRowCellValue(gridView1.FocusedRowHandle, "GRNo").ToString();
TBSName.Text = gridView1.GetRowCellValue(gridView1.FocusedRowHandle, "SName").ToString();
TBFName.Text = gridView1.GetRowCellValue(gridView1.FocusedRowHandle, "FName").ToString();
}
Which one of their Grids are you using? XtraGrid or AspXGrid? Here is a piece taken from one of my app using XtraGrid.
private void grdContactsView_RowClick(object sender, DevExpress.XtraGrid.Views.Grid.RowClickEventArgs e)
{
_selectedContact = GetSelectedRow((DevExpress.XtraGrid.Views.Grid.GridView)sender);
}
private Contact GetSelectedRow(DevExpress.XtraGrid.Views.Grid.GridView view)
{
return (Contact)view.GetRow(view.FocusedRowHandle);
}
My Grid have a list of Contact objects bound to it. Every time a row is clicked I load the selected row into _selectedContact. Hope this helps. You will find lots of information on using their controls buy visiting their support and documentation sites.
For VB.Net
CType(GridControl1.MainView, GridView).GetFocusedRow()
For C#
((GridView)gridControl1.MainView).GetFocusedRow();
example bind data by linq so use
Dim selRow As CUSTOMER = CType(GridControl1.MainView, GridView).GetFocusedRow()
All you have to do is use the GetFocusedRowCellValue method of the gridView control and put it into the RowClick event.
For example:
private void gridView1_RowClick(object sender, DevExpress.XtraGrid.Views.Grid.RowClickEventArgs e)
{
if (this.gvCodigoNombres.GetFocusedRowCellValue("EMP_dni") == null)
return;
MessageBox.Show(""+this.gvCodigoNombres.GetFocusedRowCellValue("EMP_dni").ToString());
}
var rowHandle = gridView.FocusedRowHandle;
var obj = gridView.GetRowCellValue(rowHandle, "FieldName");
//For example
int val= Convert.ToInt32(gridView.GetRowCellValue(rowHandle, "FieldName"));