How can I add Gridview columns dynamically based on calender days?
The header of the grid should show dates 01/01/2013, 02/01/2013...and each column is a TemplateField with a Dropdownlist
I achieved this for the weekly view since the fields are constant (7 fields) but when it comes to the month view I cannot add 30 or 31 fields because I've coded in ASP not on code behind C#.
Can anybody give me some hints on how to create a month calendar in this way?
I already tried these links but it didn't help
http://geekswithblogs.net/dotNETvinz/archive/2010/08/03/adding-dynamic-rows-in-gridview-with-textbox-and-dropdownlist.aspx
http://bytes.com/topic/asp-net/answers/925328-how-display-selected-dates-database-calendar-control
You can try doing something like this:
DataTable dt = new DataTable();
DataColumn dcol = new DataColumn("ID", typeof(System.Int32));
dcol.AutoIncrement = true;
dt.Columns.Add(dcol);
int days = 0;
string selected_month = "JAN";
if (selected_month == "JAN" || selected_month == "MAR")
{ days = 31; }
else if(selected_month == "APR")
{ days = 30; }
for (int z = 1; z < days; z++)
{
dcol = new DataColumn(z.ToString(), typeof(System.String));
dt.Columns.Add(dcol);
}
Related
I'v been looking through a LOT of websites and i did not find any awnser,
So let's say I have a DataGridView with a Column and the Rows are (assuming today's date is 21/05/2019 (dd/mm/yyyy))
22/05/2019
22/04/2019
21/01/2019
So I want the first one to be in red (because its 1 day off today's date)
I want the second one to be in orange (because it entered the -1 month mark)
And the last one should be normal because its far from -1 month.
I've tryed this:
var dateminusonemonth = DateTime.Today.AddMonths(-1);
foreach (DataGridViewRow row in dgproduit.Rows)
if (Convert.ToString(dateminusonemonth) = txtboxdatecontrole.Text)
{
row.DefaultCellStyle.BackColor = Color.Red;
}
But it doesn't work at all and I dont know where to look at...
EDIT : This is what i want, but i cant get it to work Change row color in DataGridView based on column date
EDIT : It worked ! with this code :
DateTime now = DateTime.Now, thirtyDaysAgo = now.AddDays(-30), expirationDate;
foreach (DataGridViewRow row in dgproduit.Rows)
{
string cellText = row.Cells["datecontrole"].Value + "";
if (DateTime.TryParse(cellText, out expirationDate))
{
if (expirationDate < now)
row.DefaultCellStyle.BackColor = Color.OrangeRed;
else if (expirationDate > thirtyDaysAgo)
row.DefaultCellStyle.BackColor = Color.LightBlue;
}
}
Whenever you have sequences of items, LINQ is your best friend
Assuming the column that shows the dates that you want to color is columnDate
DataGridViewColumn columnDate = ...
DataGridView myDataGridView = ...
var dateCells = myDataGridView.Rows.Cast<DataGridViewRow>()
.Select(row => row.Cells[columnDate.Name])
.Select(dateCell => new
{
DataGridViewCell = dateCell,
Date = DateTime.Parse(dateCell.Value.ToString()).Date,
});
So Date contains the Date part of the displayed value in the DateCell. If you don't want to compare on Date, but on a TimeSpan of 24 hours, you should remember the DateTime.
Date = DateTime.Parse(dateCell.Value.ToString());
Now to get the cells that you want to colorize:
DateTime today = DateTime.Today;
// The cells that have a date between (today - 1 day) and (today + 1 day) should be red:
var todayMinus1Day = today.AddDays(-1);
var todayPlus1Day = today.AddDays(+1);
var todayMinus1Month = today.AddMonths(-1);
var todayPlus1Month = today.AddMonths(+1)
foreach (var cell in dateCells)
{
if (todayMinus1Month <= cell.Date && cell.Date <= todayPlus1Month)
{
// either orange or red: not default:
cell.DataGridViewCell.Style = cell.DataGridViewCell.GetInheritedStyle();
cell.DataGridViewCell.Style.BackColor =
(todayMinums1Day <= cell.Date && cell.Date <= todayPlus1Day) ?
Color.Red : Color.Orange;
}
else
{ // use the inherited style = set the cell style to null
cell.DataGridViewCell.Style = null;
}
}
I can't understand what exactly you need but I will try.
var dateminusonemonth = DateTime.Today.AddMonths(-1);
foreach (DataGridViewRow row in dgproduit.Rows)
{
DateTime DateToComapre = Datetime.Parse(row.Cells[Cell with you Date to Comapre].value); //Date format must match!
if (DateTime.Now < DateToCompare)
{
row.DefaultCellStyle.BackColor = Color.Red;
}
else if (dateminusonemonth < DateToCompare && DateToCompare < DateTime.Now)
{
row.DefaultCellStyle.BackColor = Color.Orange;
}
else
{
drow.RowHeadersDefaultCellStyle.SelectionBackColor = Color.Empty;
}
}
i have a table in SqlServer which contain's: (ID, item_name, date_time_added)
i want to create a C# code to first: view (ID,item_name, date_time_added) column in datagridview then calculate (date_time_NOW - date_time_added) and view the result in a new column(named: expire's in:) in same datagridview...
Note: result would count day's remaining before expiring
what i've tried so far:
DataTable dt = new DataTable();
dt.Columns.Add(new DataColumn("Expire's in:", typeof(int)));
int countrow = dataGridView1.RowCount;
for (int i = 0; i < countrow; i++)
{
string dateAsString = dataGridView1.Rows[dataGridView1.SelectedRows[0].Index].Cells[3].Value.ToString();
DateTime.TryParseExact(dateAsString , "yyyy-MM-dd", System.Globalization.CultureInfo.InvariantCulture, System.Globalization.DateTimeStyles.AssumeLocal, out DateTime dateAsString);
dateTimePicker3.Text = dateAsString;
DateTime expire_date = dateTimePicker3.Value;
TimeSpan span = expire_date - DateTime.Now;
int days = span.Days;
dataGridView1.Rows[dataGridView1.SelectedRows[0].Index].Cells[4].Value = days;
}
Note:Code Updated...
Any help will be greatly appreciated..
I will assume the “ExpireDate” field returned from the sql query is a DateTime object. If this is the case then it would appear that converting the “date” to a string is unnecessary. Example, given a “future” date, then the difference between todays date and the “future” date can be accomplished as…
TimeSpan dif = futureDate.Subtract(DateTime.Now);
Using a DataTable proffers the ability to use an Expression column, however, I do not think this will work with dates and times. Fortunately, this should not be difficult to implement if the grids DataSource is a DataTable. Using a “Class” would be another option. This example uses a DataTable as a DataSource to the grid.
Given this, to make things simple it would appear that a method that takes a DataRow from the data table and adds this TimeSpan difference may come in handy. It may look something like below…
private void SetDifCol(DataRow row) {
TimeSpan dif = ((DateTime)row["ExpireDate"]).Subtract(DateTime.Now);
row["TimeToExpire"] = dif.Days + " days " + dif.Hours + " hours " + dif.Minutes + " minutes";
}
Given that the DataTable has already been filled with the data… the code is going to have to “ADD” this difference column, then loop through each row and calculate the difference between the dates. Therefore, a small method that simply adds this column may look something like below…
private void AddDifferenceColumn(DataTable dt) {
dt.Columns.Add("TimeToExpire", typeof(string));
}
Next is the loop through all the rows in the DataTable and simply call the SetDifCol method on each row.
private void CalculateDateDif(DataTable dt) {
foreach (DataRow row in dt.Rows) {
SetDifCol(row);
}
}
This will work as expected when the data is loaded, however, what if the user “changes” one of the “ExpireDate” values in the grid? In this case, we would need to wire up one of the grids cell change events. Specifically the grids CellValueChanged event. This event will call the SetDifCol method if the “ExpireDate” value changes in that row…
private void dataGridView1_CellValueChanged(object sender, DataGridViewCellEventArgs e) {
if (dataGridView1.Columns[e.ColumnIndex].Name == "ExpireDate") {
if (e.RowIndex >= 0 && dataGridView1.Rows[e.RowIndex].Cells["ExpireDate"].Value != null) {
DataRowView row = (DataRowView)dataGridView1.Rows[e.RowIndex].DataBoundItem;
SetDifCol(row.Row);
}
}
}
Putting this all together may look something like below…
DataTable GridTable;
public Form1() {
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e) {
GridTable = GetTable();
FillTable(GridTable);
AddDifferenceColumn(GridTable);
CalculateDateDif(GridTable);
dataGridView1.DataSource = GridTable;
dataGridView1.Columns[3].Width = 180;
}
private DataTable GetTable() {
DataTable dt = new DataTable();
dt.Columns.Add("ID", typeof(string));
dt.Columns.Add("Name", typeof(string));
dt.Columns.Add("ExpireDate", typeof(DateTime));
return dt;
}
private void AddDifferenceColumn(DataTable dt) {
dt.Columns.Add("TimeToExpire", typeof(string));
}
private void FillTable(DataTable dt) {
dt.Rows.Add("ID1", "Name1", new DateTime(2019, 12, 31));
dt.Rows.Add("ID2", "Name2", new DateTime(2019, 8, 31));
dt.Rows.Add("ID3", "Name3", new DateTime(2019, 4, 30));
dt.Rows.Add("ID4", "Name4", new DateTime(2019, 1, 31));
dt.Rows.Add("ID5", "Name5", new DateTime(2019, 4, 12, 21, 38, 00));
}
private void CalculateDateDif(DataTable dt) {
foreach (DataRow row in dt.Rows) {
SetDifCol(row);
}
}
private void SetDifCol(DataRow row) {
TimeSpan dif = ((DateTime)row["ExpireDate"]).Subtract(DateTime.Now);
row["TimeToExpire"] = dif.Days + " days " + dif.Hours + " hours " + dif.Minutes + " minutes";
}
private void dataGridView1_CellValueChanged(object sender, DataGridViewCellEventArgs e) {
if (dataGridView1.Columns[e.ColumnIndex].Name == "ExpireDate") {
if (e.RowIndex >= 0 && dataGridView1.Rows[e.RowIndex].Cells["ExpireDate"].Value != null) {
DataRowView row = (DataRowView)dataGridView1.Rows[e.RowIndex].DataBoundItem;
SetDifCol(row.Row);
}
}
}
I hope this helps.
EDIT:
to change column type from string to int to sort numerically.
In reference to the extra question you posted, you commented that ”i want to calculate according to what is inside my db Table” … There is no code in this question or the other question that shows a data base. How are you getting the data to begin with?
It appears in this question that there IS a NEW DataTable dt and a column is added to it, however, it is NEVER used. The loop in the code simply adds the difference column to the “GRID” NOT the DataTable. My answer “adds” the diffence column to the DataTable (which you should do). I recommend you show how you are getting the data from the data base.
In reference to sorting the column, you have already noticed that strings that are numbers will not sort properly numerically. This is because they are string… solution… make them ints. Using my answer, two changes are need for this. First the creation of the column needs to be an int type…
private void AddDifferenceColumn(DataTable dt) {
dt.Columns.Add("TimeToExpire", typeof(int));
}
Second a change is needed in the SetDifCol method. Since you only want the days difference and any values less than zero should show as zero (0), then the following changes should accommodate this requirement.
private void SetDifCol(DataRow row) {
TimeSpan dif = ((DateTime)row["ExpireDate"]).Subtract(DateTime.Now);
if (dif.Days >= 0) {
row["TimeToExpire"] = dif.Days;
}
else {
row["TimeToExpire"] = 0;
}
}
These two changes should sort the column numerically as expected.
Lastly, it should be clear, that IF you want this “difference” column to be reflected in the database… then YOU will have to add the difference column to the database table, THEN, you will need to issue an update command to the database table.
From what I see you try to put a string into the DateTime value here:
DateTime str;
str=dataGridView1.Rows[dataGridView1.SelectedRows[0].Index].Cells[3].Value.ToString();
If you want to parse string to DateTime the code should look like this:
string dateAsString = dataGridView1.Rows[dataGridView1.SelectedRows[0].Index].Cells[3].Value.ToString();
DateTime.TryParseExact(dateAsString, "yyyy-MM-dd", System.Globalization.CultureInfo.InvariantCulture, System.Globalization.DateTimeStyles.AssumeLocal, out DateTime dateAsDateTime);
Then you can substract that date from DateTime.Now:
TimeSpan span = dateAsDateTime - DateTime.Now;
And finally extract the days from the span:
int days = span.Days;
OR just do it all in one line:
int days = (DateTime.Now - dataGridView1.Rows[dataGridView1.SelectedRows[0].Index].Cells[3].Value).Days;
I have to add last 18 months to a drop down in asp.net C#.
I have written the logic to get last 18 months as follows.,
List<string> dateList= new List<string>();
private List<string> GetDateDropDownList(DropDown pDropDown)
{
DateTime dt = DateTime.Now;
for (int i = 1; i <= 18; i++)
{
dt = dt.AddMonths(-1);
var month = dt.ToString("MMMM");
var year = dt.Year;
dateList.Add(String.Format("{0}-{1}", month, year));
}
return dateList;
}
now I need to add this list to drop down. I am trying but it is not working. How can I add it to the drop down?
Similar to what others have said, you just bind your function to it.
However, you have a little issue in your code. You create your dateList outside of your actual method, instead of inside of it. You also do not need to pass a dropdown list into the method.
So your updated method should be:
private List<string> GetDateDropDownList()// get rid of parameter
{
List<string> dateList= new List<string>(); // inside method
DateTime dt = DateTime.Now;
for (int i = 1; i <= 18; i++)
{
dt = dt.AddMonths(-1);
var month = dt.ToString("MMMM");
var year = dt.Year;
dateList.Add(String.Format("{0}-{1}", month, year));
}
return dateList;
}
And you bind your dropdown direct to the method
myDropdown.DataSource = GetDateDropDownList();
myDropdown.DataBind();
Alternatively, with your original method you can do the following - notice it's now a void and does not return a list.
private void GetDateDropDownList(DropDown pDropDown)
{
List<string> dateList= new List<string>();
DateTime dt = DateTime.Now;
for (int i = 1; i <= 18; i++)
{
dt = dt.AddMonths(-1);
var month = dt.ToString("MMMM");
var year = dt.Year;
dateList.Add(String.Format("{0}-{1}", month, year));
}
pDropDown.DataSource = dateList;
pDropDown.DataBind()
}
And you would simply pass in your dropdown list
GetDateDropDownList(myDropdownList);
All you're doing in your method is building a list. You never add it to the drop down. Like this...
pDropDown.DataSource = dateList;
pDropDown.DataBind();
You are currently building a list of strings, but in order to make it visible within your dropdown, you'll need to specifically set the DataSource property and then call DataBind() to apply the changes:
// This sets your data
pDropDown.DataSource = dateList;
// This actually binds the current data to the DropDownList control
pDropDown.DataBind();
Additionally, you likely won't need to be returning any values from this method (unless you need them for some other reason) and could consider making it return void:
private void SetDatesForDropDown(DropDown pDropDown, int monthsBack = 18)
{
List<string> dateList= new List<string>();
DateTime dt = DateTime.Now;
for (int i = 1; i <= monthsBack; i++)
{
dt = dt.AddMonths(-1);
dateList.Add(dt.ToString("MMMM-yyyy"));
}
pDropDown.DataSource = dateList;
pDropDown.DataBind();
}
Or simply removing the DropDown parameter and using the results of the method to set your DataSource:
private void GetDateRanges(int monthsBack = 18)
{
List<string> dateList= new List<string>();
DateTime dt = DateTime.Now;
for (int i = 1; i <= monthsBack; i++)
{
dt = dt.AddMonths(-1);
dateList.Add(dt.ToString("MMMM-yyyy"));
}
return dateList;
}
along with:
YourDropDown.DataSource = GetDateRanges();
YourDropDown.DataBind();
There are a number of ways of doing this, below is one such way.
Just remember to bind it to a dropdownlist.
EDITED - Getting the Selected Value
Frontend - ASPX
<asp:DropDownList ID="DropDownList1" runat="server" OnLoad="DropDownList1_Load" OnSelectedIndexChanged="DropDownList1_SelectedIndexChanged" AutoPostBack="true"></asp:DropDownList>
Codebehind - C#
//Populate the DropDownList
protected void DropDownList1_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
// Instantiate your DropDownList
DropDownList drpList = (DropDownList)sender;
List<string> dateList = new List<string>();
DateTime dt = DateTime.Now;
for (int i = 1; i <= 18; i++)
{
dt = dt.AddMonths(-1);
var month = dt.ToString("MMMM");
var year = dt.Year;
dateList.Add(String.Format("{0}-{1}", month, year));
}
// Bind resulting list to the DropDownList
drpList.DataSource = dateList;
drpList.DataBind();
}
}
//Get the Selected Value on change
protected void DropDownList1_SelectedIndexChanged(object sender, EventArgs e)
{
// assign the selected item value to a variable
string value = ((DropDownList)sender).SelectedValue;
}
I'm struggling with the following. I have a DataTable with dates in it. Dates that can contain several time rows. Now I want to click on a date on the calender and it will put the times records from that day in a listbox so I can then select the time.
I'm stuck and googled around but I'm blind at this point.
The datatable output in gridview:
Datum
-----------------
22-09-14 13:05:00
22-09-14 13:05:18
23-09-14 13:05:36
23-09-14 13:05:54
23-09-14 13:06:12
21-09-14 14:00:01
21-09-14 15:00:01
21-09-14 16:00:01
21-09-14 17:00:01
The code in the calander SelectionChanged event:
// Create datatable
DataTable dt = new DataTable();
string FileName = "C:\\ProjectName\\data\\data.dat";
var lines = File.ReadAllLines(FileName);
// Make date column
dt.Columns.Add("Datum", typeof(DateTime));
// add rows
for (int i = 2; i < lines.Count(); i++)
{
DataRow dr = dt.NewRow();
string[] values = lines[i].Split(new char[] { ',' }).Select(x => x.Replace("\"", "")).ToArray();
for (int j = 0; j < values.Count() && j < 1; j++)
dr[j] = values[j];
dt.Rows.Add(dr);
}
// Convert selected date
string currentDate = e.SelectedDates.Count - 1 >= 0 ? e.SelectedDates[e.SelectedDates.Count - 1].Date.ToString("dd-MM-yyyy") : "none";
// Print selected date to see format
Label1.Text = currentDate;
// Create dataview and apply filter
DataView dv = new DataView(dt);
dv.RowFilter = "Datum = #" + currentDate + "#";
dv.RowStateFilter = DataViewRowState.ModifiedCurrent;
dv.Sort = "Datum DESC";
// dataview to listbox
lbSource.DataSource = dv;
lbSource.DataTextFormatString = "{0:dd-MM-yyyy HH:mm}";
lbSource.DataTextField = "Datum";
lbSource.DataValueField = "Datum";
lbSource.DataBind();
The dv filter gives me:
String was not recognized as a valid DateTime.
Debugging stops with the following line and gives the "String was not recognized as a valid DateTime.":
dv.RowFilter = "Datum = #" + currentDate + "#";
currentdate comes with the correct date: 22-09-2014 (dd-MM-yyyy)
If someone could help me out, thanks a lot :)
Basically the .rowfilter compare takes the date as Mm/dd/yyyy as comparison. It will see 20/10/2018 as an invalid date. It will work for day being lower than 12.
So in your datatable, the date is stored as dd/mm/yyyy.
Unless you change the date storage format to mm/dd/yyyy, I don't think you can rowsfilter.
I'm developing a program in C#, is a desktop application.
I have a problem, I'm using excellibrary to open an excel and copy the data to a datatable, but I have a cell with date in format mm/dd/yyyy, but when i display the datatable in datagridview this information change to a number, for example:
02/07/1984 -> 30865
this is my code, I hope somebody could help me!
private DataTable ConvertToDataTable(string FilePath)
{
string file = FilePath;
// open xls file
Workbook book = Workbook.Open(file);
Worksheet sheet = book.Worksheets[0];
DataTable dt = new DataTable();
// traverse rows by Index
for (int rowIndex = sheet.Cells.FirstRowIndex; rowIndex <= sheet.Cells.LastRowIndex; rowIndex++)
{
Row row = sheet.Cells.GetRow(rowIndex);
object[] temparray = new object[row.LastColIndex + 1];
for (int colIndex = row.FirstColIndex;
colIndex <= row.LastColIndex; colIndex++)
{
Cell cell = row.GetCell(colIndex);
temparray[colIndex] = cell.Value;
}
if (rowIndex == 0)
{
foreach (object obj in temparray)
{
dt.Columns.Add(obj.ToString());
}
}
else
{
dt.Rows.Add(temparray);
}
}
return dt;
}
The number you see is OLE Automation Date, you need to convert that number to DateTime by using DateTime.FromOADate Method :
DateTime dt = DateTime.FromOADate(30865); //dt = {02/07/1984 12:00:00 AM}
To use that method in your current code, you have to go through each column's value and for date index, parse the value to DateTime and then add it to the DataTable