I have a function that sets column values for all rows:
The code that sets this:
//Update the engineers for all rows
Btn_ValidateClick_ItemClick(object sender,ItemClickEventArgs e)
{
UpdateTotalTime(gridView);
}
private void UpdateEngineers(DevExpress.XtraGrid.Views.Base.ColumnView View)
{
//Column name that need to be updated (set)
DevExpress.XtraGrid.Columns.GridColumn col = View.Columns.ColumnByFieldName("Engineers");
try
{
int dataRowCount = View.DataRowCount;
for (int i = 0; i < dataRowCount; i++)
{
GridView detail = (GridView)gridView.GetDetailView(i, 0);
string language = gridView.GetRowCellValue(i, "Language").ToString();
for (int y = 0; y < gridView.GetDetailView(i, 0).RowCount; y++)
{
//Add all values found in a detail column to an arraylist
values.Add(detail.GetRowCellValue(y, "EngineerInitials").ToString());
}
if (values.Count >0 )
object t = //string join ...
View.SetRowCellValue(i, col, t);
}
else
{
object t = "No engineers"
View.SetRowCellValue(i, col, t);
}
}
}
}
}
The problem is that now, I want it only to set it for the rows that are selected.
I tried using the .GetSelectedRows()-function and adding the rows to an ArrayList, but this doesn't allow customability really:
private void UpdateTotalTime(DevExpress.XtraGrid.Views.Base.ColumnView View)
{
ArrayList selectedRows = new ArrayList();
for (int i = 0; i < gridView.SelectedRowsCount; i++)
{
if (gridView.GetSelectedRows()[i] >= 0)
selectedRows.Add(gridView.GetDataRow(gridView.GetSelectedRows()[i]));
}
try
{
int count = View.GetSelectedRows().Count();
for (int i = 0; i < selectedRows.Count; i++)
{
//This gets the first row of the count, not the first selected row
GridView detail = (GridView)gridView.GetDetailView(i,0);
}
}
If I select the 3 bottom rows, the first 3 get updated. Why is this?
You are adding all the selected rows to your selectedRows ArrayList. But after that, you are not using it for anything.
I guess what you want (I've never used devexpress controls) is using those selectedrows RowHandle to pass it to the GetDetailView method. According to the GetSelectedRows documentation, the method returns the int handles of the selected rows, so your code should look like this:
First, you must save the DataRow handles, not the DataRow itself, so you must change in your code this line:
selectedRows.Add(gridView.GetDataRow(gridView.GetSelectedRows()[i]));
into this:
selectedRows.Add(gridView.GetSelectedRows()[i]);
And then, change your loop into this:
for (int i = 0; i < selectedRows.Count; i++)
{
int rowHandle = (int)selectedRows[i];
GridView detail = (GridView)gridView.GetDetailView(rowHandle,0);
}
In fact, you could do everything in just one loop:
private void UpdateTotalTime(DevExpress.XtraGrid.Views.Base.ColumnView View)
{
for (int i = 0; i < gridView.SelectedRowsCount; i++)
{
int rowHandle = gridView.GetSelectedRows()[i];
GridView detail = (GridView)gridView.GetDetailView(rowHandle,0);
}
}
Related
I have following code to remove the summary row/band value on a retrieve UI event. I'm certain this is the wrong way to do it but it works.
public UiEventResult AfterRetrieveData_111(object sender, RetrieveDataEventArgs e)
{
UltraGridBase baseGrid = _view.ViewGrids["ultraGrid1"];
UltraGridLayout gridLayout = baseGrid.DisplayLayout;
for (int i = 0; i < 2; i++)
{
gridLayout.Bands[i].Columns["columnA"].Formula = "''";
}
for (int i = 0; i < 3; i++)
{
gridLayout.Bands[i].Columns["columnB"].Formula = "''";
gridLayout.Bands[i].Columns["columnC"].Formula = "''";
}
Is there a way to program the retrieve so that it populates the summary row for column A/band[2] so that is uses the last value in each column? Without the above code it will sum rows under but would like for a way for it to use the last row value instead. Data will always be sorted DESC by date so last row will always be the value needed...
One way to achieve this is in InitializeRowEvent by setting the value of the columnA to the value of the last row in the child band like this:
// Update the rows only in the first band. You can also use e.Row.Band.Key == {YOU_BAND_KEY}
if (e.Row.Band.Index == 0)
{
// set the value of the columnA to the value of the last row in the child band
e.Row.Cells["columnA"].Value = e.Row.ChildBands.LastRow.Cells["columnA"].Value;
}
Note, this will not work if you edit the cells values. If you need to update the parent row value after cell update, again in InitializeRowEvent you can add this:
// look for row in the secon band
if (e.Row.Band.Index == 1)
{
// get the last row in the second band
if (e.Row == e.Row.ParentRow.ChildBands.LastRow)
{
// get the value of the last row in the second band and set it to the parent row
e.Row.ParentRow.Cells["columnA"].Value = e.Row.Cells["columnA"].Value;
}
}
This will loop through ChildBands and set parent row value with the last value in each ChildBand.
int rowCount = gridLayout.Rows.Count;
for (int i = 0; i < rowCount; i++)
{
foreach (UltraGridChildBand childBand in baseGrid.Rows[i].ChildBands)
{
foreach (UltraGridRow row in childBand.Rows)
{
row.Cells["columnA"].Value =row.ChildBands.LastRow.Cells["columnA"].Value;
}
}
}
I am trying to insert a sound whenever there is a match in my game. However, I keep getting a NullReferenceException when I get the match. It goes to the line soundEffectInstance.Play();. Any help is greatly appreciated. I've attempted everything when trying to get it to work. Here is my code:
using System.Collections.Generic;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
namespace AndyKlax.KlaxGame
{
internal class Grid
{
private const int GridOrigin = 660;
SoundEffect soundEffect;
SoundEffectInstance soundEffectInstance;
private readonly List<Block>[] _grid = new List<Block>[Klax.NumberOfColumns];
public void LoadContent(ContentManager content)
{
soundEffect = content.Load<SoundEffect>(#"Sounds/24372^pop2.mp3");
soundEffectInstance = soundEffect.CreateInstance();
}
internal Grid()
{
for (int i = 0; i < Klax.NumberOfColumns; i++ )
{
_grid[i] = new List<Block>();
}
}
private bool RemoveBlocks()
{
var foundBlocksToRemove = false;
//Mark all blocks in the grid as unmatched
for (int column = 0; column < Klax.NumberOfColumns; column++)
{
for (int row =_grid[column].Count -1 ; row >=0 ; row--) //Loop backwards do its safe to remove
{
if (_grid[column][row].Delete)
{
_grid[column].RemoveAt(row);
foundBlocksToRemove = true;
}
}
}
return foundBlocksToRemove;
}
private void SearchForMatches()
{
//Search the whole grid - look for matches in each direction and set the deleted flag for anything you find
for (int column = 0; column < Klax.NumberOfColumns; column++)
{
for (int row = 0; row < _grid[column].Count; row++)
{
SearchForMatches(column, row, 1, 0); //Horizontal
SearchForMatches(column, row, 0, 1); //Vertical
SearchForMatches(column, row, 1, 1); //Diagonal one way
SearchForMatches(column, row, 1, -1); //Diagonal the other way
}
}
}
private void SearchForMatches(int column, int row, int xStep, int yStep)
{
int startColorIndex = _grid[column][row].ColorIndex;
int matchCount = 0;
int x = column;
int y = row;
//Loop in the given direction till we run out of color or grid
do
{
matchCount++;
x += xStep;
y += yStep;
} while (x < Klax.NumberOfColumns && y < _grid[x].Count && y>0 && startColorIndex == _grid[x][y].ColorIndex);
//If the match is long enough
if (matchCount >= 3)
{
//Then mark all those blocks for removal
x = column;
y = row;
//Loop in the given direction till we run out of color or grid
do
{
_grid[x][y].Delete = true;
x += xStep;
y += yStep;
soundEffectInstance.Play();
} while (x < Klax.NumberOfColumns && y < _grid[x].Count && startColorIndex == _grid[x][y].ColorIndex);
}
}
private void ResetDeleteFlags()
{
//Mark all blocks in the grid as unmatched
for (int column = 0; column < Klax.NumberOfColumns; column++)
{
for (int row = 0; row < _grid[column].Count; row++)
{
_grid[column][row].Delete = false;
}
}
}
internal void Draw(SpriteBatch spriteBatch)
{
//Like the paddle the position of the block is inferred by its position in the grid
spriteBatch.Begin();
for (int column = 0; column < Klax.NumberOfColumns; column++)
{
for (int row = 0; row < _grid[column].Count; row++)
{
_grid[column][row].Draw(spriteBatch, column, GridOrigin - row * Klax.Texture.Height);
}
}
spriteBatch.End();
}
internal void Add(int column, Block block)
{
_grid[column].Add(block);
//Search for matches
do
{
ResetDeleteFlags();
SearchForMatches(); //Look for matches and mark their deleted flag
} while (RemoveBlocks()); //If we removed any then iterate again as there may be new matches
}
public bool HasSpace(int column)
{
//Is there room in this column
return _grid[column].Count < Klax.NumberOfRows;
}
}
}
From what I'm seeing in your code you are using ContentManager.Load from the Microsoft.Xna.Framework framework.
Under this assumption your code probably won't ever work and always will return null.
The problem here is twofold:
ContentManager.Load supports only specific types as given by its definition (I'll post a link further below). SoundEffects are not part of these types
This load method thinks that all files given have no extension by themselves but instead have an ungiven .xnb extension (and are of the xnb format).
Thus your Sounds/24372^pop2.mp3 translates to Sounds/24372^pop2.mp3.xnb for it.
One example directly from the documentation how it is used:
Model model = contentManager.Load<Model>( ".\\content\\models\\box" );
This would load box.xnb as a model.
The full documentation for that method is here:
https://msdn.microsoft.com/en-us/library/bb197848.aspx
Like I mentioned if my assumption that you are using THAT method is correct then it is clear why the loading fails with that as it is looking for a file that does not exist. But even if that is corrected according to the documentation it should still not work as it is not of a supported type (I find it strange though that the method does not throw an exception when you try to use it to load something not supported but that developer oversight has nothing to do with your problem at all in essence).
I am trying to output the cell values of a data grid to an XML . The cells of the grid are combobox cells with values ALLOCATED, AVAILABLE, OCCUPIED. My xml output needs to be of the form as stated below: (where status is the selected value from the combo box of each cell and Xloc is the row index , YLoc is the column index of that particular cell)
<Cell XLoc="1" YLoc="1" Status="AVAILABLE"/>
<Cell XLoc="1" YLoc="2" Status="OCCUPIED"/>
<Cell XLoc="1" YLoc="3" Status="OCCUPIED"/>
Currently I am creating a list and saving the combox selected values from the grid ie., AVAILABLE, OCCUPIED....
private List<string> Grid_Values()
{
List<string> CellValues = new List<string>();
for (int i = 0; i < ToolMapGrid.Rows.Count; i++)
{
for (int j = 0; j < ToolMapGrid.ColumnCount; j++)
{
CellValues.Add(ToolMapGrid.Rows[i].Cells[j].Value.ToString());
}
}
...
}
I am writing the above values to XML in this way :
List<string> GridValues = Grid_Values();
foreach (string item in GridValues)
{
writer.WriteStartElement("Cell");
writer.WriteAttributeString("Status",item);
writer.WriteEndElement();
}
I dont understand how do I write Xloc and Yloc values to the XML file. I am returning the combo values as a list but how do I make the same method also return the row and column indexes and how do I write it to the XML file.
Please help me. Thanks in advance
Create a new class called XmlInfo which has three properties, like this:
class XmlInfo
{
string value{get; set;}
int column {get: set;}
int row {get; set; }
}
After that change your code like this:
private List<XmlInfo> Grid_Values()
{
List<XmlInfo> CellValues = new List<XmlInfo>();
for (int i = 0; i < ToolMapGrid.Rows.Count; i++)
{
for (int j = 0; j < ToolMapGrid.ColumnCount; j++)
{
XmlInfo nfo = new XmlInfo {
value = ToolMapGrid.Rows[i].Cells[j].Value.ToString(),
row = i,
column = j}
CellValues.Add(nfo);
}
}
}
Then you can use the code like this:
List<XmlInfo> GridValues = Grid_Values();
foreach (XmlInfo item in GridValues)
{
writer.WriteStartElement("Cell");
writer.WriteAttributeString("Status", item.value);
writer.WriteAttributeString("XLoc", item.column);
writer.WriteAttributeString("YLoc", item.row);
writer.WriteEndElement();
}
You might want to review this for syntax errors, as I typed it directly into the editor and I might have missed something.
This is how I implemented and it worked :)
for (int i = 0; i < ToolMapGrid.Rows.Count; i++)
{
for (int j = 0; j < ToolMapGrid.ColumnCount; j++)
{
writer.WriteStartElement("Cell");
writer.WriteAttributeString("XlOC", (i + 1).ToString());
writer.WriteAttributeString("YLOC", (j + 1).ToString());
writer.WriteAttributeString("Status", ToolMapGrid.Rows[i].Cells[j].Value.ToString());
writer.WriteEndElement();
}
}
I have been saving into the ComboBox a value out of the selected column in datagridview with below code.
My question is:How can I prevent duplicate records when I save the values into the ComboBox? How can I do that?
Code:
int ColumnIndex = dgUretimListesi.CurrentCell.ColumnIndex;
CmbAra.Text = "";
for (int i = 0; i < dgUretimListesi.Rows.Count; i++)
{
CmbAra.Items.Add(dgUretimListesi.Rows.Cells[ColumnIndex].Value.ToString());
}
Please try this
private void dgvServerList_CellEndEdit(object sender, DataGridViewCellEventArgs e)
{
try
{
if (e.ColumnIndex == 1)
{
string id = dgvServerList[e.ColumnIndex, e.RowIndex].Value.ToString();
int duplicaterow = 0;
for (int row = 0; row < dgvServerList.Rows.Count; row++)
{
if (row != e.RowIndex && id == dgvServerList[e.ColumnIndex, row].Value.ToString())
{
duplicaterow = row + 1;
MessageBox.Show("Duplicate found in the row: " + duplicaterow);
this.dgvServerList[e.ColumnIndex, e.RowIndex].Value = "";
break;
}
}
}
}
catch
{
}
}
you could first transfer your datagridview items to a dictionary (which guarantees uniqueness) and then transfer that dictionary content to the combobox. or you could check for uniqueness yourself using a 'Contains' method on the combobox. you could even tie the dictionary to the combobox as a source for the combobox items.
Dictionary<string,bool> d = new Dictionary<string,bool>();
int ColumnIndex = dgUretimListesi.CurrentCell.ColumnIndex;
CmbAra.Text = "";
for (int i = 0; i < dgUretimListesi.Rows.Count; i++)
{
d[dgUretimListesi.Rows.Cells[ColumnIndex].Value.ToString()] = true;
}
CmbAra.Items.AddRange(d.Keys);
Use a set:
int ColumnIndex = dgUretimListesi.CurrentCell.ColumnIndex;
CmbAra.Text = "";
HashSet<string> set = new HashSet<string>();
for (int i = 0; i < dgUretimListesi.Rows.Count; i++)
{
string s = dgUretimListesi.Rows.Cells[ColumnIndex].Value.ToString();
if(!set.Contains(s)) {
CmbAra.Items.Add(s);
set.Add(s);
}
}
by using the following check and then determine to add or not
if(CmbAra.Items.Contains(dgUretimListesi.Rows.Cells[ColumnIndex].Value.ToString()))
You can use the following code part.
if(!(CmbAra.Items.Contains(dgUretimListesi.Rows.Cells[ColumnIndex].Value.ToString())))
{
CmbAra.Items.Add(dgUretimListesi.Rows.Cells[ColumnIndex].Value.ToString());
}
else
{
MessageBox.Show("Value Already exists , not added");
}
I am binding the data in a data table from two different datagrid
protected ICollection BindGenerateReport()
{
DataTable dtGenerateReport = new DataTable();
DataRow drRow;
for (int innerCounter = 0; innerCounter < dgInvoices.Columns.Count; innerCounter++)
{
dtGenerateReport.Columns.Add();
}
for (int counter = 0; counter < dgInvoices.Items.Count+dgReceipts.Items.Count;counter++ )
{
drRow = dtGenerateReport.NewRow();
if (dgReceipts.Columns[6] == dgInvoices.Columns[1])
{
for (int innerCounter = 0; innerCounter < dgReceipts.Columns.Count; innerCounter++)
{
drRow[innerCounter] = dgReceipts.Columns[innerCounter];
}
}
else
{
for (int innerCounter = 0; innerCounter < dgInvoices.Columns.Count; innerCounter++)
{
drRow[innerCounter] = dgInvoices.Columns[innerCounter];
}
}
dtGenerateReport.Rows.Add(drRow);
}
DataView dv = new DataView(dtGenerateReport);
return dv;
}
and i am binind the function a event click like that
protected void btnGenerateReport_Click(object sender, EventArgs e)
{
dgGenerateReport.DataSource = BindGenerateReport();
dgGenerateReport.DataBind();
}
but i want to know that what exactlu datagrid.columns[number] returns (the value inside that column or the datatype or only the column collection ).My code is not working
The columns collection will return an instance of a type derived from DataGridColumn, this could be a BoundColumn, ButtonColumn etc.
Check the MSDN Article for more information.