I have a XtraGrid dropped on to a Winform. I have created 3 unbound columns named ID, StartTime and EndTime and set their unbound types as Int, DateTime and DateTime respectively.
I have created a class:
public class Data
{
public Data(int id, DateTime startTime, DateTime endTime)
{
this.id = id;
this.startTime = startTime;
this.endTime = endTime;
}
private int id;
private DateTime startTime;
private DateTime endTime;
public int ID
{
get { return id; }
set { id = value; }
}
public DateTime StartTime
{
get { return startTime; }
set { startTime = value; }
}
public DateTime EndTime
{
get { return endTime; }
set { endTime = value; }
}
}
In the form constructor I created a List and bind the list to my gridcontrol at runtime
List<Data> list = new List<Data>();
list.AddRange(new Data[] {
new Data(1, Convert.ToDateTime("1:00:00 AM"),
Convert.ToDateTime("3:00:00 AM")),
new Data(2, Convert.ToDateTime("8:00:00 PM"),
Convert.ToDateTime("8:30:00 PM")),
new Data(3, Convert.ToDateTime("12:00:00 PM"),
Convert.ToDateTime("1:00:00 AM")),
new Data(4, Convert.ToDateTime("2:00:00 AM"),
Convert.ToDateTime("3:00:00 AM"))
});
gridControl1.DataSource = list;
When run the application, I get an empty grid. Somehow the columns that I created at design time are not filled correctly with the data at runtime. I try to do the same thing with no columns created at design time and the application run with correctly filled data. I am missing something.
Any ideas to debug the problem or
solve the problem will be very
appreciated. Thanks in advance
Set the FieldName property of your columns to ID, StartTime, EndTime (Case Sensitively!!!!). Also, I would suggest that you move your code to set the grid's DataSource to the form's Load event. This should help you.
Related
I'm trying to display dates from a list within a ListBox. To do this I am trying to bind the list to a listbox.
Here is the code for my driver class.
public class Driver
{
private string name;
private string occupation;
private DateTime dateOfBirth;
private List<DateTime> dateOfClaim;
public Driver(string name, string occupation, DateTime dateOfBirth, List<DateTime> dateOfClaim)
{
this.name = name;
this.occupation = occupation;
this.dateOfBirth = dateOfBirth;
this.dateOfClaim = dateOfClaim;
}
public string DriverName
{
get{ return name; }
set{ name = value; }
}
public string DriverOccupation
{
get { return occupation; }
set { occupation = value; }
}
public DateTime DriverDateOfBirth
{
get { return dateOfBirth; }
set { dateOfBirth = value; }
}
public List<DateTime> DriverDateOfClaim
{
get { return dateOfClaim; }
set { dateOfClaim = value; }
}
}
I have a button which allows you to add a date for a claim to a driver, up to a maximum of 5 claims. I have a 'temporary' list which holds these dates before they are assigned to the dateOfClaim list within the Driver list as the new driver object has not yet been created.
Here are parts of the code from a form which declares and populates the arraylist.
private List<Driver> drivers = new List<Driver>();
private List<DateTime> claimDates = new List<DateTime>();
if (noOfClaims <= 4)
{
claimDates.Add(dtpAddClaim.Value.Date);
noOfClaims++;
}
if (noOfDrivers <= 4)
{
drivers.Add(new Driver(txtName.Text, txtOccupation.Text, dtpDOB.Value.Date, claimDates));
noOfDrivers++;
}
To bind the dateOfClaim list to the listbox I have tried using the following code, but nothing displays in the listbox.
lstClaimDates.DataSource = drivers;
lstClaimDates.DisplayMember = "DriverDateOfClaim";
I've tried displaying the dates in a label using the following code, but again, nothing displays which leads me to believe I'm not adding to the dateOfClaim list correctly.
foreach (DateTime d in drivers[0].driverDateOfClaim)
label1.Text += d.ToString() + " ";
Any help solving this would be greatly appreciated.
WinForms:
You need to define the value/field/property that you would like to show in your listBox:
List<Driver> drivers = new List<Driver>();
drivers.Add(new Driver("name", "The Earth", DateTime.Now, null));
listBox1.DataSource = drivers;
listBox1.DisplayMember = "drivername";
Update 0:
Let me know if it is not applicable for you:
foreach (var c in drivers[0].driverDateOfClaim)
{
listBox1.Items.Add(c);
}
Magnus Montin is superprogrammer and he shows another solution:
List<Driver> drivers = new List<Driver>();
drivers.Add(new Driver("name", "The Earth", DateTime.Now, new List<DateTime>() {
DateTime.Now,
DateTime.Now,
} ));
listBox1.DataSource = drivers[0].driverDateOfClaim;
Update 1:
List<Driver> drivers = new List<Driver>();
drivers.Add(new Driver("name", "The Earth", DateTime.Now, new List<DateTime>()
{
DateTime.Now,
DateTime.Now,
} ));
foreach (var c in drivers[0].driverDateOfClaim)
{
textBox1.Text += " | " + c;
}
you can bound them as string, e.g. using Linq
lstClaimDates.DataSource = drivers[i].driverDateOfClaim.Select(d => d.ToString()).ToList();
should do the job (you can specify your date format in the ToString call)
I'm trying to access a List within an ArrayList to bind that list to a listbox.
Here is the code for my driver class.
public class Driver
{
private string name;
private string occupation;
private DateTime dateOfBirth;
private List<DateTime> dateOfClaim;
public Driver(string name, string occupation, DateTime dateOfBirth, List<DateTime> dateOfClaim)
{
this.name = name;
this.occupation = occupation;
this.dateOfBirth = dateOfBirth;
this.dateOfClaim = new List<DateTime>();
}
public string driverName
{
get{ return name; }
set{ name = value; }
}
public string driverOccupation
{
get { return occupation; }
set { occupation = value; }
}
public DateTime driverDateOfBirth
{
get { return dateOfBirth; }
set { dateOfBirth = value; }
}
public List<DateTime> driverDateOfClaim
{
get { return dateOfClaim; }
set { dateOfClaim = value; }
}
}
I have a button which allows you to add a date for a claim to a driver, up to a maximum of 5 claims so I have a temporary list which holds the dates list before it is assigned to the list in the arraylist as the new driver has not yet been created in the arraylist.
Here are parts of the code from a form which declares and populates the arraylist.
private ArrayList drivers = new ArrayList();
private List<DateTime> claimDates = new List<DateTime>();
if (noOfClaims <= 4)
{
claimDates.Add(dtpAddClaim.Value.Date);
noOfClaims++;
}
if (noOfDrivers <= 4)
{
drivers.Add(new Driver(txtName.Text, txtOccupation.Text, dtpDOB.Value.Date, claimDates));
noOfDrivers++;
}
So my problem comes when trying to access the dateOfClaim list.
I'm trying to bind that list to a listbox and have tried using this to do that but am getting an error saying 'ArrayList' does not contain a definition for 'driverDateOfClaim'.
lbxClaimDates.DataSource = drivers.driverDateOfClaim;
Any help solving this would be greatly appreciated.
You need to index the array list. You would need to access an item of the array list and then acces driverDateOfClaim for a specific Driver instance in the ArrayList
lbxClaimDates.DataSource = ((Driver) drivers[0]).driverDateOfClaim
Also in Drivers constructor you arent assigning the dateOfClaim parameter to the DateOfClaim property.
I want to write an extension method that adds one day to a Nullable DateTime, but modifies the date itself.
I want to use it as follows:
someDate.AddOneDay();
This directly changes the value of someDate.
The code I initially wrote was:
public static DateTime? AddOneDay(this DateTime? date)
{
if (date.HasValue)
{
date.Value = date.Value.AddDays(1);
}
return null;
}
but this doesn't work since the reference is changed thus calling it this way
won't change the value of someDate.
Is there a way to achieve this and avoid code like:
someDate = someDate.AddOneDay();
Also I was thinking for some setter of the DateTime properties, but they don't have any..
public int Day { get; }
public int Month { get; }
public int Year { get; }
You can't DateTime is immutable, and should stay that way.
Just do:
someDate = someDate.AddOneDay();
And if you want to be more specific, you could rename your function to:
DateTime? someDate = someDate.AddOneDayOrDefault();
old school %)
public static void AddOneDay(ref DateTime date)
{
if (date != null) date = date.AddDays(1);
}
usage:
DateTime date = DateTime.Now;
AddOneDay(ref date);
UPD
one line version of method:
public static void AddOneDay(ref DateTime date) { date = date.AddDays(1); }
C# does support a similar feature, even for mutable values, which is the use of += on nullable values:
DateTime? date = GetDate();
var oneDay = TimeSpan.FromDays(1);
date += oneDay;
I have a List that contains a series of transaction objects. What I'm trying to do is to display these transaction objects in a Datagridview control on loading a form, basically the Datagridview should represent something of a transaction register to display the data for each of the transaction objects in the list.
I must admit to a lack of experience when it comes to using Datagridviews and I'm having some difficulty with understanding what I need to do here.
My question is, how do I go about getting the details of each of the objects in the list to display in the Datagridview?
Here is my code.
First the transaction class:
public class Transaction
{
// Class properties
private decimal amount;
private string type;
private decimal balance;
private string date;
private string transNum;
private string description;
// Constructor to create transaction object with values set.
public Transaction(decimal amount, string type, decimal currBal, string date, string num, string descrip)
{
this.amount = amount;
this.type = type;
this.balance = currBal;
this.date = date;
this.transNum = num;
this.description = descrip;
}
// Get and Set accessors to allow manipulation of values.
public decimal Amount
{
get
{
return amount;
}
set
{
amount = value;
}
}
public string Type
{
get
{
return type;
}
set
{
type = value;
}
}
public decimal Balance
{
get
{
return balance;
}
set
{
balance = value;
}
}
public string Date
{
get
{
return date;
}
set
{
date = value;
}
}
public string TransNum
{
get
{
return transNum;
}
set
{
transNum = value;
}
}
public string Description
{
get
{
return description;
}
set
{
description = value;
}
}
public decimal addCredit(decimal balance, decimal credit)
{
decimal newBalance;
newBalance = balance + credit;
return newBalance;
}
public decimal subtractDebit(decimal balance, decimal debit)
{
decimal newBalance;
newBalance = balance - debit;
return newBalance;
}
}
}
Now the code for the "Register" form:
public partial class Register : Form
{
List<Transaction> tranList = new List<Transaction>();
public Register(List<Transaction> List)
{
InitializeComponent();
this.tranList = List;
}
private void Register_Load(object sender, System.EventArgs e)
{
//regView represents the Datagridview that I'm trying to work with
regView.AutoSize = true;
regView.DataSource = tranList;
regView.Rows.Add(tranList[0]);
}
}
And here's the output I get.
There's really two high level approaches to this.
1) Add the manually created rows directly to the DataGridView. In this case, you have to manually update/remove them as things change. This approach is "ok" if you don't intend to alter/change the content of the display after you initialize it. It becomes untenable if you do.
To add it directly, you need to create a DataGridViewRow, and populate it with the individual values, and then add the DataGridViewRow to the DataGridView.Rows.
2) Data bind the DGV. There's many articles about databinding to a DataGridView. In some cases, it's easier to just add your data to a DataTable, and then extract a DataView from that, and bind the DataGridView to the DataView. Other people find it easier to directly bind to a collection.
CodeProject has a decent article to get you started down that path, but a quick Google search will yield many other articles.
http://www.codeproject.com/Articles/24656/A-Detailed-Data-Binding-Tutorial
use as DGV:
DataGridView groupListDataGridView;
column:
DataGridViewTextBoxColumn groupListNameColumn;
column setup should be like this:
groupListNameColumn.DataPropertyName = "name";
use this property, else all columns will be added.
groupListDataGridView.AutoGenerateColumns = false;
populate like this:
private void populateGroupList() {
groupListDataGridView.DataSource = null;
formattedGroupList = new SortableBindingList<DataGridGroupObject>();
foreach (GroupObject go in StartUp.GroupList) {
DataGridGroupObject dggo = new DataGridGroupObject();
dggo.id = go.Id;
dggo.name = go.Name;
formattedGroupList.Add(dggo);
}
groupListDataGridView.DataSource = formattedGroupList;
groupListDataGridView.Invalidate();
}
and model:
public class DataGridGroupObject
{
public int id { get; set; } //this will be match id column
public string name { get; set; } // this will be match name column
}
Simply add using System.Linq; at the top. Then you can do this:
//This will create a custom datasource for the DataGridView.
var transactionsDataSource = tranList.Select(x => new
{
Amount = x.amount,
Type = x.type,
Balance = x.balance,
Date = x.date,
TransNum = x.transNum
Description = x.description
}).ToList();
//This will assign the datasource. All the columns you listed will show up, and every row
//of data in the list will populate into the DataGridView.
regView.DataSource = transactionsDataSource;
When I use the system.datetime as my datamember it returns a strange format in my datagridview.
My Datamembers looks like this:
[DataMember(Name = "TimeAdded")]
public DateTime TimeAdded;
And my AddStudent looks like this:
public void AddStudent(Student student)
{
student.StudentID = (++eCount).ToString();
student.TimeAdded = DateTime.Now; // not important more so the method to get the correct format
students.Add(student);
}
The output I get is 2012-04-12T03:10:42.8138255+01:00 is there a way to fix this?
I think you want:
student.TimeAdded = DateTime.Now;
Right now you're just converting a null time to local time.
Assuming you are referring to the fact that your dates are set to default(DateTime), then you want yamen's answer, if you don't like the format the DateTime is showing, then add another property onto Student that uses a standard DateTime format string like so.
public class Student
{
// existing date, don't expose this
public DateTime TimeAdded;
// expose this instead
[DataMember(Name = "TimeAddedString")]
public string TimeAddedString
{
//show as "Monday, January 01, 0001 12:00 AM"
get { return this.TimeAdded.ToString("f"); }
}
}
public class Student
{
public string TimeAddedString
{
get
{
return this.TimeAdded.ToString("dd/MM/yyyy hh:mm:ss");
// your desired format can goes here
}
}
}
public void AddStudent(Student student)
{
student.StudentID = (++eCount).ToString();
student.TimeAdded = DateTime.Now; // or your desired datetime
students.Add(student);
}
If you are converting incoming student time added you need to re-assign it:
public void AddStudent(Student student)
{
student.StudentID = (++eCount).ToString();
student.TimeAdded = student.TimeAdded.ToLocalTime();
students.Add(student);
}