I have a GridView which I have a List bound to - I want to be able to allow filter of the data based on multiple CheckBoxLists.
For arguments sake let's say I have a List of Jobs, and I want to filter the jobs by code - So I would have a CheckBoxList like
C#
ASP.NET
php
F#
etc..
If someone selects multiple codes, how do you pass the values into a List to rebind to the GridView? Is there a way to pass values as an array? Or maybe a comma seperated string?
Any examples (I'm a C# boy) would be greatly appreciated, and I hope I have explained it properly :S
use an ObservableCollection<T> . it automatically allows the gridview to "observe" that the underlying datasource has changed and thus update itself.
wherever you do your filtering for the gridview you have to build the list manually before you filter.
var languages = new List<string>();
foreach (ListItem item in cblLanguages.Items)
{
if (item.Selected)
{
languages.Add(item.Value);
}
}
then when you filter you can do something like (example using linq2sql)
var jobs = db.Jobs.Where(x => langauges.Contains(x.LanguageCode));
gvJobs.DataSource = jobs;
gvJobs.DataBind();
I'm not sure I completely understand your question. But I often do the following to get ListItems into a form queryable via LINQ to objects:
var items = cblLanguages.Items.Cast<ListItem>();
// Selected Items
var selectedItems = items.Where(li => li.Selected);
// Item's containing 'C'
var itemsWithC = items.Where(li => li.Text.Contains("C"));
// Values between 2 and 5
var itemsBetween2And5 = from li in items
let v = Convert.ToInt32(li.Value)
where 2 <= v && v <= 5
select li;
Related
I have a database which it's schema is as follows:
As you can see, We have WareCategories which will be category of the wares i'm going to be working in my website. WareTypes which will be Definition of each Item type. Categories define properties in the table WarePropertyDefinitions and WareProperties define values for each property that has been defined in WarePropertyDefinitions table.
Now i have a search page that users search for items in OldWares and user selects category and i show the user all properties defined in WarePropertyDefinitions and user fills the data if he likes better results. But my problem is that i can't filter WareTypes based on WareProperties because it's from the type ICollection and i can't access filter options.
How can i apply this kind of filtering based on properties?
Thanks in advance...
Edit:
This is a part of the code i'm presenting to describe more:
var lst = WareCategory.GetItem(Convert.ToInt32(ddlChildren.SelectedValue)).WarePropertyDefinitions.ToList();
foreach (var ListItem in lst)
{
var value = BaseHelper.FindFormValue("PropertyValue" + ListItem.Id.ToString());
if (!string.IsNullOrEmpty(value))
{
query = query.Where(m => m.WareType.WareProperties.);
}
}
}
This segment of code is in my search function and as you can see i'm going to generate a list of items in WarePropertyDefinition that user selected via a drop down menu called ddlChildren. I'm going to iterate in this definition and user entered value for each property (the value variable will hold the value user entered and i will check if user have entered anything in the textbox) i will include it in where section (through this i will add it in where clause that ultimately filters my selection). but as you can see the code is incomplete because i don't know how to complete it.
Use the Any() extension method, for example:
query = query.Where(m => m.WareType.WareProperties.Any(wp => wp.Id == 5));
I have fixed the my problem by this code:
query = query.Where(m => m.WareType.WareProperties.Any(wp => wp.WarePropertyDefinition_Id == ListItem.Id && wp.TextValue == value));
but because #user3159792's answer was the basic of my problem i have selected his answer as the default answer to my problem. very thanks.
I have got a response back from an API which contains a list of hotels, which I want to store in an array and then display this list in a table, something like this.
//Get a response
IRestResponse<RootObject> searchResponse = client.Execute<RootObject>(searchRequest);
var hotelList = searchResponse.Data.HotelListResponse.HotelList.HotelSummary.ToArray();
foreach (var hotelSummary in hotelList.ToArray())
{
TextBoxResults.Text = hotelSummary.hotelId.ToString();
TextBoxResults.Text = hotelSummary.shortDescription.ToString();
TextBoxResults.Text = hotelSummary.address1.ToString();
TextBoxResults.Text = hotelSummary.address2.ToString();
TextBoxResults.Text = hotelSummary.city.ToString();
}
At the moment, what this is doing is only returning one of the ten results from the list of results and not all 10.
What I'm trying to do is put the list into an array and then display the results in a table in my ASP.net page, the list will not contain more than ten results.
You've chosen the wrong Control to show your data. Textbox can only show 1 value not a list of values. I guess you are using forms. then you have grid view.
use it like this:
MyGridview.DataSource = hotelList ;
MyGridview.DataBind();
Take a look at this link from asp.net
Update
also take a look at this
C# - Populating Gridview
The reason why it's happening is because you're just overwriting the TextBoxResults. Seems like you don't have a Datagridview or some sort.
So I used the following as suggested:
//Get a response
IRestResponse<RootObject> searchResponse = client.Execute<RootObject>(searchRequest);
var hotelList = searchResponse.Data.HotelListResponse.HotelList.HotelSummary.ToArray();
foreach (var hotelSummary in hotelList.ToArray())
{
GridViewResults.DataSource = hotelList;
GridViewResults.DataBind();
}
This returns everything, and opens up the list and all the element provided from the API, it would be good to return only certain columns, instead of all of them.
I am populating a listBox at runtime from a database as follows:
List<FILE_REPORT_TYPES> ReportTypes = GetReportTypesFromDatabase(ReportMappingIds)
BindingList<FILE_REPORT_TYPES> pbReportTypesBindingList = new BindingList<FILE_REPORT_TYPES>(ReportTypes);
listBoxReports.DataSource = ReportTypesBindingList;
listBoxReports.DisplayMember = "REPORT_DESCRIPTION";
listBoxReports.ValueMember = "REPORT_ID";
I then would like select multiple items on the listBox when running the windows form and retrieve each individual Value of my selections. If only one selection is made one could do the following:
listBoxReports.SelectedValue;
I would like to do the following:
var list = listBoxReports.SelectedValues;
However this is not allowed i.e. "SelectedValues" does not exist.
Some people are erroneously suggesting that in this particular case SelectedIndices may be used. It cannot be used, I am trying to retrieve the "VALUE". This cannot be done (in this particular case):
listBox.Items[i].Value;
I think the solution should be along the lines of:
foreach(var line in listBox.Items)
{
var res= ((SOME CASTING)line).Value;
}
To get the selected items you have 2 options
a.) ListBox.SelectedIndices which returns the indices of the selected items which you then need to use to look up in the Items property what the value is or
b.) ListBox.SelectedItems which returns you a collection with the selected items themselves (be aware that it is an objectlist so you need to transform the items into your appropriate datatype).
Edit: With the additional information the following is possible
List<FILE_REPORT_TYPES> mySelectedList = new List<FILE_REPORT_TYPES>();
foreach (Object selectedItem in ListBox.SelectedItems)
{
mySelectedList.Add( ((FILE_REPORT_TYPES)selectedItem) );
}
You can use ListBox.SelectedIndices or ListBox.SelectedItems.
If you want to get all selected-items, you can let the foreach cast:
foreach(FILE_REPORT_TYPES frt in listBox.SelectedItems)
{
// ...
}
or if you want to get the ReportID into a list with the help of LINQ:
List<decimal> reportIds = listBox.SelectedItems.Cast<FILE_REPORT_TYPES>()
.Select(frt => frt.REPORT_ID)
.ToList();
Alternative to the selected value you could do the following
listBoxReports.SelectedItems;
Answer (the casting is the trick):
List<decimal> reportIds = new List<decimal>();
foreach(var line in listBoxReports.SelectedItems)
{
reportIds.Add(((PB_FILE_REPORT_TYPES)line).REPORT_ID);
}
You may try like below
List<FILE_REPORT_TYPES> reportList = new List<FILE_REPORT_TYPES>();
foreach(var item in listBox.SelectedItems)
{
reportList.Add((FILE_REPORT_TYPES)item);
}
I am working on a windows application using .net 2.0. The UI appl has a datagrid and the data will be populated from the XML file.
The data grid has more than 500 rows. Sorting functionality has implemented. but customer still wants a find option or a search functionality on one of the columns with a text box where user is going to enter first 3 letters and it has to search in the grid and has to show the related rows that starts with the give search criteria.
Any suggestions pls how to implement this....
Thanks
You can use a Filter option in the BindingSource object.
private BindingSource dashBoardBindingSource = new BindingSource();
dashBoardBindingSource.DataSource=<<data source items>>;
dashBoardBindingSource.Filter="Column Name=textbox.text";
datagrid.DataSource = dashBoardBindingSource;
Store off your full collection of data, and then when the filter needs to be performed, create the filtered collection and bind the filtered collection to the grid. Just wire up appropriate text changed events to your filter box, calling FilterGridData. It works nicely when filtering via multi-column as well. Oh, and you don't have to use BindingList here. Use whatever data source you want to bind to the grid - the core of this is just "create the filtered collection by filtering with LINQ."
BindingList<Foo> _allFoos;
private void LoadData(IEnumerable<Foo> dataToDisplayInGrid)
{
this._allFoos = new BindingList<Foo>(dataToDisplayInGrid.ToList());
this.FilterGridData(string.Empty);
}
private void FilterGridData(string filterText)
{
BindingList<Foo> filteredList = null;
if (!string.IsNullOrEmpty(filterText))
{
string lowerCaseFilterText = filterText.ToLower();
IList<Foo> filteredItems = this._allFoos.Where(x => (x.Name ?? string.Empty).ToLower().Contains(lowerCaseFilterText)).ToList();
filteredList = new BindingList<Foo>(filteredItems);
}
else
{
filteredList = new BindingList<Foo>(this._allFoos);
}
dataGrid.DataSource = filteredList;
}
I have three sets of listboxes, I move items from lb1 to lb2, from lb3 to lb4 and from lb5 to lb6. The listboxes on the left contains the same items and I don't want the user to be able to submit the page if one or more items from the left listboxes is added to more than one listbox to the right. For example, item A in lb1, lb3 and lb5 can only be saved in either lb2, lb4 or lb6, not in two or three of them.
I want to perform this check before submitting the page (and later on I will add validation with javascript) and I wonder what is the most efficient way to do this.
Add all items to a list and check if there are any duplicates?
Thanks in advance.
Edit:
something like this:
List<string> groupList = new List<string>();
foreach (ListItem item in lbFullAccess.Items)
{
groupList.Add(item.Value.ToString());
}
foreach (ListItem item in lbContributor.Items)
{
groupList.Add(item.Value.ToString());
}
foreach (ListItem item in lblReadOnly.Items)
{
groupList.Add(item.Value.ToString());
}
Well, there's a hundred different ways you could do it. Absolutely nothing wrong with your suggestion of iteration.
You could have a little fun with LINQ:
public bool AreAllValuesUnique()
{
// Build up a linq expression of all of the ListItems
// by concatenating each sequence
var allItems = lbFullAccess.Items.Cast<ListItem>()
.Concat(lbContributor.Items.Cast<ListItem>())
.Concat(lbReadOnly.Items.Cast<ListItem>());
// Group the previous linq expression by value (so they will be in groups of "A", "B", etc)
var groupedByValue = allItems.GroupBy(i => i.Value);
// Finally, return that all groups must have a count of only one element
// So each value can only appear once
return groupedByValue.All(g => g.Count() == 1);
}
Not really sure about the performance of calling Cast (converting each element of the ListItemCollection to a ListItem, resulting in an IEnumerable) on each collection, but it is probably negligible.