How to set column ticked from other column - c#

How can I set a value into gridview column? The thing is the column was added manually, not from the database. What I want is when the checklist value was 1 the cek22 column got ticked and when value was 0 the cek22 column was unticked. I used devexpress.
Example of my code that I used:
public void abc()
{
//select query in here
gridControl1.DataSource = dt;
//iam adding a column here
dt.Columns.Add("cek22",typeof(bool));
}

If your column is added manually then your column is working in unbound mode. So, you can just use its unbound expression. If you want to update your checklist column from cel22 then you can use CellValueChanging event.
Here is example:
var table = new DataTable();
table.Columns.AddRange(new[]
{
new DataColumn("preferred", typeof(string)),
new DataColumn("checklist", typeof(int))
});
table.Rows.Add("Director Fury", 1);
table.Rows.Add("Maria Hill", 0);
gridControl1.DataSource = table;
gridView1.PopulateColumns();
var column = new GridColumn();
column.FieldName = "cek22";
column.UnboundType = UnboundColumnType.Boolean;
column.UnboundExpression = "[checklist]";
column.Visible = true;
gridView1.Columns.Add(column);
gridView1.CellValueChanging += (sender, e) =>
{
if (e.Column.FieldName == "cek22")
gridView1.SetRowCellValue(e.RowHandle, "checklist", e.Value);
};
Here is the result:

The DevExpress Grid works with DataSource. So manipulate your DataSource and populate this to your Grid. The GridView will show this data. So if you want a check field i would recommend you to extend your DataSource with a bool Property. I don't now which DataSource you are using but if there is any bool value devexpress automatically add a checkbox column for you. If you want to link your custom column to the bool value in your DataSource you need to set the FieldName Property of the Column to your PropertyName.
If your checklist Property is 0 your bool Property return false and vice versa. This would be the easiest solution i guess. Assumed your are using a IList as DataSource.
Small example:
public class MyDataSource()
{
public int Checklist { get; set; }
public bool Cek22
{
get { return Checklist == 1; }
}
}
private void ExplainADevExpressGrid()
{
List<MyDataSource> dataSource = new List<MyDataSource>();
dataSource.Add(new MyDataSource());
myGrid.DataSource = dataSource;
}

Alternatively, add the column as part of the data source and populate it conditionally.
private void Form1_Load(object sender, EventArgs e)
{
DataTable dataTable = GetDataTable(10);
gridControl1.DataSource = dataTable;
}
private DataTable GetDataTable(int rows = 1)
{
DataTable table = new DataTable("Table1");
table.Columns.Add("checklist", typeof(int));
table.Columns.Add("cek22", typeof(bool));
for (int i = 0; i < rows; i++)
{
DataRow row = table.NewRow();
row["checklist"] = i % 2 == 0 ? 0 : 1;
row["cek22"] = ((int)row["checklist"]) == 0 ? false : true;
table.Rows.Add(row);
}
return table;
}

Related

how to sum values between columns in grid view with IFCondition?

i have 3 columns in gridview, Column_A, Column_B and Column_total. then i do simple calculation between Column_A and Column_B and put it in Column_total.. example: when i enter value 1 in row Column_A and 1 in row Column_B, Column_total displays result 2. this simple code works:
private void Gdv_CellEndEdit(object sender, GridViewCellEventArgs e)
{
foreach (GridViewDataRowInfo Val in Gdv.SelectedRows)
{
Val.Cells["Column_Total"].Value = Convert.ToInt32(Val.Cells["Column_A"].Value) + Convert.ToInt32(Val.Cells["Column_B"].Value);
}
}
but in Column_total still showing result when I delete value in Column_A..
What I want, Column_total shows result when I enter value in Column_A, then when I delete value in Column_A then Column_total will return empty and won't show any result.. anyone can help?
Your method is not being recalled to reassign the updated value, I can only guess your .value is a string as you are using convert and didn't specify.
private void Gdv_CellEndEdit(object sender, GridViewCellEventArgs e)
{
bool _; /*Throw away value true/false output not needed,
prevents compiler warning.*/
foreach (GridViewDataRowInfo Val in Gdv.SelectedRows)
{
_ = int.TryParse(Val.Cells["Column_A"].Value, out a);
_ = int.TryParse(Val.Cells["Column_B"].Value, out b);
Val.Cells["Column_Total"].Value = (a != 0 || b != 0) ? (a + b) : "";
//If a or b is not 0, as int cannot be null; will sum(a+b), else return "" empty.
//Can change the or || to && if you require both to have values > 0.
}
}
finally.. agree with #JohnG, to solve my question problem is to use column expression.this is the last code snippet of my project :
// Create second column.
DataColumn Col_A = new DataColumn();
Col_A .DataType = System.Type.GetType("System.Decimal");
Col_A .ColumnName = "Column_A";
// Create second column.
DataColumn Col_Total = new DataColumn();
Col_Total .DataType = System.Type.GetType("System.Decimal");
Col_Total .ColumnName = "Column_total";
Col_Total .Expression = "Column_A * Column_B";
// Add columns to DataTable.
dt.Columns.Add(Col_A);
dt.Columns.Add(Col_Total);
DataView view = new DataView(dt);
dgv.DataSource = view;
I added 2 new columns named "Col_A" and "Col_Total" and in the summation column, the column "Column_B" is obtained from the gridview which displays the data source from mysql.
it really works, and I don't know if there's anything better than this?
Thank you for those of you who have answered my previous question.

Conditional Delete after button click (radgridview)

assume I have 2 columns in gridview : column A and column B. I want to delete the whole row if Column B has no value. this code checks column B if it doesn't have any value. next, how to enter the delete command based on the value obtained from the code ?
private void Button1_Click(object sender, EventArgs e)
{
foreach (GridViewRowInfo row in DGV1.Rows)
{
if (row.Cells[1].Value == null || Convert.ToString(row.Cells[1].Value) == string.Empty)
{
MessageBox.Show("Null value");
}
}
}
Hopefully I can offer a couple of tips for working with RadGridView or really most any grid view. First, use BeginInvoke to avoid blocking the Click message which allows the UI thread to return from the click handler (mouse returns to the up position, any new button state is painted).
private void buttonRemove_Click(object sender, EventArgs e)
{
// Do not block the click event.
BeginInvoke((MethodInvoker)delegate
{
onButtonRemove();
});
}
Next make an array of records (or rows) that need to be removed. If your view is bound to a DataSource this is especially easy using System.Linq. Then simply remove from DataSource.
void onButtonRemove()
{
// Perform Linq query to see what needs to be removed
var removes =
DataSource
.Where(record => string.IsNullOrWhiteSpace(record.ColumnB));
// Cast to an array before iterating to
// avoid "CollectionWasModified" exception.
foreach (var record in removes.ToArray())
{
DataSource.Remove(record);
}
}
This particular code defines a row with this Record class:
class Record
{
public string ColumnA { get; set; } = "SomeValue";
public string ColumnB { get; set; }
}
If you were using a Winforms DataGridView it could initialize like this:
BindingList<Record> DataSource = new BindingList<Record>();
private void InitializeDataGridView()
{
dataGridView1.AllowUserToAddRows = false;
dataGridView1.DataSource = DataSource;
// Add one or more records to auto-create columns.
DataSource.Add(new Record { ColumnB = "Not empty or null"});
DataSource.Add(new Record { ColumnB = String.Empty});
DataSource.Add(new Record { ColumnB = null});
// Column formatting
dataGridView1.Columns[nameof(Record.ColumnA)].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
dataGridView1.Columns[nameof(Record.ColumnB)].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
}
Your post is for Telerik.WinControls.UI.RadGridView but the initialization is very similar:
BindingList<Record> DataSource = new BindingList<Record>();
private void InitializeDataGridView()
{
DGV1.DataSource = DataSource;
// Add one or more records to auto-create columns.
DataSource.Add(new Record { ColumnB = "Not empty or null"});
DataSource.Add(new Record { ColumnB = String.Empty});
DataSource.Add(new Record { ColumnB = null});
// Column formatting
DGV1.AutoSizeColumnsMode = GridViewAutoSizeColumnsMode.Fill;
}
Hope this helps get you where you want to be.

Looping through gridview and change certain column font colour

So I have a gridview and I wanted to make certain columns text a different colour... i.e every column that says actual I want this text to be green... can anybody help? My gridlooks similar to this.
Hour - actual A - target A - actual aa - target aa - actual b - target b.
And finally is there a way to reset the data in my gridview after a certain amount of time... i.e shiftstart 6am-2pm 2pm-10pm 10pm-6am... So the data refreshes after 8 hours back to zero.
public void Refreshdata(int selectedProduct, DateTime shiftStart, DateTime shiftEnd)
{
BizManager biz = new BizManager();
GridView1.DataSource = biz.GetPacktstatisticsForShift(
shiftStart
, shiftEnd
, selectedProduct).DefaultView;
GridView1.DataBind();
public DataTable CreatePackingStats(DataSet dset)
{
using (DataManager dmgr = new DataManager())
{
DataTable target = dset.Tables[0];
DataTable actual = dset.Tables[1];
DataColumn[] cols = new DataColumn[1];
cols[0] = actual.Columns["Hour"];
actual.PrimaryKey = cols;
DataTable final = new DataTable();
// Create table columns
foreach (DataColumn col in target.Columns)
{
final.Columns.Add(new DataColumn(col.ColumnName, col.DataType));
if (col.ColumnName.Contains("Target"))
{
// Add an equivilant actual column
string newColumnName = col.ColumnName.Replace("Target", "Actual");
final.Columns.Add(newColumnName, col.DataType);
}
}
//// Add rows to new table
foreach (DataRow row in target.Rows)
{
string key = row["Hour"].ToString();
DataRow newRow = final.Rows.Add();
// Store column value
foreach (DataColumn col in final.Columns)
{
if (col.ColumnName.Contains("HOUR") || col.ColumnName.Contains("Target"))
{
newRow[col.ColumnName] = row[col.ColumnName];
}
else
{
// Find actual data
DataColumn actColumn = actual.Columns[col.ColumnName] as DataColumn;
if (actColumn == null)
{
newRow[col.ColumnName] = 0;
}
else
{
if (string.IsNullOrEmpty(actual.Rows.Find(key)[col.ColumnName].ToString()))
{
newRow[col.ColumnName] = 0;
}
else
{
newRow[col.ColumnName] = actual.Rows.Find(key)[col.ColumnName].ToString();
}
}
}
}
}
return final;
The CreatePackingStats is populating my grid with added columns FYI.
I guess there is a way to add colour text whilst the code is looping through the data and creating extra columns, not sure how to do this tho.?
And also the CreatePackingStats is located in a class and not in the page behind aspx.
Sorry about all the questions I am new and learning, all your help will help to develop and I appreciate all the help I receive.
Right-click on your GridView then go to the properties tab and select events.In there you will find the event called RowDataBound.
In that event write your code to change the forecolor like:
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
//here the Cells is an array where you can pass the index value of the cell where you want to check and if you don't know where the value is then you can do a for loop and then check the value
if (e.Row.Cells[0].Text == "someValue")
{
e.Row.Cells[0].ForeColor = System.Drawing.Color.Red;
}
}
}
Update 1 for comparing the value using the IndexOf()
As for the data what you have given, you have to change the compare function from == to IndexOf("SomeValue").For that, you can try the IndexOf("actual"). If it gives value > -1 then change the color.
or you can try the below code where I am looping through all the columns in the row(you can try to avoid the looping if you have knowledge on which column the value will occur):
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
for (int i = 0; i < e.Row.Cells.Count; i++)
{
if (e.Row.Cells[i].Text.ToLower().IndexOf("actual") > -1)
{
e.Row.Cells[i].ForeColor = System.Drawing.Color.Red;
}
}
}
}
Update 2 Adding the snapshots of sample data and it's output.
Here is the sample data with which I am working:
And here is the processed output using the IndexOf() loop over the in RowDataBound event.
Hope this helps.

How to set a datagridview values to it's datasource

I want to pass datasource of a datagridview to another Form,
this is how i do that:
private void RationSummary_Click(object sender, EventArgs e)
{
RationReportFrm RRFrm = new
RationReportFrm(HomeDetailsdgv.DataSource, RationFormulationdgv;
RRFrm.ShowDialog();
}
and
public RationReportFrm(object RationTotalds, object HomeTotalds)
{
InitializeComponent();
AnimalPerformancedgv.DataSource = RationTotalds;
ProteinValuedgv.DataSource = HomeTotalds;
}
now the question is:
datasource of one of these datagridviews has set by a datatable and it passes to RationReportFrm without any problem,
but one of them dosen't have any datasource and it's cells filled programmatically, How should I set it's cells values to it datasource in order to pass it to another form?
I think the beset way is to make a method to convert datagridview to a datatable
private DataTable GetDTFromDGV(DataGridView dgv)
{
var dt = new DataTable();
foreach (DataGridViewColumn column in dgv.Columns)
{
if (column.Visible)
{
dt.Columns.Add();
if (column.Name != "")
{
dt.Columns[column.Index].ColumnName = column.Name;
}
}
}
object[] CellValue = new object[dgv.Columns.Count];
foreach (DataGridViewRow row in dgv.Rows)
{
for (int i = 0; i < row.Cells.Count; i++)
{
CellValue[i] = row.Cells[i].Value;
}
dt.Rows.Add(CellValue);
}
return dt;
}

Reset column increment datagridview

I am trying to update the row increment number in a DataGridView in my WinForms application after deleting a row or rows. I have looked at sources and the all point on how to add the incrementing to a column in DataTable. My DataGridView is bound to my DataTable, and that is bound to a DataSet.
How I created by datatable:
DataColumn itemNumber = new DataColumn();
itemNumber.ColumnName = "ItemNumber";
itemNumber.AutoIncrement = true;
itemNumber.AutoIncrementSeed = 1;
itemNumber.AutoIncrementStep = 1;
DataColumn article = new DataColumn();
article.ColumnName = "Article";
article.ReadOnly = true;
DataColumn description = new DataColumn();
description.ColumnName = "Description";
description.ReadOnly = true;
DataColumn type = new DataColumn();
type.ColumnName = "Type";
type.ReadOnly = true;
//add to datatable
dt.Columns.Add(itemNumber);
dt.Columns.Add(article);
dt.Columns.Add(description);
dt.Columns.Add(type);
Removing a row from the DataGridView
foreach (DataGridViewRow row in dgvView.SelectedRows)
{
dgvView.Rows.RemoveAt(row.Index);
}
If I have 5 rows, and delete one. I would like the increment values to start from the 1,2,3,4 etc...
Can someone point me on how to achieve this?
I can't think of an efficient way to do this, but here are some ideas that may work with small data sets.
Keep up with the values yourself
1) Don't define the column as an AutoIncrement column):
DataColumn itemNumber = new DataColumn();
itemNumber.ColumnName = "ItemNumber";
//itemNumber.AutoIncrement = true;
//itemNumber.AutoIncrementSeed = 1;
//itemNumber.AutoIncrementStep = 1;
2) Handle the DataGridView.RowsAdded and DataGridView.RowsRemoved events and "reset" the values:
private void dgvView_RowsAdded(object sender, DataGridViewRowsAddedEventArgs e)
{
if (dgvView.Columns.Contains("ItemNumber"))
{
foreach (DataGridViewRow r in dgvView.Rows)
{
r.Cells["ItemNumber"].Value = r.Index + 1;
}
}
}
private void dgvView_RowsRemoved(object sender, DataGridViewRowsRemovedEventArgs e)
{
if (dgvView.Columns.Contains("ItemNumber"))
{
foreach (DataGridViewRow r in dgvView.Rows)
{
r.Cells["ItemNumber"].Value = r.Index + 1;
}
}
}
Regenerate the values by rebuilding the DataTable and rebinding to it
1) Define the helper method below:
private DataTable ResetAutoIncrementColumn(DataTable dt, string autoIncrementColumnName)
{
DataTable result = new DataTable();
DataColumn itemNumber = new DataColumn(autoIncrementColumnName);
itemNumber.AutoIncrement = true;
itemNumber.AutoIncrementSeed = 1;
itemNumber.AutoIncrementStep = 1;
result.Columns.Add(itemNumber);
dt.Columns.Remove(autoIncrementColumnName);
result.Merge(dt, true);
return result;
}
2) Call it at the appropriate time (e.g. after a series of deletes as in the original question):
dt = ResetAutoIncrementColumn(dt, "ItemNumber");
dt.Columns["ItemNumber"].SetOrdinal(0);
dgvView.DataSource = dt;
dgvView.Columns["ItemNumber"].DisplayIndex = 0;
If you are just looking for a visual row number
Also, if you are just looking to have a visual row number on the DataGridView (and you don't care about the value being present in the underlying DataTable), you can handle the DataGridView.RowPostPaint event as follows (pulled from https://stackoverflow.com/a/12840794/3085273):
private void dgGrid_RowPostPaint(object sender, DataGridViewRowPostPaintEventArgs e)
{
var grid = sender as DataGridView;
var rowIdx = (e.RowIndex + 1).ToString();
var centerFormat = new StringFormat()
{
// right alignment might actually make more sense for numbers
Alignment = StringAlignment.Center,
LineAlignment = StringAlignment.Center
};
var headerBounds = new Rectangle(e.RowBounds.Left, e.RowBounds.Top, grid.RowHeadersWidth, e.RowBounds.Height);
e.Graphics.DrawString(rowIdx, this.Font, SystemBrushes.ControlText, headerBounds, centerFormat);
}

Categories