Binding DropdownList with a nested json result - c#

I have for the most part successfully connected to an API endpoint and manage to deserialize nested json result and bind it to a gridview using Newtonsoft.Json serialization attributes.
I however cannot bind to a dropdownlist. What is the correct property name to use to pass the supplier name to my dropdownlist?
I can see the property I want to pass (supplier name) and have tried all possible strings I can think of but all I get is the class name to display.
The Supplier Name displays fine on the gridview
I can see the property I want to display supplier -> name
Binding Code
var readdata = comsumeapi.Result;
if (readdata.IsSuccessStatusCode)
{
var displayrecords = readdata.Content.ReadAsAsync<IList<CoupaPODetails>>();
displayrecords.Wait();
empobj = displayrecords.Result;
GridView1.DataSource = empobj;
GridView1.DataBind();
DropDownList1.DataSource = empobj;
DropDownList1.DataTextField = "supplier";
DropDownList1.DataBind();
}

It would have been quite helpful to see your JSON object code but I think I can glean what I need from the screenshots
You've bound the drop down list to supplier object, not the name of the supplier. I think you should probably make a new list of all the different suppliers and bind to that, something like:
var x = empobj.Select(e => e.supplier.name).Distinct().ToList();
(Your supplier object only seems to contain a name? This a bit odd why there would even be a supplier object at all if it only houses a string. I figured it might contain more than that , like a name and an ID. If it contains more than that and you want a display text and a value that are different, use one of the techniques from here to group by eg the value and then linq .Select(g => new ListItem(){Text = g.First(), Value = g.Key}) to generate a List<ListItem> that can be the datasource for your drop down)
Don't forget that you'll also need to bind to the grid's row data bound event to set the selected item in the drop down, detail for which is here

Related

Why DisplayMember doesn't work with manually added DataRow in ListBox?

Here is the thing I add manually few DataRow's to this.listBox1.Items and set in WinForms Designer the DisplayMember to column name but all I get displayed later is a list of type's name (System.Data...) .
How to solve this issue?
CODE:
list1.ForEach(x => this.listBox1.Items.Add(x)); //x is DataRow from a filled DataTable
The DisplayMember and ValueMember are applicable only when you use data binding (ListBox.DataSource). They work either with real properties, which can be retrieved by reflection, or via the .NET component model and the ICustomTypeDescriptor interface.
If you bind a DataTable directly, the GetEnumerator method and the IList implementation returns always DataRowView instances instead of DataRows. DataRowView implements the ICustomTypeDescriptor where the DisplayName can refer a column name.
So if you want to add some custom filtered list, I suggest you to create one from whatever source. For example:
listBox1.DisplayMember = "Name";
listBox1.ValueMember = "Value";
var list = Enumerable.Range(1, 10).Select(i => new {Name = i.ToString(), Value = i}).ToList();
listBox1.DataSource = list;
If Name property exists, you will see its value; otherwise, you will see the ToString of the items.
However, if you add the items programmatically (ListBox.Items), these properties are ignored and always the ToString of the items will be used.
Specify the column name you want to add to your list box:
list1.ForEach(x => this.listBox1.Items.Add(x["column_name"]));

Binding BindingList<string[]> to datagridview

Situation:
I am attempting to bind a BindingList<string[]> constructed from a LINQ to SQL query to a DataGridView.
Problem:
I either cannot make modification to the DataGridView after items are generated -or- I get a bunch of unwanted fields in my DataGridView (it depends on which iteration of my code I use) I have googled as hard as I can and tried implementing most of the solutions I have found online to no avail.
I know that string has no public property for its actual value. I am having a difficult time determining how to retrieve that (I believe is part of the problem).
C#
int item = (from p in CurrentConversion.Companies[lbCompanies.SelectedIndex].Modules
where p.ModuleName.Equals(clbModules.SelectedItem)
select p.ModuleId)
.FirstOrDefault();
BindingList<string[]> Data = new BindingList<string[]>((
from p in CurrentConversion.Companies[lbCompanies.SelectedIndex].QuestionAnswers
where p[2].Equals(item)
select new string[] { p[0].ToString(), p[3].ToString() })
.ToList());
dgvQuestions.DataSource = Data;
dgvQuestions.Refresh();
Unwanted Behavior:
This occurs after binding
Question:
Why is this happening?
How do I fix it?
Additional Information:
I am not sure what additional information may be need but I will supply what is requested.
Also if I switch to my other code iteration:
int item = (from p in CurrentConversion.Companies[lbCompanies.SelectedIndex].Modules where p.ModuleName.Equals(clbModules.SelectedItem) select p.ModuleId).FirstOrDefault();
var Data = new BindingList<object>((from p in CurrentConversion.Companies[lbCompanies.SelectedIndex].QuestionAnswers where p[2].Equals(item) select new {Question = p[0].ToString(), Answer = p[3].ToString() }).Cast<object>().ToList());
dgvQuestions.DataSource = Data;
dgvQuestions.Refresh();
dgvQuestions.Columns[1].ReadOnly = false;
I can see the data properly but I cannot edit the column I would like to.
You are binding to a list of string arrays, and you are getting the properties form the array. Most likely you want something like the following:
var Data = new BindingList<object>((
from p in CurrentConversion.Companies[lbCompanies.SelectedIndex].QuestionAnswers
where p[2].Equals(item)
select new {
Val1 = p[0].ToString(),
Val2 = p[3].ToString()
}).ToList());
The reason you're seeing those fields in the Grid is that you're binding each row to a string[]. So it is automatically displaying the properties of string[] as the columns. There is no built-in logic for the grid to parse an array and use the contents of the array as columns.
In order to get the DataGrid to display your data correctly, you should bind it to a custom type, and it will use the public properties of the type as columns.

C# NHibernate QueryOver select multiple Properties

In my C# application I use NHibernate to get all rooms from my database table 'room'.
using (ISession pSession = NHibernateHelper.OpenSession())
{
IList<Room> roomList = pSession.QueryOver<Room>().
Where(x => x.FloorID == 3).
.List();
}
The table 'room' and also my Mapping class (Room.cs) contains lets say the following properties:
roomID
hash
date
identifier
I have a DataGridView which should display my table entries from the database: the code is:
roomDataGridView.DataSource = roomList;
That works fine so far. But now I decide that I dont want to show all the properties from the Room class, I only want to display
roomID
identifier
I tried the following:
roomDataGridView.DataSource = listOfRoomPropertiesForCurrentFloor.Select(x => new {x.Identifier, x.RoomID });
Unfortunately this does not work...nothing gets printed in my DataGridView.
Question: How can I store all properties from the room table in my room model BUT ONLY show TWO of the four properties in the DataGridView?
Make sure your column names are defined in the DataGridView and create the object, basically assign the x.Identifier to the name "Identifier" so it can be picked up and call the ToList() function
roomDataGridView.DataSource = listOfRoomPropertiesForCurrentFloor
.Select(x => new {Identifier = x.Identifier, RoomID = x.RoomID }).ToList();
Expecting that DataGridView attribute AutoCreateColumns should be set to true. There are already answers:
c# Hide a property in datagridview with datasource
Is there an Attribute I can use in my class to tell DataGridView not to create a column for it when bound to a List
Extract:
Mark the property which should not be displayed with an attribute [Browsable(false)]

Add 2 or more field to value member of C# coding

I have table with 4 primary key fields. I load that in to drop down list in my WinForm application created by using C#.
On the TextChanged event of drop down list I have certain TextBox and I want to fill the information recived by the table for the certain field I selected by the drop down list.
So as I say the table having 4 fields. Can I get those all 4 fields into value member from the data set, or could you please tell me whether is that not possible?
Thank you.
Datatable dt=dba.getName();
cmb_name.ValueMember="id";
cmb_name.DisplayMember="name";
cmb_name.DataSource=dt;
this is normal format.. but i have more key fields.. so i need to add more key fields..
You can use DataSource property to bind your source data to the ComboBox (e.g. a List of Entities, or a DataTable, etc), and then set the DisplayMember property of the ComboBox to the (string) name of the field you want to display.
After the user has selected an Item, you can then cast the SelectedItem back to the original row data type (Entity, DataRow, etc - it will still be the same type as you put in), and then you can retrieve your 4 composite keys to the original item.
This way you avoid the SelectedValue problem entirely.
Edit:
Populate as follows:
cmb_name.DisplayMember = "name";
cmb_name.DataSource = dt;
// Ignore ValueMember and Selected Value entirely
When you want to retrieve the selected item
var selectedRow = (cmb_name.SelectedItem as DataRowView );
Now you can retrieve the 4 values of your PK, e.g. selectedRow["field1"], selectedRow["field2"], selectedRow["field3"] etc
If however you mean that you want to DISPLAY 4 columns to the user (i.e. nothing to do with your Table Key), then see here How do I bind a ComboBox so the displaymember is concat of 2 fields of source datatable?
cmb_name.DisplayMember = "name";
cmb_name.DataSource = dt;
DataRowView selectedRow = (cmb_name.SelectedItem as DataRowView );
The result will be here:
MessageBox.Show(selectedRow.Row[0].ToString());
MessageBox.Show(selectedRow.Row[1].ToString());
MessageBox.Show(selectedRow.Row[2].ToString());
MessageBox.Show(selectedRow.Row[3].ToString());
.....
If you want to get some data from a ComboBox in to a List you can use something like this
List<string> ListOfComboData = new List<string>();
ListOfComboData = yourComboBox.Items.OfType<string>().ToList<string>();
I have no real idea if this is what you mean as the question is very poorly structured. I hope this helps...
Edit: To put the selected text in to some TextBox use
yourTextBox.Text = youComboBox.Text;
in the SelectedIndexChanged event of your ComboBox.
You could follow the approach here with the following class:
public class ComboBoxItem
{
public string Text { get; set; }
public object[] PrimaryKey { get; set; }
}
private void Test()
{
ComboboxItem item = new ComboboxItem();
item.Text = "Item text1";
item.PrimaryKey = new object[] { primaryKey1, primaryKey2, primaryKey3, primaryKey4};
comboBox1.Items.Add(item);
comboBox1.SelectedIndex = 0;
MessageBox.Show((comboBox1.SelectedItem as ComboboxItem).Value.ToString());
}

How do you bind a data field value to a combobox index?

This may have been already asked but I can't seem to find this specific question, so here goes...
I have a form in C# where every textbox is bound to a field in a row. Rows can be cycled through by some buttons on the bottom but all the data displayed at a time in the from is from one row. Any changes that are made get updated back to the database when the user clicks "update"
One field (class) is an enumeration (0,1,2) where only the value is stored in the database, but doesn't mean much to the user. I was asked to make this more obvious to the user, so I decided to go with a dropdown style combo box. Since the database didn't have any reference to what the values meant, I decided to use the DataBindings instead of DataSource so I could just use the index as the data bind, but it seems that SelectedItem or Value are not the way to do this.
Here is my goal:
1 exists in database, so "B" is selected in combo box.
User selects "C" and updates the database, 2 is now stored in the database.
Any thoughts on what I need to get this working?
I assume you have a BindingSource on your form to bind to the data. You can bind the SelectedIndex property of the ComboBox as follows:
comboBox.DataBindings.Add("SelectedIndex", bindingSource, "PropertyInTheDataSource");
Actually I was able to bind it to a custom Object. It's a little too much work for such a simple task. But you have complete control on Display/Value pairs. Anyway, I thought I'd share and you decide:
Create a new class (say CustomItem) with 2 fields:
Public int Value{get;set;}
public string Title {get;set;}
Then in you form:
var item1 = new CustomItem() { Title = "A", Value = 10 };
var item2 = new CustomItem() { Title = "B", Value = 20 };
var item3 = new CustomItem() { Title = "C", Value = 30 };
var lst = new List<CustomItem>();
lst.Add(item1);
lst.Add(item2);
lst.Add(item3);
comboBox1.DataSource = lst;
comboBox1.DisplayMember = "Title";
comboBox1.ValueMember = "Value";
Now You have a databound combobox in case you don't have BndingSource in your form.
Just remember to define your class's Title and Value as properties otherwise it wouldn't work.

Categories