I create one datalayer method
public static List<SegmentBL> GetAllSegment(string SortDirection, string SortExpression)
{
var ds = DBHelper.GetDatabase().ExecuteDataSet("UDS_Select_SegmentMaster");
var val = ds.Tables[0].AsEnumerable().Select(r => new SegmentBL
{
_SegmentId = Convert.ToInt32(r[0].ToString()),
_SegmentName = r[1].ToString()
});
List<SegmentBL> list = val.ToList();
return list;
}
from that I create one Bussiness logic method
public DropDownList GetAll(string SortDirection, string SortExpression)
{
var list = new DropDownList();
list.DataSource = SegmentDL.GetAllSegment(SortDirection, SortExpression);
list.DataTextField = "_SegmentName";
list.DataValueField = "_SegmentID";
list.DataBind();
ListItem item = new ListItem();
item.Text = "--Select--";
item.Value = "0";
list.Items.Insert(0, item);
return list;
}
Finally Presentation Layer Method for filling dropdownlist
private void FillSegment()
{
ddlSegment.DataSource = seg.GetAll(General.SortAscending,"SegmentID").Items;
ddlSegment.DataBind();
ddlSegment.DataTextField = "_SegmentName";
ddlSegment.DataValueField = "_SegmentID";
}
It's working fine except the DataTextField and DataValueField not assign properly. Currently DataTextField and DataValueField same. What is mistake I did in above code.
You are binding before the elements are added to the datasource bind after the elements being added. You may pass dropdownlist to your method intead of creating local drop down in GetAll method.
public DropDownList GetAll(string SortDirection, string SortExpression, DropDownList list)
{
// var list = new DropDownList(); //Remove this line
list.DataSource = SegmentDL.GetAllSegment(SortDirection, SortExpression);
list.DataTextField = "_SegmentName";
list.DataValueField = "_SegmentID";
ListItem item = new ListItem();
item.Text = "--Select--";
item.Value = "0";
list.Items.Insert(0, item);
list.DataBind();
return list;
}
Move the Databind() line.
private void FillSegment()
{
ddlSegment.DataSource = seg.GetAll(General.SortAscending,"SegmentID").Items;
ddlSegment.DataTextField = "_SegmentName";
ddlSegment.DataValueField = "_SegmentID";
ddlSegment.DataBind(); //After and not before defining the fields value
}
Related
I have a combobox cmbCourses and I am populating my this code
var _courses = new DatabaseHandler().GetAllCourses();
foreach (var a in _courses)
{
ComboBoxItem item = new ComboBoxItem();
item.Text = a.Value;
item.Value = a.Key;
cmbCourses.Items.Add(a.Value);
}
public Dictionary<int, String> GetAllCourses()
{
Dictionary<int, String> courses = new Dictionary<int, String>();
var connection = DatabaseConnector.Instance();
if(connection.IsConnect())
{
connection.Connection.Open();
string query = "SELECT * FROM courses";
cmd = new MySqlCommand(query, connection.Connection);
cmd.Prepare();
var result = cmd.ExecuteReader();
while(result.Read())
{
courses.Add(result.GetInt16(0), result.GetString(1));
}
}
connection.Connection.Close();
return courses;
}
But when I try to get key it shows value instead
using this code
MessageBox.Show(cmbCourses.SelectedItem.ToString());
You are only adding the value to the ComboBox. Add the KeyValuePair to the ComboBox and set the DisplayMemberPath and SelectedValuePath properties:
var _courses = new DatabaseHandler().GetAllCourses();
foreach (var a in _courses)
{
cmbCourses.Items.Add(a);
}
cmbCourses.DisplayMemberPath = "Value";
cmbCourses.SelectedValuePath = "Key";
You can then get the key of the selected item like this:
var item = cmbCourses.SelectedItem as KeyValuePair<int, String>;
if (item != null)
MessageBox.Show(item.Key);
You can use the GetValue() method to get the value rather than the display text:
MessageBox.Show(cmbCourses.GetValue().ToString());
Seems you have problem in adding items to your combobox, you are adding only the value by this line cmbCourses.Items.Add(a.Value);, Can you try this :
cmbCourses.Items.Add(item);
Then you can use this line to get the value :
MessageBox.Show(cmbCourses.SelectedValue.ToString());
Don't forget to set these for your combobox :
cmbCourses.DisplayMember = "YOUR DISPLAY FIELD NAME";
cmbCourses.ValueMember = "YOUR VALUE FIELD NAME";
I want to add some items to a combobox like this :
public class ComboboxItem
{
public string Text { get; set; }
public object Value { get; set; }
public override string ToString()
{
return Text;
}
}
ComboboxItem item = new ComboboxItem();
item.Text = "choose a server...";
item.Value = "-1";
ComboBox_Servers.Items.Add(item);
...
and read those texts and values in SelectedIndexChanged like this :
private void ComboBox_Servers_SelectedIndexChanged(object sender, EventArgs e)
{
MessageBox.Show(ComboBox_Servers.SelectedValue.ToString());
}
But SelectedValue is always null! what is the problem and how can I fix it?
You can take the SelectedItem and cast it back to your class and access its properties.
MessageBox.Show(((ComboboxItem)ComboBox_Countries_In_Silvers.SelectedItem).Value);
Edit You can try using DataTextField and DataValueField, I used it with DataSource.
ComboBox_Servers.DataTextField = "Text";
ComboBox_Servers.DataValueField = "Value";
try this:
ComboBox cbx = new ComboBox();
cbx.DisplayMember = "Text";
cbx.ValueMember = "Value";
EDIT (a little explanation, sory, I also didn't notice your combobox wasn't bound, I blame the lack of caffeine):
The difference between SelectedValue and SelectedItem are explained pretty well here: ComboBox SelectedItem vs SelectedValue
So, if your combobox is not bound to datasource, DisplayMember and ValueMember doesn't do anything, and SelectedValue will always be null, SelectedValueChanged won't be called. So either bind your combobox:
comboBox1.DisplayMember = "Text";
comboBox1.ValueMember = "Value";
List<ComboboxItem> list = new List<ComboboxItem>();
ComboboxItem item = new ComboboxItem();
item.Text = "choose a server...";
item.Value = "-1";
list.Add(item);
item = new ComboboxItem();
item.Text = "S1";
item.Value = "1";
list.Add(item);
item = new ComboboxItem();
item.Text = "S2";
item.Value = "2";
list.Add(item);
cbx.DataSource = list; // bind combobox to a datasource
or use SelectedItem property:
if (cbx.SelectedItem != null)
Console.WriteLine("ITEM: "+comboBox1.SelectedItem.ToString());
Dictionary<int,string> comboSource = new Dictionary<int,string>();
comboSource.Add(1, "Sunday");
comboSource.Add(2, "Monday");
Aftr adding values to Dictionary, use this as combobox datasource:
comboBox1.DataSource = new BindingSource(comboSource, null);
comboBox1.DisplayMember = "Value";
comboBox1.ValueMember = "Key";
This is similar to some of the other answers, but is compact and avoids the conversion to dictionary if you already have a list.
Given a ComboBox "combobox" on a windows form and a class SomeClass with the string type property Name,
List<SomeClass> list = new List<SomeClass>();
combobox.DisplayMember = "Name";
combobox.DataSource = list;
Which means that combobox.SelectedItem is a SomeClass object from list, and each item in combobox will be displayed using its property Name.
You can read the selected item using
SomeClass someClass = (SomeClass)combobox.SelectedItem;
combo1.DisplayMember = "Text";
combo1.ValueMember = "Value";
combo1.Items.Add(new { Text = "someText"), Value = "someValue") });
dynamic item = combo1.Items[combo1.SelectedIndex];
var itemValue = item.Value;
var itemText = item.Text;
Unfortunatly "combo1.SelectedValue" does not work, i did not want to bind my combobox with any source, so i came up with this solution. Maybe it will help someone.
I am working on exporting data and right now some fields export the value, instead of the text. So I am saving the object that returns the text and value to a list box and matching it to the value in the listbox from the object like so:
MaterialDB materials = new MaterialDB();
DropDownList listBoxMaterials = new DropDownList();
listBoxMaterials.DataSource = materials.GetItems(ModuleId, TabId);
listBoxMaterials.DataBind();
string materialString = "";
foreach (ListItem i in listBoxMaterials.Items)
{
if (i.Value == row["MaterialTypeID"].ToString())
{
materialString = i.Text;
}
}
When I use this for the i.Value it always returns "System.Data.DataRowView" instead of the actual value. I'm doing this all in code behind. Anyway around this to get it to work?
Thanks!
You need to set the DataTextField and DataValueField properties of the DropDownList. Example:
MaterialDB materials = new MaterialDB();
DropDownList listBoxMaterials = new DropDownList();
listBoxMaterials.DataSource = materials.GetItems(ModuleId, TabId);
listBoxMaterials.DataTextField = "MaterialName";
listBoxMaterials.DataTextValue = "MaterialID";
listBoxMaterials.DataBind();
string materialString = "";
foreach (ListItem i in listBoxMaterials.Items)
{
if (i.Value == row["MaterialTypeID"].ToString())
{
materialString = i.Text;
}
}
I have a combobox with objects of Foo type, here is the Foo class:
public class Foo
{
public string name { get; set; }
public string path { get; set; }
}
The Foo.name is the displayed text in the combobox and Foo.path is the value of the selected option.
I want to delete an option from the combobox after some operation I made.
I've tried these ways:
1
comboBox2.Items.Remove(#comboBox2.Text);
2
comboBox2.Items.Remove(#comboBox2.SelectedValue.ToString());
3
Foo ToDelete = new Foo();
ToDelete.name = #comboBox2.Text;
ToDelete.path = #comboBox2.SelectedValue.ToString();
comboBox2.Items.Remove(ToDelete);
Nothing works for me. : / How to do this?
UPDATE
This is how I'm initializing my combobox:
string[] filePaths = Directory.GetFiles(sites.paths[comboBox1.SelectedIndex]);
List<Foo> combo2data = new List<Foo>();
foreach (string s in filePaths)
{
Foo fileInsert = new Foo();
fileInsert.path = s;
fileInsert.name = Path.GetFileName(s);
combo2data.Add(fileInsert);
}
comboBox2.DataSource = combo2data;
comboBox2.ValueMember = "path";
comboBox2.DisplayMember = "name";
comboBox2.Items.Remove(comboBox2.SelectedValue); will only remove from the combobox, not from the datasource bound to the combobox. You may remove it from the datasource and re-bind the datasource.
Use ComboBox.SelectedIndex property.
For example: let me have comboBox1 added to the form. In the delete button:
if (comboBox1.SelectedIndex >= 0)
comboBox1.Items.RemoveAt(comboBox1.SelectedIndex);
combox1.Remove(takes an object)
Object selectedItem = comboBox1.SelectedItem;
So you cna do it this way combox1.Remove(selectedItem);
Suppose you want to Remove Items by Index:
combo2data.RemoveAt(0); //Removing by Index from the dataSource which is a List
//Rebind
comboBox2.DataSource = null;
comboBox2.DataSource = combo2data;
comboBox2.ValueMember = "path";
comboBox2.DisplayMember = "name";
Suppose you want to Remove by seraching for a member value
Foo item = combo2data.Where(f => f.name.Equals("Tom")).FirstOrDefault();
if (item != null)
{
combo2data.Remove(item);
comboBox2.DataSource = null;
comboBox2.DataSource = combo2data;
comboBox2.ValueMember = "path";
comboBox2.DisplayMember = "name";
}
These 2 commands will remove an item from your data source.
list.Remove((Foo)comboBox1.SelectedItem);
or
list.Remove(list.Find(P=>P.name == comboBox1.SelectedText));
I think the secret is to first attribute null to the datasource and after rebind to a modified collection:
int idToRemove = 1;
var items = (cbx.DataSource as List<MyEntity>);
items.RemoveAll(v => v.Id == idToRemove);
rebindCombobox(cbx, items, "Name", "Id");
private void rebindCombobox(ComboBox cbx, IEnumerable<Object> items, String displayMember, String valueMember)
{
cbx.DataSource = null;
cbx.DisplayMember = displayMember;
cbx.ValueMember = valueMember;
cbx.DataSource = items;
}
Perhaps delete all items in the Combobox with
comboBox.Items.Clear();
I've got a very simple object:
public class DocumentType
{
private int id;
private string name;
public int ID
{
get { return this.id; }
set { this.id = value; }
}
public string Name
{
get { return this.name; }
set { this.name = value; }
}
}
I've got a list of DocumentType objects: List<DocumentType> documentTypes = getDocuments();
I'm working on a custom control where I'm trying to dynamically create a repeater and dynamically bind it to my object list. Here's my code:
private Repeater docList;
docList = new Repeater();
docList.DataSource = documentTypes;
docList.DataBind();
foreach (RepeaterItem repeatItem in docList.Items)
{
// if condition to add HeaderTemplate Dynamically only Once
if (repeatItem.ItemIndex == 0)
{
RepeaterItem headerItem = new RepeaterItem(repeatItem.ItemIndex, ListItemType.Header);
HtmlGenericControl hTag = new HtmlGenericControl("h4");
hTag.InnerHtml = "Header";
repeatItem.Controls.Add(hTag);
}
// Add ItemTemplate DataItems Dynamically
RepeaterItem repeaterItem = new RepeaterItem(repeatItem.ItemIndex, ListItemType.Item);
Label lbl = new Label();
// This part is completely broken!
lbl.Text = string.Format("Content: {0} {1} <br />", (DocumentType)repeaterItem.DataItem).ID, repeaterItem.NamingContainer);
repeatItem.Controls.Add(lbl);
// Add SeparatorTemplate Dynamically
repeaterItem = new RepeaterItem(repeatItem.ItemIndex, ListItemType.Separator);
LiteralControl ltrlHR = new LiteralControl();
ltrlHR.Text = "<hr />";
repeatItem.Controls.Add(ltrlHR);
}
The header and separator work great. I can't figure out how to bind the item template to the current item to get it to display. I know what I have in there right now is completely broken, but I've tried several variations with no luck.
Thanks in advance for any help or pointers in the right direction!
The problem you are having is that you are assuming that the RepeaterItem contains the data. It does not. It contains the information on how to display the individual item. You need to use that index to get back into the data source. I'm not sure if there's a better way, but below is how I got it to work...
List<DocumentType> documentTypes = new List<DocumentType>();
documentTypes.Add(new DocumentType(){ ID=1, Name="Bob"});
documentTypes.Add(new DocumentType() { ID = 2, Name = "Tom" });
documentTypes.Add(new DocumentType() { ID = 3, Name = "Chick" });
Repeater docList = new Repeater();
docList.DataSource = documentTypes;
docList.DataBind();
foreach (RepeaterItem repeatItem in docList.Items)
{
int index = repeatItem.ItemIndex;
DocumentType docType = ((IList<DocumentType>)docList.DataSource)[index];
// if condition to add HeaderTemplate Dynamically only Once
if (index == 0)
{
HtmlGenericControl hTag = new HtmlGenericControl("h4");
hTag.InnerHtml = "Header";
repeatItem.Controls.Add(hTag);
}
// Add ItemTemplate DataItems Dynamically
RepeaterItem repeaterItem = new RepeaterItem(repeatItem.ItemIndex, ListItemType.Item);
Label lbl = new Label();
// This part is completely broken!
lbl.Text = string.Format("Content: {0} {1} <br />", docType.ID, repeaterItem.NamingContainer);
repeatItem.Controls.Add(lbl);
// Add SeparatorTemplate Dynamically
LiteralControl ltrlHR = new LiteralControl();
ltrlHR.Text = "<hr />";
repeatItem.Controls.Add(ltrlHR);
}
StringBuilder sb = new StringBuilder();
docList.RenderControl(new HtmlTextWriter(new StringWriter(sb)));
Text = sb.ToString();