get repositoryItemGridLookupEdit parent's currentrow processed - c#

I have a Gridview and a RepositoryItemGridLookUpEdit in that GridView
I want to show a CustomDisplayText in the RepositoryItemGridLookUpEdit
private void rgluePerson_CustomDisplayText(object sender, DevExpress.XtraEditors.Controls.CustomDisplayTextEventArgs e)
{
var person = rgluePerson.GetRowByKeyValue(e.Value) as Person;
var name = person.Name;
var surname = person.Surname;
e.DisplayText = name + ", " + surname;
}
}
The problem is that the person name depends of another cell in the same row (in the main Gridview), and i don't know how to get the current's Gridview row being processed (current row doesn't work since i need the row being processed in the moment)...... i can't use a gridView event cuz it will change the cell value, but i want to change the Text value.
Does anyone knows how to do that?

You cannot get the row being processed by the CustomDisplayText event because there are no such fields or properties that contains current row. You can only use this event for focused row. For this your must check if sender is type of GridLookUpEdit:
private void rgluePerson_CustomDisplayText(object sender, CustomDisplayTextEventArgs e)
{
if (!(sender is GridLookUpEdit))
return;
var anotherCellValue = gridView1.GetFocusedRowCellValue("AnotherCellFieldName");
//Your code here
e.DisplayText = yourDisplayText;
}
For not focused rows you can use only ColumnView.CustomColumnDisplayText event:
private void gridView1_CustomColumnDisplayText(object sender, CustomColumnDisplayTextEventArgs e)
{
if (e.Column.ColumnEdit != rgluePerson)
return;
var anotherCellValue = gridView1.GetListSourceRowCellValue(e.ListSourceRowIndex, "AnotherCellFieldName");
//Your code here
e.DisplayText = yourDisplayText;
}

Related

Winforms DataGridView is adding two rows instead of one

When I add data to a row in my DataGridView I want a blank row to be added. This occurs but when I focus on a field in the current row and enter no data, default values are populated for that row and the new row is populated with the default values as well. Then another blank row is added as you can see from the animated gif I pasted below.
I wanted to see if anyone could help me determine what to do to prevent the blank row from being populated with default values as well as the current row. After leaving a field in the current row and not entering a value, it's okay for default values to populate that row but I don't want anything to populate the blank row.
I have pasted relevant code from the form class below. I tried to eliminate parts of the class that were not relevant to the question:
public partial class frmCharitableContributions : Form
{
private readonly string connectionString = ConnectionStringProvider.GetConnectionString();
private readonly BusinessLayer bl = new BusinessLayer();
private void FrmCharitableContributions_Load(object sender, EventArgs e)
{
PopulateDataGridView();
}
private void PopulateDataGridView()
{
try
{
DataSet dsCharitableContributions = bl.GetCharitableContributions(connectionString);
CharitableContributionsDataGridView.DataSource = dsCharitableContributions.Tables[0];
}
catch (Exception ex)
{
MessageBox.Show("Exception Thrown in PopulateDataGridView: " + ex.Message);
}
}
private void CharitableContributionsDataGridView_CellValueChanged(object sender, DataGridViewCellEventArgs e)
{
if (CharitableContributionsDataGridView.CurrentRow != null)
{
DataGridViewRow dgvRow = CharitableContributionsDataGridView.CurrentRow;
bool isValid = ValidateFields(dgvRow);
if (isValid)
{
bl.InsertOrUpdateCharitableContributions(connectionString, dgvRow);
}
else
{
return;
}
BeginInvoke(new MethodInvoker(PopulateDataGridView));
}
}
// This event will fire when a cell recognize editing
private void CharitableContributionsDataGridView_CellBeginEdit(object sender, DataGridViewCellCancelEventArgs e)
{
CharitableContributionsDataGridView.AllowUserToAddRows = false;
}
// This event will fire when a cell recognizes the end of editing
// Allow or deny adding a new row here based on conditions such as required fields being filled in or selected
private void CharitableContributionsDataGridView_CellEndEdit(object sender, DataGridViewCellEventArgs e)
{
int currentRowIndex = e.RowIndex;
DataGridViewRow dgvRow = CharitableContributionsDataGridView.Rows[currentRowIndex];
if (dgvRow.Cells["cbxCharitableOrganizationName"].Value.ToString() != "")
{
if (CharitableContributionsDataGridView.CurrentRow != null)
{
bl.InsertOrUpdateCharitableContributions(connectionString, dgvRow);
CharitableContributionsDataGridView.AllowUserToAddRows = true;
}
}
}
}

How to show grid row value in textBox on SelectionChanged event C#?

I have to show the grid selected row value into textboxes.I'm using this code, but it's not working. Any help will be appreciated.
private void CRUD_SelectionChanged(object sender, EventArgs e)
{
txtBoxID.Text = CRUD.SelectedRows[0].Cells[0].Value.ToString();
txtBoxStates.Text = CRUD.SelectedRows[1].Cells[1].Value.ToString();
txtBoxName.Text = CRUD.SelectedRows[2].Cells[2].Value.ToString();
txtBoxAddress.Text = CRUD.SelectedRows[3].Cells[3].Value.ToString();
txtBoxCenter.Text = CRUD.SelectedRows[4].Cells[4].Value.ToString();
txtBoxCity.Text = CRUD.SelectedRows[5].Cells[5].Value.ToString();
}
You're indexing your selected rows. if you have less than 6 selected rows, then you will go out of bounds. You probably want to fetch data from only one row. Check if only one row is selected and then use index 0. Make sure you set CRUD.MultiSelect = false
Alternatively use CRUD.CurrentRow which will only ever get you one row.
Form.Designer.cs:
this.CRUD.SelectionChanged += new System.EventHandler(this.CRUD_SelectionChanged);
Form.cs:
private void CRUD_SelectionChanged(object sender, EventArgs e)
{
txtBoxID.Text = CRUD.CurrentRow.Cells[0].Value.ToString();
txtBoxStates.Text = CRUD.CurrentRow.Cells[1].Value.ToString();
txtBoxName.Text = CRUD.CurrentRow.Cells[2].Value.ToString();
txtBoxAddress.Text = CRUD.CurrentRow.Cells[3].Value.ToString();
txtBoxCenter.Text = CRUD.CurrentRow.Cells[4].Value.ToString();
txtBoxCity.Text = CRUD.CurrentRow.Cells[5].Value.ToString();
}

dataGridView change cell datasource and type

After I click a particular row and I click a button, I want to change the cell type from default type (DataGridViewTextBoxCell) to DataGridViewComboBoxCell and to change that cell data source to a list.
Somehow I encountered an unexplained behavior, In one line it works and shows the ComboBox, in other, it just enters to edit mode.
My code looks something like this:
private void btnClick(object sender, EventArgs e)
{
dataGridView.BeginEdit(true);
var selectedRow = CurrentCell.RowIndex;
var selectedColumn = CurrentCell.ColumnIndex;
var cellName = dataGridView[0, _selectedCell.RowIndex].Value.ToString();
var dict = GetDict(cellName);
if (dict != null)
{
var comboBoxCell = new DataGridViewComboBoxCell
{
DataSource = dict.Keys.ToList()
}
dataGridView[1, selectedRow] = comboBoxCell;
dataGridView.CurrentCell = dataGridView.Rows[selectedRow].Cells[selectedColumn];
}
dataGridView.BeginEdit(false);
}
Update: It seems only after the event CellBeginEdit is fired, which is caused by pressing other cell it updates, But then it takes like 3-4 click for the ComboBox to open.
Try This Code. You should override CellClick Event or Call You Method There. This code is written in CellClick Event, Don't get confused with Name
//This Code is written in CellClick Event not in CellContentClick (Don'tconfuse with signature)
private void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
dataGridView1.BeginEdit(true);
var selectedRow = (sender as DataGridView).CurrentCell.RowIndex;
var selectedColumn = (sender as DataGridView).CurrentCell.ColumnIndex;
var comboBoxCell = new DataGridViewComboBoxCell
{
};
dataGridView1.CurrentCell = dataGridView1.CurrentCell as DataGridViewComboBoxCell;
dataGridView1[selectedColumn, selectedRow] = comboBoxCell;
dataGridView1.CurrentCell = dataGridView1.Rows[selectedRow].Cells[selectedColumn];
dataGridView1.BeginEdit(false);
}

C# Binding Source Control

I am Developing a winforms application. I have two datagrid views populated from two different bindingsources(control). I am using these to implement the master detail approach. My problem is that when the first datagridview is populated using the binding source I can't select the first row of it ,because the first element in the binding source is defaultly selected and can't be selected. Can any one provide me a solution for this
As you say the first row is selected by default. So after populating the DataSource to your first GridView you can set the second GridView based on first entry. Later you check the selectionChanged Event to populate the second GridView based on selectedRow of your first one.
Code could look sth. like this:
private void PopulateDataSource()
{
dataGridView1.DataSource = myBindingSource;
DataRowView selectedRow;
if (dataGridView1.SelectedRows.Count > 0)
selectedRow = dataGridView1.SelectedRows[0] as DataRowView;
if (selectedRow != null)
dataGridView2.DataSource = myBindingSource2; //Set the BindingSource based on selectedRow in first Grid
}
private void dataGridView1_SelectionChanged(object sender, EventArgs e)
{
DataRowView selectedRow;
if (dataGridView1.SelectedRows.Count > 0)
selectedRow = dataGridView1.SelectedRows[0] as DataRowView;
if (selectedRow != null)
dataGridView2.DataSource = myBindingSource2; //Set the BindingSource based on selectedRow in first Grid
}
If this doesn't work let me know but should do the job.
UDPATE
Here is a similar example using the events and methods of the bindingSource:
private void Initialize()
{
RegisterBindingSourceEvents();
dataGridView1.DataSource = bindingSource1;
dataGridView2.DataSource = bindingSource2;
bindingSource1.DataSource = myDataSource;
}
private void RegisterBindingSourceEvents()
{
bindingSource1.DataSourceChanged += BindingSource1_DataSourceChanged;
bindingSource1.CurrentChanged += BindingSource1_CurrentChanged;
}
private void BindingSource1_CurrentChanged(object sender, EventArgs e)
{
DataRowView row = bindingSource1.Current as DataRowView;
if (row != null)
bindingSource2.DataSource = myDataSource2BasedOnRow;
}
private void BindingSource1_DataSourceChanged(object sender, EventArgs e)
{
DataRowView row = bindingSource1.Current as DataRowView;
if (row != null)
bindingSource2.DataSource = myDataSource2BasedOnRow;
}
Further you maybe can use:
bindingSource.MoveNext();
bindingSource.MoveFirst();
To simulate focusing seconde row and directly first row. A bit ugly but i would guess this fires current_changed (untested). Better use first approach.
UDPATE-2
I'm sorry to tell you that this is not possible in a beautiful manner. The problem is that the Current Property of your bindingList is always set if your DataSource contains items. So if the user select the same row as the bindingSource Current Property contains your event won't get called. I found a solution which works in my example. You will need one gridEvent and maybe have to do some improvments but the idea should do the job. Sorry but without gridEvent i can't solve this:
Notice that iam using List as DataSource for my Testcase. You got DataTable and have to cast to DataRowView instead of Dummy for sure.
private bool _automatedRowChange;
private void Initialize()
{
List<Dummy> dummies = new List<Dummy> { new Dummy { Id = 1, Text = "Test1" }, new Dummy { Id = 2, Text = "Test2" } };
bindingSource1.DataSource = dummies;
dataGridView1.DataSource = bindingSource1;
//So the first row isn't focused but the bindingSource Current Property still holds the first entry
//That's why it won't fire currentChange even if you click the first row. Just looks better for the user i guess
dataGridView1.ClearSelection();
bindingSource1.CurrentChanged += BindingSource1_CurrentChanged;
dataGridView1.CellClick += DataGridView1_CellClick;
}
private void DataGridView1_CellClick(object sender, DataGridViewCellEventArgs e)
{
var clickedRow = dataGridView1.Rows[e.RowIndex].DataBoundItem as Dummy;
var currentRow = bindingSource1.Current as Dummy;
if (clickedRow != null &&
currentRow != null &&
clickedRow.Equals(currentRow))
{
_automatedRowChange = true;
bindingSource1.MoveNext();
_automatedRowChange = false; //MovePrevious is based on the click and should load the dataSource2
bindingSource1.MovePrevious();
}
}
private void BindingSource1_CurrentChanged(object sender, EventArgs e)
{
if (!_automatedRowChange) //Check if you jump to next item automatically so you don't load dataSource2 in this case
{
//Set the second DataSource based on selectedRow
}
}

How to access DataGrid column value

I have an autogenerated DataGridand I want to retrieve the ID value. There is a HyperLink button on each row and I want to send the value of that row's ID to a new page via query string. The order of ProductGrid is as follows
(HyperLinkButton,ID,Name,Details).
This is how I am binding the Grid:
public void webService_GetProductsCompleted(object sender, ServiceReference1.GetProductsCompletedEventArgs e)
{
ProductGrid.ItemsSource = e.Result;
ProductGrid.Visibility = Visibility.Visible;
}
And this is the HyperLink button click event where I tried retreiving the cell value but got null(commented)
private void HyperlinkButton_Click_1(object sender, RoutedEventArgs e)
{
//string var = ProductGrid.Columns[1].GetCellContent(ProductGrid.SelectedItem).ToString();
this.NavigationService.Navigate(new Uri("/Home?", UriKind.Relative));
}
Can somebody help me in finding out how can I send my cell value in a query string?
You can use RowCommand event or try this way.
private void HyperlinkButton_Click_1(object sender, RoutedEventArgs e)
{
LinkButton lnkbtn= sender as LinkButton;
//getting particular row linkbutton
GridViewRow grow = lnkbtn.NamingContainer as GridViewRow;
//getting userid of particular row
string prodid = ProductGrid.DataKeys[gvrow.RowIndex].Value.ToString();
string prodname = grow.Cells[0].Text;
}

Categories

Resources