Dependant dropdownlist(cascading) - c#

I have an existing dropdownlist that lists names.
I am trying to create another drop down list that contaings all Alphabets
What i am trying to accomplish is:
When a user selects an alphabet from the Alphabet Dropsownlist, the second dropdwonlist will populate all the names that start with the selected Alphabets.
I had this code.
`NamesDropDownList.SelectedValue = (NamesDropDownList.DataValueField).Where(NamesDropDownList.SelectedItem.Value).Contains(AlphabetsDropDownList.SelectedItem.Value);`
but it is giving me an error:
Error Message: string does not contain a definition of Where, and the method overload contains invalid arguments.
Any Help Or approach to this problem.
thanks

There are several things wrong with that one line of code. Let's start with the source of the data. This is not the source of your data:
NamesDropDownList.DataValueField
That's just a string property on a DropDownList. You can't select records from that, you have to select them from the database (or wherever your backing data is). You haven't provided that context, so I'm going to suppose it's some standard LINQ-queryable data source. Let's say, for the sake or example, that it's something like this:
dbContext.Names
That is what you'd attach a "where" clause to in order to select data. So now let's move on to that clause and see what it looks like. For starters, it doesn't look like this:
.Where(NamesDropDownList.SelectedItem.Value).Contains(AlphabetsDropDownList.SelectedItem.Value)
The .Where() method doesn't expect a string, it expects a Func<T, bool> as a predicate. Inside that predicate is where you'd have your .Contains(), which would operate on the string and not on the whole collection. So it might look something like this:
dbContext.Names.Where(n => n.Name.Contains(AlphabetsDropDownList.SelectedItem.Value))
What this line of code essentially does is:
From the Names table in the database, select all records where the Name column contains the given value.
That would give you the filtered set of records from the data source, which could then be used to bind to the next DropDownList.

Look into creating an event handler on the parent DDL
Dynamic DDL Event Handler
DropDownList Change Event

Just have the SelectedIndexChanged() event handler from the alphabet dropdownlist populate the names list:
private DataSet GetNameData()
{
string sql = "select Firstname, Lastname from Names where Firstname like '#Letter%';";
SqlParameter arg = new SqlParamter("#Letter", ddlLetter.SelectedItem.Value));
SqlCommand cmd = new SqlCommand, sql, ConnectionString);
cmd.Paramters.Add(arg);
SqlDataAdapter da = new SqlDataAdapter();
DataSet ds = new DataSet();
da.SelectCommand = cmd;
da.Fill(ds);
return ds;
}
private void ddlLetter_SelectedIndexChanged(object sender, EventArgs e)
{
DataSet Names = GetNameData();
ddlNames.DataSource = Names.Table[0];
ddlNames.DataTextField = "Firstname";
ddlNames.DataValueField = "Id";
ddlNames.DataBind();
ddlNames.Items.Insert(0, new ListItem("Please select a name", 0);
}
Make sure you have the alphabet dropdownlist set with AutoPostBack="true" otherwise it won't work.
Hope this helps!

Related

Drop Down List is not finding correct value

When I connect my dropdownlist (cmbStaff) and then try and apply a selected value to cmbStaff it will always return the very first value within the dropdownlist.
Here is the code I use to bind data to the dropdownlist
if(!IsPostBack)
{
String Sql = #" select * from SupportTeam";
SqlConnection conn = new SqlConnection(Properties.Resources.cString);
SqlDataAdapter DA = new SqlDataAdapter(Sql, Properties.Resources.cString);
DataSet DS = new DataSet();
DA.Fill(DS, "SupportTeam");
cmbStaff.DataValueField = "SupportTeamID";
cmbStaff.DataTextField = "SupportTeamName";
cmbStaff.DataSource = DS;
cmbStaff.DataBind();
cmbStaff.Items.Insert(0, "--Please select a support team--");
}
But in future code when I try and apply a selected value to the drop down it will always select the first index.
For example, if I do this
cmbStaff.SelectedValue = "TEL";
When I debug, it will always return this
cmbStaff.SelectedValue = "--Please select a support team--"
cmbStaff.SelectedIndex = 0;
Why is it doing this.
I have data stored in the table as the combo works it just does not set starting index to the value that I want and that is what I need it to do.
Here is a snippet of the data I have stored in the SupportTeam Table
Sorry if is seem vague, thanks in advance!
That is not how you set a selected value for a drop down list. you use the findbyvalue function and set selected =true
cmbStaff.Items.FindByValue("TEL").Selected = true;
The problem I was having was Sql Related. It keep adding blank spaces onto the end of the value I was entering. I changed
String Sql = #" select * from SupportTeam";
to
String Sql = #" select rtrim(SupportTeamID) as SupportTeamID, rtrim(SupportTeamName) as SupportTeamName from SupportTeam";
It now works. I cannot find the exact reason why this happened. Of course the .Trim() function will also work when declaring Sql variables in c#.

Putting elements via array into a Listbox

first show my code:
datTable = new DataTable();
sqlCmd = new SqlCommand("SELECT [CustomerId] FROM
[DataSource]", connection);
sqlDatAdapter = new SqlDataAdapter(sqlCmd.CommandText, connection);
sqlDatAdapter.Fill(datTable);
customer.DisplayMember = "CustomerId";
customerListbox.DataSource = datTable;
So that works fine to fill the Listbox with a column from a database in SQL. What I wanted to do is a loop where he automatically fills in more than one Listbox. It works for loop with the SQL Statements but how can I handle the line
customer.DisplayMember = "CustomerId"
Is there a way or have I to duplicate this piece of code over and over again and change the lines manually? I tried to create an array of objects and fill it with customer.DisplayMember etc but that does not work.
What I mean is: I will do this piece of code more than once and everytime just the Listbox and the SQL Column changes. So fill different Listboxes with different columns. So maybe an array or a list with objects like
customer.DisplayMember, product.DisplayMember etc
If I understand what you mean, you want to populate multiple list boxes. You could create a method to populate all the list boxes by passing in a dictionary of the list boxes/data member, and the datatable. Something like this:
private void PopulateListBoxes(Dictionary<ListBox, string> ListBoxCollection, DataTable CustomerTable)
{
foreach(var key in ListBoxCollection.Keys)
{
key.DisplayMember = ListBoxCollection[key];
key.DataSource = CustomerTable;
}
}
And you could call like this:
//this DataTable should contain data for all list boxes
sqlDatAdapter.Fill(dataTable);
Dictionary<ListBox, string> myListBoxes = new Dictionary<ListBox, string>();
//add your existing list boxes here with the corresponding data member
myListBoxes.Add(customerListBox, "CustomerID");
myListBoxes.Add(productListBox, "ProductID");
//add more here
PopulateListBoxes(myListBoxes, dataTable);

DataGridView bound with binding list displays blank rows

I have table in my database stored in SQL Server 2012 and through this table I am iterating and adding new object in my binding list. This list is then set as datasource for my DataGridView.
As I understand, the DataGridView should create columns and fill the rows with data, but when I run the build, I only see blank rows. Their count is matching the count of rows in table and I also debugged with breakpoints so I have determined that I really have my datasource filled with data, but I cannot figure those blank rows out.
This is method I use for creating dataset and filling the binding list
public void selectCars()
{
string connString = #"Data Source=POHJOLA\SQLEXPRESS;Initial Catalog=BlueCars;Integrated Security=True";
using (SqlConnection connection = new SqlConnection(connString))
{
connection.Open();
string query = "SELECT * FROM Car ORDER BY CarID ASC";
SqlCommand command = new SqlCommand(query, connection);
using (SqlDataAdapter adapter = new SqlDataAdapter(command))
using (DataSet result = new DataSet())
{
adapter.Fill(result);
foreach (DataRow row in result.Tables[0].Rows)
{
carsList.Add(new Car(Convert.ToInt32(row[0]), row[1].ToString(), row[2].ToString(), row[3].ToString(), Convert.ToDecimal(row[4]),Convert.ToInt32(row[5]),row[6].ToString(),row[7].ToString() ));
}
}
}
}
This is my initialization
public managerCarForm()
{
InitializeComponent();
selectCars();
carsGrid.DataSource = carsList;
}
Also I should probably add, that I created columns manually in designer and set datanameproperty to parameters of the car class
I am not getting any exception or error here..
Thanks very much in advance!
I came across the exact same problem in VB.
I Found out that the solution was this:
(I´ll just write my code in VB you can translate it).
Before setting the DataSource of the grid, you should Clear the grid out.
carsGrid.DataSource = Nothing
carsGrid.Rows.Clear()
carsGrid.Columns.Clear()
Then set your grid DataSource as usual. In My case:
carsGrid.DataSource = GetEmptyObject._Get()
Hope it Helps.
foreach (DataRow row in result.Tables[0].Rows)
{
carsList.Add(new Car(Convert.ToInt32(row[0]), row[1].ToString(), row[2].ToString(), row[3].ToString(), Convert.ToDecimal(row[4]),Convert.ToInt32(row[5]),row[6].ToString(),row[7].ToString() ));
}
Please check your carList by applying a breakpoint after foreach loop to verify it contains at least a single data row. And also check your query.
If your application is an ASP.NET
try to modify your code as below..
public managerCarForm()
{
InitializeComponent();
selectCars();
carsGrid.DataSource = carsList;
carsGrid.Databind();
}
Normally this happens when you have manually added the columns in design time.
Or you have AutoGenerateColumns = false;
If you use AutoGenerateColumns = true; the columns will be/should be auto generated.
To solve this:
Right click on the grid -> Edit Columns.
Go to property: DataPropertyName
Set that to the variable name that you bind to (the table column name in your case).
(You say you have done that, but the value here should exactly match what you have in your list. I have made a DTO class and via a loop I have populated a List of my own and set the names to match the properties of that DTO. This should solve it for you.)

Drop Down List not getting populated

I have a c# code line as,
using (SqlDataSource sqlds = new SqlDataSource(ConnectionString(), SelectCommand()))
{
drop1.DataSource = sqlds;
drop1.DataTextField = "UserName";
drop1.DataBind();
}
now it's not populating my dropdownlist,
<asp:DropDownList id="drop1" runat="server" />
so I want to check if sql is returning data or not
if i put line break, I am not sure how to find out if sql is returning data, I am using using select statement and connection string for gridview and it works but not with drop down list
Be sure you have your sqlquery into select command then you need convert you
sqldatasource select command into dataview.
string query = "select yourfield from yourtable";
using (SqlDataSource sqlds = new SqlDataSource(conn.ConnectionString, query))
{
System.Data.DataView dv = (System.Data.DataView)sqlds.Select(DataSourceSelectArguments.Empty);
if (dv.Count > 0)
{
DropDownList1.DataSource = sqlds;
DropDownList1.DataTextField = "yourfield";
DropDownList1.DataBind();
}
}
You should be able to put a breakpoint on drop1.DataSource = sqlds; and then move your mouse over sqlds and it should show you how many rows are contained in the DataSource.
your way of binding datasource to the dropdown is correct and same thing is working for me.
Possible errors can be
in the connectionString. Verify if it is correct.
in the Select Query. Verify if the SelectCommand() methods returns correct sql query.
use Selected event of the SqlDataSource to verify whether it returned any row i.e
sqlds.Selected += new SqlDataSourceStatusEventHandler(sdl_Selected);
where sql_Selected is:
void sdl_Selected(object sender, SqlDataSourceStatusEventArgs e)
{
var a = e.AffectedRows;
}
as a Side note - make sure your select query doesn't contain any string concatenation prone to sql injection. i.e. SELECT UserName from [TableName] where certainCol ="+ variable.
Don't do it
provide a sql parameter instead, and add the SelectParameters to your SqlDataSource

TextBox AutoComplete from MDB

I have a .Net 4 Windows Forms app that uses a Microsoft Access Database with one table which has three columns CityCode, Name and Country.
What I want to do is have an autocomplete which shows the “Name” and “Country” but when selected the “CityCode” Value is shown in the textbox. In addition if the user types A City Code eg LAX as they type L it would list all the cities whose code or Name starts with L.
Can this be done?
Currently I have the following for access the database (but it seems to be a bit slow!)
textBoxCity.AutoCompleteCustomSource = CityList();
public static AutoCompleteStringCollection CityList()
{
string connectionStringLD = string.Empty;
connectionStringLD = #"Driver={Microsoft Access Driver (*.mdb)};DBQ=c:\CityList.mdb";
string SQL = "SELECT CityCode from CityTable";
OdbcConnection conn = new OdbcConnection(connectionStringLD);
OdbcCommand cmd = new OdbcCommand(SQL);
cmd.Connection = conn;
conn.Open();
OdbcDataReader reader = cmd.ExecuteReader();
AutoCompleteStringCollection theCityList = new AutoCompleteStringCollection();
while (reader.Read())
{
theCityList.Add(reader.GetValue(0).ToString());
}
return theCityList;
}
You can use Like '%' Query in your Sql Statement which will return the city name based on your input.
You can Refer this example Sql Parameter with C# Using Like wildCards
I'm not sure what you're getting at with
What I want to do is have an autocomplete which shows the “Name” and “Country” but when selected the “CityCode” Value is shown in the textbox.
but I can answer the autocomplete part of your question.
To do this you need to get your data into a DataTable; you can read it from the database into the table however you want, but the Right Way to do it is to use OleDbConnection, OleDbDataAdapter, and OleDbCommandBuilder - msdn has examples.
Now that it's in a DataTable, bind it to a ComboBox:
var query =
from row in mytable.AsEnumerable()
select new { citycode = row.Field<string>("CityCode") } // put whatever you want in the anonymous type
mycombobox.DisplayMember = "citycode"
mycombobox.ValueMember = "citycode" // this one can be a different member name
mycombobox.DataSource = query.toList(); // the datasource should be set last
And now you can set the combo box behavior to be an autocomplete:
combobox1.AutoCompleteMode can be set to Append (to simply autocomplete), Suggest (to bring up a dropdown box), or SuggestAppend (both)
Set combobox1.AutoCompleteSource to ListItems to have it get the autocomplete entries from the data binding.
If you prefer to allow users to type whatever they want and only suggest your datatable values as options, then you should only set the AutoCompleteCustomSource and not worry about actual data binding with DataSource.
This is kind of all a lot of trouble; since cities aren't exactly going to be opening international airports several times a second you might prefer just dumping all the airport codes into a List, which you can also data bind to.

Categories