Update Devexpress ComboBoxItemCollection items in the gridview mouse down event - c#

I am using Devexpress Xtragrid Gridcontrol to show stuff in the grid. Each row shows the values of one object, which is represented as text cell besides two comboboxes. To represent the comboboxes I am using repositoryItemComboBox and ComboBoxItemCollection. I have also defined this event for the gridview
prjGridView_MouseDown(object sender, MouseEventArgs e)
{
var hitInfo = prjGridView.CalcHitInfo(e.Location);
if (hitInfo.InRowCell)
{
int rowHandle = hitInfo.RowHandle;
GridColumn column = hitInfo.Column;
if (hitInfo.Column.Name.Equals("UsersItems"))
{
//Update the cell combobox data
}
How can I get the control in the cell shown in the hitInfo. I need this to update the values of the combobox in that cell, each "UserItems" combobox can have different items.
thanks,
ES

You can use ActiveEditor property of gridview.
var activeEditor = prjGridView.ActiveEditor;

Found a very simple method.
I defined this in the class
private ComboBoxItemCollection phaseColl
within the molusedown event I simply use the RowHandle to extract the correct object that is being represented in the row and update the combobox. I think this is a very simple implementation since one cannot look at multiply controls at the same time this will work.
-es

Related

how to get the rows property in gridview of devxpress with a button to edit?

i have a gridview with devexpress my gridview contain a id ID="GriviewLV1" and i have a button in the row of the gridview to edit the record , in the event click of the button im trying give click in the button to edit but cannot get the property rows or something like that. im trying something like this but cannot do rows property because dont exist the rows property in grid view devexpress
button_Edit_click(object sender, EventArgs e)
{
foreach (GridViewRow row in GriviewLV1.Rows)
{
}
}
And for what exactly do you need row collection?
As far as I know, you can only manipulate with records (DataSource property object). Also it is possible to get selected row. Some my code examples with explanation:
private List<ImageSetMember> imageSets;
...
//assign collection as grid's DataSource.
//From now on any actions on imageSets object will be automatically reproduced
//as grid's row changes.
imageSetGridControl.DataSource = imageSets;
...
private void replaceButtonEdit_Click(object sender, System.EventArgs e)
{
//get focused row record's index at DataSource collection
int index = imageSetGridView.GetDataSourceRowIndex(imageSetGridView.FocusedRowHandle);
var selectedImage = imageSet[index].Image; //accessing to row's record
}

WinForm - DataGridView when row change event

I currently have an event set for RowHeaderMouseClick when I click on the header, my textbox is populated with data from the DataGrid. I want to make my textbox populate when I select the row instead of the header. Ideally, I want to hide the header. What is the correct event/property that I need to set to achieve this?
Edit:
Attaching screenshot
You can make like this for any event
//Handle RowChanged.
table.RowChanged += table_RowChanged;
//RowChanged Event.
static void table_RowChanged(object sender, DataRowChangeEventArgs e)
{
Console.WriteLine("... Changed: " + (int)e.Row["Dosage"]);
}
You don't need to do it with events, as you seem to be saying that the textbox gets populated with an item from the row. In such a case you would have:
your datagridview bound to a bindingsource
your bindingsource bound to a datatable or other list that supports binding
your textbox's text property bound to the same bindingsource
Every time the user clicks a row in the grid (or uses the keyboard to move to another row) they are causing the Current property of the bindingsource to update. This in turn changes any of the textboxes that are bound to true same binding source (a textbox only shows the current row item to which it is bound)
For a quick demo of how this works, do these steps (apologies I can't make any screenshots - I'm on a cellphone) - skip any steps you've already done
add a DataSet type file to your project
open it and right click the surface, add a datatable and name it eg Person
right click it and add a couple of columns eg FirstName and LastName
save
switch to the form
open the Dat Sources window (view menu, other windows)
drag the Person node to the form, a datagridview appears as well as some other stuff (bindingsource) - look at the DataSource property of the grid
in the Data sources window again click the drop down button next to Person, change it to details
drag the person node to the form again, this time textboxes appear; take a look at their Text bindings in the (data bindings) section of their properties - they're bound to the same bindingsource as the grid is
run the project, type 4 names into the grid and then select different rows at random using the mouse; the textboxes update to stay current with the grid selection
If this isn't the way you've done things up to now you should consider making it the way; using the DataSet designer to create strongly typed datatables is an easy way to model the data aspects of your program and there is a lot of tooling set up to make life easier when you use them to make a data driven app. If you've been putting data directly into a datagridview it's something you should avoid going forward, and instead separate your concerns in a more mvc style pattern
If you want to remove or make the rowHeader invisible
You can SET an Event DataGridView CellClick and below is the CODE
//Im Assuming that we are getting the row VALUES
try{
int rowIndex = e.RowIndex; //getting the position of ROW in DGV when CLick
int columns = Columns.Count//numebr of Columns
for(int i=0; i< columns;i++)
{
//Here we can populate textBoxes and using FlowLayoutPanel
string values = dataGridView1.Rows[rowIndex].Columns[i].Value.toString();
//Creating new TextBox
TextBox txtBox = new TextBox();
txtBox.Text = values;
txtBox.Size = new Size(100,200);
flowLayoutPanel1.Controls.Add(txtBox);
}
}catch(Exception ee){}
OR If you want to pass the VALUES of the selected ROW you can do like this
textBox.Text = dataGridView1.Rows[rowIndex].Columns[0].Value.toString();//1st col
textBox1.Text = dataGridView1.Rows[rowIndex].Columns[1].Value.toString();//2nd col
First, right-click your dataGrid and select properties
Then change the SelectionMode to FullRowSelect if you like as shown below:
Next, In the datagrid event section double-click on SelectionChanged
and write code like this, you can use other events, although
// Just for example
private void dataGridView1_SelectionChanged(object sender, EventArgs e)
{
try
{
if (dataGridView1.CurrentRow != null && dataGridView1.CurrentRow.Index >= 0)
{
var row = dataGridView1.CurrentRow;
txtCode.Text = (row.Cells["code"].Value != null) ? row.Cells["code"].Value.ToString() : string.Empty;
txtFirstName.Text = (row.Cells["firstName"].Value != null) ? row.Cells["firstName"].Value.ToString() : string.Empty;
txtLastName.Text = (row.Cells["lastName"].Value != null) ? row.Cells["lastName"].Value.ToString() : string.Empty;
}
}
catch { }
}

Infragistics grid : row overlapping

I'm using Infragistics ultrawingrid v16.1 in windows application. Below are Row style properties of grid. each cell in row has 3 to 4 lines of data. But it is showing only first line. In below screenshot, first line data is overlapped. I'm expecting the data shown as in second row. Please let me know how to show entire data of a cell. Thanks in advance.
this.grd1.DisplayLayout.Override.RowSelectors = Infragistics.Win.DefaultableBoolean.False;
this.grd1.DisplayLayout.Override.RowSizing = Infragistics.Win.UltraWinGrid.RowSizing.AutoFree;
this.grd1.DisplayLayout.Override.RowSizingArea = Infragistics.Win.UltraWinGrid.RowSizingArea.EntireRow;
this.grd1.DisplayLayout.Override.RowSizingAutoMaxLines = 5;
You should tell the grid that the cells are multiline cells. To do so set CellMultiLine to true like this:
this.grd1.DisplayLayout.Override.CellMultiLine = Infragistics.Win.DefaultableBoolean.True;
Here is and sample in Infragistics online documentation about this property - "Displaying Multi-Line Cells"
You can leave your settings as is, and hook to the InitializeLayout event, (like wnvko said), by double clicking over the UltraGrid in Design time, and use there the EventArgs to set the CellMultiLine to True like:
private void ultraGrid1_InitializeLayout(object sender, Infragistics.Win.UltraWinGrid.InitializeLayoutEventArgs e)
{
e.Layout.Override.CellMultiLine = Infragistics.Win.DefaultableBoolean.True;
}
Add height to your row below is property to add max height to row
this.grd1.DisplayLayout.Override.MaxRowHeight = 100;
set your required height

C# DataGridView and Input Form

I have a DataGridView binded with data from a database. I need to create a Form, which has input fields for data from a single grid row.
The Form has 30+ input controls - TextBoxes, Checkboxes and NumericUpDowns.
For now I went with this approach:
Retrieve current row from the DataGridView and load values from the cells to class instance
Pass the instance to the form and manually fill the input controls
Update the database from the form, update the DataGridView
I want to improve some things:
Is there any way to quickly fill all input controls from a class instance?
Is there any way to determine which input controls have changed their values besides manually subscribing every control on an event handler?
Is there any way to improve this whole thing, e.g. do something more efficiently?
If you are already passing in a DataRow, then you could instead pass in the DataTable and something that identifies the row in that table. And maybe optionally an adapter, if you want to commit the changes immediately on form exit. Then you can create a DataView of that table. And bind each edit control to a field in that view. Something like this:
public partial class EditForm : Form
{
DataRow row = null;
DataView view;
SqlDataAdapter adapter;
public EditForm(SqlDataAdapter adapter, DataTable table, int rowId)
{
InitializeComponent();
this.adapter = adapter;
view = table.DefaultView;
view.RowFilter = $"ID = {rowId}";
if (view.Count == 0) throw new Exception("no such row");
DataRowView dvr = view[0];
row = dvr.Row;
datebox.DataBindings.Add(new Binding("Value", view, "DATE"));
stringbox.DataBindings.Add(new Binding("Text", view, "O_STRING"));
this.FormClosing += EditForm_FormClosing;
}
private void EditForm_FormClosing(object sender, FormClosingEventArgs e)
{
if (row.RowState == DataRowState.Modified) adapter.Update(new DataRow[] { row });
}
}
The above assuming that your table has key column named ID and fields DATE and O_STRING.
This will save you the trouble of creating an intermediate custom class instance, based on that row, moving values to and from various objects and automatically sets the RowStatae in the original table.
Re: value changed indicators. Not sure if there is a really elegant way to do that. Firstly, if I had to, I would change the background (or foreground) color rather than font boldness. Setting font to bold would change the width of the content and that is usually quite annoying. Then, I would add handlers to the TextChanged events (or ValueChange events, for controls that are not text-based). You dont need to write custom handlers to each and every edit control - in the event handler, you get the object sender parameter that points to the control object. Then you can get the field name binded to that control with something like this:
private void stringbox_TextChanged(object sender, EventArgs e)
{
Control ctrl = (Control)sender;
string fieldName = ctrl.DataBindings[0].BindingMemberInfo.BindingMember;
if ((string)view[0].Row[fieldName] != ctrl.Text) ctrl.BackColor = Color.Pink;
}
That way you will only need to add a TextChanged handler once (per edit contol class), not one per every edit box you have.

Set Focus on row by cell value

I have two grid views namely PositionsReadyListGridView and PositionsNotReadyListGridView.
Now the functionality requirement is on click of Button Set Not Ready the selected item from PositionsReadyListGridView is removed from this list and added to PositionsNotReadyListGridView.
Similarly on click of Button Set Ready the selected item from PositionsNotReadyListGridView is removed from this list and added to PositionsReadyListGridView.
I have implemented this functionality but I am unable to set Focus on the latest row which is added to the either of the GridView.
Is there a way that I can set Focus to the row according to cell
values?
For example in both of the Grids I have a column colID which is unique to a row.
Can I somehow use this ID to set Focus to the row added to either PositionsReadyListGridView (on Set Ready click) or PositionsNotReadyListGridView (on Set Not Ready Click)?
Thanks
You can use LocateByValue method, which returns RowHandle of located row and set this value to FocusedRowHandle property:
int rowHandle = PositionsReadyListGridView.LocateByValue("colID", ID);
if (rowHandle != GridControl.InvalidRowHandle)
PositionsReadyListGridView.FocusedRowHandle = rowHandle
to get the lately added row get it by
PositionsReadyListGridView.Rows.Count - 1
and for setting the focus
PositionsReadyListGridView.Rows[PositionsReadyListGridView.Rows.Count - 1].Cells[colID].Selected = true;
private void PositionsNotReadyListGridView_RowsAdded(object sender, DataGridViewRowsAddedEventArgs e)
{
this.PositionsNotReadyListGridView.Rows[e.RowIndex].Selected = true;
}
for devExpress use this code :
gridView1.FocusedRowHandle = gridView1.LocateByValue("columnName",value of columnName, null);

Categories