Is there a way to get handle of row of which the selectionvalue is changed in combobox?
Let me try to explain it using example.
In GridView, I have two columns,
Name, Type
Type column has combobox, with values 1 and 2.
What I want to do is on selecting value 1 in type column ,
I want to change the Name to "One"
On selecting 2 in type column,
I want to change the Name to "Two"
This is what I was trying,
private void OnType_SelectedValueChanged(object sender, EventArgs e)
{
DevExpress.XtraEditors.ComboBoxEdit comboType = sender as DevExpress.XtraEditors.ComboBoxEdit;
DataRow row = (DataRow) myGridView.GetFocusedRow();
if (comboType .SelectedItem.ToString() == "1")
{
row.Name = "one";
}else
{
row.Name = "two";
}
}
But here I am getting myGridView.GetFocusedRow() as null.
What am I doing wrong?
Correct way is to bind a repository editor to column.
RepositoryItemComboBox riCmb = new RepositoryItemComboBox();
Handle the editvaluechanged event
riCmb.EditValueChanged += riCmb_EditValueChanged;
Then inside the event handler
if(myGridView.GetRowCellValue(myGridView.FocusedRowHandle, "FieldName").ToString() == "1")
{
grvInstruments.SetRowCellValue(grvInstruments.FocusedRowHandle, "FieldName", "One");
}
Related
I have two datagrid. DG1 and DG2 with one column A (each) and many rows. Task is to highlight a particular row in one Datagrid when user selects row with same value in another datagrid. Example: User selects DG1 row 5, column A whose value is 'ABC'. 'ABC' is row 23, column A in DG2. Hence row 23 of DG should be highlighted in 'Red'.
This should work vice-versa (Clicking row 23 of DG2 should highlight row 5 of DG1).
Currently my code works by invoking the SelectedItem property of a Datagrid. And the down side to this is that there is an infinite loop of selection i.e. when user selects row 5 of DG1 it selects row 23 of DG2 which then kicks of selection for row 5 of DG1 which then kicks of selection of row 23 of DG2.
So a solution to my problem can be either to fix this infinite loop problem or provide a way to highlight a particular row of a datagrid with a specific color thus eliminating a call to selecteditem property of a datagrid altogether.
here is some code:
//This is the function invoked when a user selects a row in a DG1
private void DG1SelectedItem(object sender, SelectionChangedEventArgs e)
{
if (DG1.SelectedItem != null)
{
var val = DG1.SelectedItem; //Get the paticular row that was selected
DataRowView row = (DataRowView)val;
object[] list = row.Row.ItemArray;
String rowValue = list[0].ToString(); //get the value within that selected row
HighLightRow(DG2, account); //Call a function that highlights a particular row in a Datagrid with a given string value
}
}
//This is the function invoked when a user selects a row in a DG2
private void DG2SelectedItem(object sender, SelectionChangedEventArgs e)
{
if (DG2.SelectedItem != null)
{
var val = DG2.SelectedItem; //Get the paticular row that was selected
DataRowView row = (DataRowView)val;
object[] list = row.Row.ItemArray;
String rowValue = list[0].ToString(); //get the value within that selected row
HighLightRow(DG1, account); //Call a function that highlights a particular row in a Datagrid with a given string value
}
}
//Function to highlight the row in datagrid 'dg' with value of 'value' (only checks first column)
private void HighLightRow(DataGrid dg, string value)
{
dg.UnselectAll();
var itemsource = dg.ItemsSource as IEnumerable;
int index = 0;
ArrayList rowIndices = new ArrayList();
//loop through entire datagrid looking for the string 'value' in the first column
//if found, store the index in an array so it can be utillized to highlight all rows later on
foreach (var item in itemsource)
{
DataRowView row = item as DataRowView;
object[] list = row.Row.ItemArray;
String valueToFind = list[0].ToString();
if (valueToFind.Equals(value))
rowIndices.Add(index);
index++;
}
//For all rows where the string 'value' was foung in the first column of the datagrid, highlight it
//Currently the implementation relies on SelectedItem
for (int i = 0; i < rowIndices.Count; i++)
{
object item = dg.Items[(int)rowIndices[i]];
dg.SelectedItem = item; //this code then invokes DG2SelectedItem (or DG1SelectedItem depending on which SelectedItem function was initially invoked) and we have the inifite loop problem
**/*
This is where I would like to select the row at the indices stored in rowIndices and highlight them red (and not rely on dg.SelectedItem like in the line above)
Something like:
dg.Row[i].Background = Brushes.Red;
*/**
int m = dg.SelectedIndex;
dg.UpdateLayout();
dg.ScrollIntoView(dg.Items[m]);
}
dg.LoadingRow += Dg_LoadingRow;
}
Writing code in the code-behind of a Window or Control is not recommended in WPF. Using MVVM approach is far superior. You should consider moving to that paradigm.
Having said that, the solution to your problem is simple. Just introduce a global variable named UpdateFlag. Set it to true at the start of each grid's handler and to false at the end of the handler. At the very beginning of each handler (before setting the flag) check if this flag is true and exit the handler immediately if that is the case. This will stop the infinite recursion of selection change.
Some thing like this:
private bool UpdateFlag = false;
private void FirstHandler()
{
if(UpdateFlag) return;
UpdateFlag = true;
//Do your highlighting here
UpdateFlag = false;
}
private void SecondHandler()
{
if(UpdateFlag) return;
UpdateFlag = true;
//Do your highlighting here
UpdateFlag = false;
}
I want when I click on datagridview row then my two text boxes and combobox fill with the corresponding values but two text boxes fill accurately but category dropdown is not filling.
My C# code is
private void dataGridView1_CellClick(object sender, DataGridViewCellEventArgs e)
{
if (e.RowIndex != -1 && e.ColumnIndex !=-1)
{
//edit = 1;
DataGridViewRow row = dataGridView1.Rows[e.RowIndex];
proID = Convert.ToInt32(row.Cells["proIDGV"].Value.ToString());
proTxt.Text = row.Cells["nameGV"].Value.ToString();
barcodetxt.Text = row.Cells["barcodeGV"].Value.ToString();
catDD.SelectedValue = row.Cells["catIDGV"].Value.ToString();// not working properly due to which edit button is not working
// catDD.SelectedItem = row.Cells["catGV"].Value.ToString();//Also Write this line of code but not produce the desire result
MainClass.Disabled(leftPanel);
}
}
For category dropdown, which is a combo-box, to have a SelectedItem or SelectedValue you should already have all the possible categories in the "items" property, otherwise, the programming cannot select the category out of nowhere. To select items which don't exist you need to add an item first, or if you don't really need the items afterward you can just use:
catDD.Text = row.Cells["catIDGV"].Value.ToString();
Although I would not recommend doing it this way.
The other way is that you can add items by doing this (this is what I recommend):
Edit: You first add the item then select it.
string item = row.Cells["catIDGV"].Value.ToString(); // Your selected item in DataGridView
catDD.Items.Add(item); // Add the item
catDD.SelectedItem = item; // Select the item
I have a User Control with an Ultragrid. In a particular form where I add a ValueList. The value list will not show for the particular column I'm interested in. If I then code in another column instead by changing the index value for columns I get the value list in the column.
The code looks like:
private void AddCombo(object sender, UcUltraGen.RowClickArgs e)
{
ValueList vl;
if (!ucUltraGridMain.Grid.DisplayLayout.ValueLists.Exists("Texas"))
{
vl = ucUltraGridMain.Grid.DisplayLayout.ValueLists.Add("Texas");
}
else
{
vl = ucUltraGridMain.Grid.DisplayLayout.ValueLists["Texas"];
}
var row = e.VariantRow;
List<PcBase> list = PcBase.PcBaseList.Where(x => x.VariantId == row.Cells["Id"].Text).ToList();
AddValueList(list, vl);
ucUltraGridMain.Grid.DisplayLayout.Bands[0].Columns[1].ValueList =
ucUltraGridMain.Grid.DisplayLayout.ValueLists["Texas"];
And if I change to
...
ucUltraGridMain.Grid.DisplayLayout.Bands[0].Columns[2]
It works. How can I have changed the behavior of columns[1]?
The property in column[1] was read only that is it only had a "get" implemented. By adding a set it worked. Hope this helps someone.
This is my code:
DataGridViewComboBoxColumn col = new DataGridViewComboBoxColumn();
col.ValueMember = "Value";
col.DisplayMember = "Name";
col.DataSource = lstParameterDataSource;
//lstParameterDataSource is lst like List<BindEntity>.
The BindEntity is a class which has two property. One property is Value, and the other one is Name. Both of them are string type.
this.dgvCondition.RowsAdded += delegate(object sender, DataGridViewRowsAddedEventArgs args)
{
if (this._parameters != null && this._parameters.Count > 0)
{
DataGridViewComboBoxCell cell = this.dgvCondition.Rows[args.RowIndex].Cells[0] as DataGridViewComboBoxCell;
cell.Value = lstParameterDataSource[0].Value;
}
};
dgvCondition is my datagridview which user will be edited. In addition I handle the event RowsAdded of gvCondition so that display a default value in datagridview when user adding a new row.
When I add this col to my dgvCondition, and then add a row on it. It always show a empty cell except I select a value by myself. I tried to debug this app, and I found that code cell.Value = lstParameterDataSource[0].Value; didn't work. The cell's Value is always null.
What is going on? I want it show a default value when UI show. How can I implement this function?
You can use this,
((DataGridViewComboBoxCell)(this.dgvCondition.Rows[args.RowIndex].Cells[0])).Value= lstParameterDataSource[0].Value;
let me know if u help this.
I have a datagridview which I fill it as below :
var q= repository.GetStudents();//
dataGridView1.DataSource = null;
dataGridView1.Columns.Clear();
dataGridView1.DataSource = q;
dataGridView1.Columns.RemoveAt(1);
//Remove IsActive
//Cause I want to have my own implementation
dataGridView1.Columns[0].DataPropertyName = "StudentID";
dataGridView1.Columns[0].HeaderText = "Studunet ID";
dataGridView1.Columns[1].DataPropertyName = "IsActive";
dataGridView1.Columns[1].HeaderText = "Status";
The "IsActive" property is of boolean Type. When the "IsActive" cell is being displayed, it show true/false. I want to replace it with my own custom value.
I read this and this posts but I could not resolve my problem.
You can use the CellFormatting event of the DataGridView, e.g.:
void dataGridView_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
{
var grid = (DataGridView)sender;
if (grid.Columns[e.ColumnIndex].Name == "IsActive")
{
e.Value = (bool)e.Value ? "MY_TEXT_FOR_TRUE" : "MY_TEXT_FOR_FALSE";
e.FormattingApplied = true;
}
}
EDIT (as per comment):
It's very similar to what you're doing now, just remove the bound column and add a new column of the desired type and set the DataPropertyName properly e.g. :
this.dataGridView1.Columns.Remove("COL_TO_CUSTOMIZE");
var btnCol = new DataGridViewDisableButtonColumn();
btnCol.Name = "COL_TO_CUSTOMIZE";
btnCol.DataPropertyName = "COL_TO_CUSTOMIZE";
var col = this.dataGridView1.Columns.Add(btnCol);
Note that this append the column at the end, but you can decide the position of the column by using dataGridView.Columns.Insert method instead of Add.
One of the funky things about a DataGridViewComboBoxColumn is that you can give it one data source that has a column of values to lookup and a column of values to show, and you can bind it to another column of values and then it will perform the lookup for you
So, suppose your collection q of Students (or whatever they are) has an IsActive true/false and you want this to show as "All the time", or "Not a chance".. Let's hash together a combobox that does this:
var cb = new DataGridViewComboBoxColumn();
cb.DisplayMember = "DisplayMe"; //the related text to show in the combo
cb.ValueMember = "ValueToLookup"; //the name in the combo's lookup list
cb.DataPropertyName = "IsActive"; //the name of your property on Student, to look up
cb.DataSource = "All the time,Not a Chance"
.Split(',')
.Select(s => new { DisplayMe = s, ValueToLookup = (s[0] == 'A') } )
.ToList();
It doesn't really matter how we generat the combo's datasource; here I've made a string into a List<anonymous_string+bool> by splitting, then selecting a new anonymous type with the two property names I need; you can use anything that has some named properties - a List of KeyValuePair, Tuple, whatever..
The critical thing is that the combo can read the q.IsActive bool you cited in DataPropertyName, look that bool up in its list in the property named in the ValueMember, then display the property named in the DisplayMember. It works for editing too, so the user can choose a new item from the combo and the translation works back the other way - "what does the user choose? what is the value of its property named in ValueMember, put that value into the student IsActive property named in DataPropertyName".. And it doesnt stop at bools either; the value member can be anything - an int, date etc