I believe I have read every document on the internet regarding this issue and I'm still having trouble.
I have a DataGridView populated by two List and combined into a var
topList = ShippingOrder.GetTopGroups();
topItemsList = ShippingOrder.GetCurrentTopSheet();
topList.AddRange(topItemsList);
var newList = topList.OrderBy(x => x.GroupOrder).ToList();
One of the columns in the DdataGridView is a ComboBox. It's populated from a separate List
alertList = GetComboBoxValue();
It's values are associated with the datagridview combox.
emailRecipientDataGridViewComboBoxColumn.DataSource = alertList;
emailRecipientDataGridViewComboBoxColumn.DataPropertyName = "EmailAlert";
emailRecipientDataGridViewComboBoxColumn.DisplayMember = "PopUpText";
emailRecipientDataGridViewComboBoxColumn.ValueMember = "PopUpValue";
The DataPropertyName corresponds to topList.EmailAlert.
The DisplayMember corresponds to alertList.PopUpText.
The ValueMember corresponds to alertList.PopUpValue.
Then the datagrid is filled
dgvTopSheet.DataSource = newList;
CurrencyManager cm = (CurrencyManager)(dgvTopSheet.BindingContext[newList]);
cm.Refresh();
Once the datagrid is filled, everything looks good except the combobox value is not showing. I can use the dropdown arrow and the values acquired from the alertList show up but the comboxbox value isn't binding the value from topList on load.
As I understand from the 50 plus documents I've read on the datagridviewcombobox the DataPropertName is the field needed to bind the control to the data in the dgv. This doesn't appear to be working and 4 hours later I'm a bit frustrated. Something simple seems to be alluding me greatly.
Any help is appreciated.
eta -
The BusinessObjects Class
public class BusinessObjects : INotifyPropertyChanged
{
public BusinessObjects()
{
}
private string popUpText;
public string PopUpText
{
get { return popUpText; }
set
{
popUpText = value;
OnPropertyChanged(new PropertyChangedEventArgs("PopUpText"));
}
}
private string popUpValue;
public string PopUpValue
{
get { return popUpValue; }
set
{
popUpValue = value;
OnPropertyChanged(new PropertyChangedEventArgs("PopUpValue"));
}
}
}
The ShippingOrder Class
public class ShippingOrder : INotifyPropertyChanged
{
private string emailAlert;
public string EmailAlert
{
get { return emailAlert; }
set
{
emailAlert = value;
OnPropertyChanged(new PropertyChangedEventArgs("EmailAlert"));
}
}
private string partNumber;
public string PartNumber
{
get { return partNumber; }
set
{
partNumber = value;
OnPropertyChanged(new PropertyChangedEventArgs("PartNumber"));
}
}
}
sample data looks like:
ShippingOrder.PartNumber = "1234Dp01".
ShippingOrder.EmailAlert = "BSmith#example.com".
BusinessObject.PopUpText = "Bob Smith".
BusinessObject.PopUpValue = "BSmith#example.com".
Related
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;
I have a DataGrid in my View as shown below.,
My Question is how can I Append the values from the textboxes to the row datagrid
I have make sure that the Model has All the properties, When I click on the Add button it overwrites the dataGrid and shows only one latest record the and my ViewModel look like this:
class BatchItemsViewModel : ViewModelBase
{
public SearchItemsModel msearchItems { get; set; }
ObservableCollection<SearchItemsModel> _BatchItemsGrid;
public ObservableCollection<SearchItemsModel> BatchItemsGrid
{
get { return _BatchItemsGrid; }
set
{
_BatchItemsGrid = value;
OnPropertyChanged("BatchItemsGrid");
}
}
private ICommand _addDataToBatchGrid;
public ICommand addDataToBatchGrid
{
get
{
return _addDataToBatchGrid;
}
set
{
_addDataToBatchGrid = value;
}
}
public BatchItemsViewModel()
{
msearchItems = new SearchItemsModel();
addDataToBatchGrid = new RelayCommand(new Action<object>(AddDataInBatchGrid));
}
public void AddDataInBatchGrid(object obj)
{
ObservableCollection<SearchItemsModel> batchGridData = new ObservableCollection<SearchItemsModel>();
var data = new SearchItemsModel
{
BatchNumber = msearchItems.BatchNumber,
MFDDate = msearchItems.MFDDate,
ExpiryDate = msearchItems.ExpiryDate,
Quantity = msearchItems.Quantity,
};
batchGridData.Add(data);
BatchItemsGrid = batchGridData; // HERE I am overwriting the datagrid
//How can I Append the batchGridData to BatchItemsGrid (BatchItemsGrid.Append(batchGridData)???)
}
}
NOTE: I have gone through the other threads as well in the community for the similar posts but I couldn't find the appropriate and please correct me if I am going in wrong direction.
public void AddDataInBatchGrid(object obj)
{
var data = new SearchItemsModel
{
BatchNumber = msearchItems.BatchNumber,
MFDDate = msearchItems.MFDDate,
ExpiryDate = msearchItems.ExpiryDate,
Quantity = msearchItems.Quantity,
};
this.BatchItemsGrid.Add(data);
}
...Should do the trick. (don't replace the whole collection, just add items to it and let the notification events handle the UI updates)
What I would like to do is to populate a drop down menu from a database.
First of all I plan to use a combo box.
I have created an object that contains the data that I need to take from the database. The object is as follows
namespace RLMD
{
public class FlashCardLevel
{
private int intFCLId;
private String strFCLName;
public FlashCardLevel(int intFCLId, String strFCLName)
{
this.intFCLId = intFCLId;
this.strFCLName = strFCLName;
}
public int IntFCLId
{
get { return intFCLId; }
set { this.intFCLId = value; }
}
public String StrFCLName
{
get { return strFCLName; }
set { this.strFCLName = value; }
}
}
}
What I need to do is to add a list of items from a database, but for ease of use I have simulated given some sample data.
public List<FlashCardLevel> Rifle(List<FlashCardLevel> fcLevel)
{
fcLevel.Add(new FlashCardLevel(1, "Severe"));
fcLevel.Add(new FlashCardLevel(2, "Moderate"));
fcLevel.Add(new FlashCardLevel(3, "Mild"));
fcLevel.Add(new FlashCardLevel(4, "Slight"));
return fcLevel;
}
I'm calling the method here.
List<FlashCardLevel> fcLevel = new List<FlashCardLevel>();
talkToDatabase.Rifle(fcLevel);
this.comboCardLevel.DataSource = fcLevel;
this.comboCardLevel.DisplayMember = "Name";
this.comboCardLevel.ValueMember = "Value";
The combobox is displaying no information.
I would appreciate any help
Updated:
The DisplayMember Property should be referring to FlashCardLevel (class), Property StrFCLName and ValueMember should be pointing to IntFCLId.
List<FlashCardLevel> fcLevel = new List<FlashCardLevel>();
talkToDatabase.Rifle(fcLevel);
this.comboCardLevel.DataSource = listFromDatabase;
this.comboCardLevel.DisplayMember = "StrFCLName";
this.comboCardLevel.ValueMember = "IntFCLId";
The DisplayMember and ValueMember should point to your properties name.
this.comboCardLevel.DisplayMember = "IntFCLId";
this.comboCardLevel.ValueMember = "StrFCLName";
I have a combo box that populates data from the database, which, based on a list box selection populates the data within a given list box through an SQL query. Problem is that the display member property wont show. I wont show the back-end sql because that works fine and the list box actually populates just not the display member. So the data in the list box is blank.
Here is the code:
The Combobox method:
private void populateFromMedication()
{
MedicationList medicationItem = new MedicationList();
// if item is selected
if( !( ( Locations )cmbLocationDescriptionList.SelectedItem == null ) )
{
// set location to be the seletect location from the combo
location = ( Locations )cmbLocationDescriptionList.SelectedItem;
List<MedicationList> fromMedicatitionList = new List<MedicationList>();
// retrieve a list of medication from the database
fromMedicatitionList = LocationData.RetrieveMedicationByLocation( location.LocationID, GlobalVariables.SelectedResident.ResidentID );
//bind the list for to the medication list
lstMedicationForCurrentLocation.ItemsSource = fromMedicatitionList;
lstMedicationForCurrentLocation.DisplayMemberPath = "Description";
}
}
On form Initialization:
public FormInitialize()
{
InitializeComponent();
LoadData();
LoadResidentData();
populateFromMedication();
}
MedicationList Class:
public class MedicationList
{
public int MedicationID { get; set; }
public string Description
{
get
{
return Description;
}
set
{
Description = value;
OnPropertyChanged( "Description" );
}
}
}
You need to check that
1) There is a property in MedicationList by the name Description and that OnPropertyChanged is applied on its setter.
string _Description;
public string Description
{
get
{
return _Description;
}
set
{
_Description = value;
OnPropertyChanged("Description");
}
}
For more on OnPropertyChanged read this
2) Try giving Displaymember before providing Itemsource.
I have the following issue: I am creating a Windows Phone 7 application and I am using a ListBox which is bound to an ObservableCollection people. The implementation of this you see below:
public class Person
{
private string _id { get; set; }
private string _name { get; set; }
public Person(string Id, string Name, string Title)
{
_id = Id;
_name = Name;
}
public string Id
{
get { return _id; }
set
{
_id = value;
FirePropertyChangedEvent("Id");
}
}
public string Name
{
get { return _name; }
set
{
_name = value;
FirePropertyChangedEvent("Name");
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void FirePropertyChangedEvent(string propertyName)
{
if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
The people Collection is filled with Person objects. They are created in the following function... listValues is my ListBox.
void svc_GetHierachyCompleted(object sender, HCMobileSvc.GetHierachyCompletedEventArgs e)
{
var data = e.Result.ToArray();
listValues.ItemsSource = null;
people.Clear();
int i = 0;
foreach(var item in data)
{
if (i == 0)
{
// Manager
mgrField1.Text = item[1].ToString();
mgrField2.Text = item[2].ToString();
i++;
}
else
{
// Untergebenen hinzufügen
people.Add(new Person(item[0].ToString(), item[1].ToString(), item[2].ToString()));
}
}
// Update List
listValues.ItemsSource = people;
}
Now I have a DataTemplate with two textblocks bound to both properties Id and Name. When the SelectionChanged event is fired I try to rebuild the entire list (so I call the function above again) using the following code:
string id = people[listValues.SelectedIndex].Id;
MessageBox.Show(id);
CreateHierachy(id);
The CreateHierachy just only queries a WebService which then goes into the method above. The problem is, as soon as I select a value in the ListBox I get the following error:
ArgumentOutOfRangeException {"\r\nParameter name: index"}
The error is caused by the line listValues.SelectedIndex.
I absolutely have no idea why that happens. What I know is that the MessageBox shows me the correct SelectedIndex value. What I also know is that when I remove the line people.Clear() that the error goes away but the ListBox does not get Updated.
Any ideas where the problem might be?
Thanks!!!
Bye,
WorldSignia
You should check here for SelectedIndex being >= 0:
if (listValues.SelectedIndex >= 0)
string id = people[listValues.SelectedIndex].Id;