WCF - list in ComboBox - c#

I'd like to get country's names form one field of list and put them to the comboBox:
public TravelAgencyResponse GetInformation(TravelAgencyRequest request)
{
TravelAgencyResponse response = new TravelAgencyResponse();
// response.Offers = new OfferDto();
response.Offers = new List<DataTransferObjects.OfferDto>();
response.Offers.Add(new DataTransferObjects.OfferDto()
{
IdOffer = 0,
KindOfAccommodation = "Hotel",
Country = "Spain",
});
response.Offers.Add(new DataTransferObjects.OfferDto()
{
IdOffer = 1,
KindOfAccommodation = "Hotel",
Country = "Italy",
});
response.ThisOffer = (from offer in response.Offers
where offer.Country == request.Country
select offer).FirstOrDefault();
return response;
}
I thought that I can use LINQ without FirstOrDefault() but I can't do that in this situation.
private void button1_Click(object sender, EventArgs e)
{
Uri baseAddr = new Uri("http://localhost:1232/TravelAgencyService/SimpleTravelAgencyService/");
ChannelFactory<ITravelAgencyService> factory = new ChannelFactory<ITravelAgencyService>(new WSHttpBinding(),
new EndpointAddress(baseAddr));
ITravelAgencyService proxy = factory.CreateChannel();
var response = proxy.GetInformation(
new TravelAgencyService.Messages.TravelAgencyRequest()
{
Country = textBox1.Text
});
comboBox1.Items.Add(response.ThisOffer.Country);
listBox1.Items.Add(response.ThisOffer.Country);
}
I tried put these information in ComboBox like that:
comboBox1.Items.Add(response.ThisOffer.Country);
and I give only the first country or like that:
comboBox1.Items.Add(response);
and I don't get anything.
my first steps with WCF! Be understanding, please!

So if I understand your question correctly, you want to fill a ComboBox with all the countries that are contained in any response.Offers's Country property, correct?
Since you mentioned you are new to WPF, I'll skip the part about MVVM and DataBinding and show you a way it can be done with what you have now.
First you need to "extract" all the countries from the Offers, preferably only once and sorted alphabetically.
List<string> countries = response.Offers
.Select(o => o.Country) // We only need the "Country" of the offer
.Distinct() // Every country only once
.OrderBy(c => c) // Sort by name
.ToList(); // make a List<string> out of it
Instead of adding items manually, I'd recommend assigning all of them at once, by setting the DataSource property.
comboBox1.DataSource= countries;
You need to make sure however that Items is empty, manually added items and DataSource do not work well together.
If you want to pre-select a certain country (e.g. the one from ThisOffer) you can set the SelectedItem property of the ComboBox:
comboBox1.SelectedItem = response.ThisOffer.Country;

Related

List of objects, add properties together based of another property

I have a List that contains 2 properties per object. The properties are as follows:
string Project;
double Value;
So in any given case we might have a List of 5 objects, where 3 of them have a Project property called "Test" and the other 2 objects have a Project Property called "Others", but none of the 5 objects have the same "Value".
{
Project = "Test" Value = 1,
Project = "Test" Value = 5,
Project = "Test" Value = 25,
Project = "Others" Value = 89,
Project = "Others" Value = 151
}
Okay, I get a lot of data from a Database (I "Query" it out into a List of objects), then I take the specific properties I need from that List and add to my own List as follows.
public class Data
{
public string Project {get; set;}
public double Value {get; set;}
}
public List<Data> dataList = new List<Data>();
foreach(var item in DatabaseList)
{
Data newData = new Data(
data.Project = item.Project;
data.Value = item.Project;
dataList.Add(newData);
}
This gives me my list of data that I somehow need to combine based on the property in "Project"
But I have a hard time figuring out how to seperate them from one another, my first thought was to find "Unique" "Projects" and adding that to a new List called "counter", to then loop through that list based of the "Project" property, so something like this:
List<Data> counter = dataList.GroupBy(x => x.Project).Select(First()).ToList();
foreach(var item in counter)
{
Data finalItem = new Data();
foreach (var item2 in dataList)
{
if(item.Project == item2.Project)
{
finalItem.Project = item2.Project;
finalItem.Value += item2.Value;
finalList.Add(finalItem);
}
}
}
So I already know that the above is so messy its crazy, and its also not going to work, but this was the angle I was trying to take, I was also thinking whether I could maybe make use of Dictionary, but I feel like there is probably a super simple solution to something like this.
I think your initial thoughts regarding making use of a dictionary are good. Your use of .GroupBy() is a first step to create that dictionary, where the project name is the dictionary Key and the sum of values for that project is the dictionary Value.
You already seem to be familiar with the System.Linq namespace. The extension method .ToDictionary() exists in the same namespace, and can be used to define the Key and Value selector for each KeyValuePair (KVP) in the dictionary as follows:
.ToDictionary(
<selector for Key>,
<selector for Value>
);
The dictionary may be created by utilizing .ToDictionary() directly after .GroupBy(), as follows:
Dictionary<string, double> dataDictionary = dataList
.GroupBy(item => item.Project)
.ToDictionary(
itemsByProject => itemsByProject.Key,
itemsByProject => itemsByProject.Sum(item => item.Value));
Example fiddle here.
You can use the following code to compute the total Value for objects with Project="Test" :
double TestsValue = my_list.Where(o=>o.Project=="Test").Sum(t=>t.Value);
and do the same for "Others".
Assuming you're happy to return an IEnumerable of Data, you can do this:
var projects = dataList.GroupBy(p => p.Project)
.Select(grp =>
new Data
{
Project = grp.First().Project,
Value = grp.Sum(pr => pr.Value)
});

display list items into data grid view c#

I have a super-class (abstract) and then 2 inherited classes.
SuperClass: Sessions
Class 1: Cycling
Class 2: Running
I also have a list that will hold all of my objects private List<Session> allSessions = new List<Session>();
I also have declared some arrays that hold hard-coded data to populate my objects.
Also, Running and Cycling has an overridden ToString() method that displays different data depending on the class.
public override string ToString() => $"Cycle Average RPM is {AverageRpm} and Average Resistance is {AverageResistance}";
I am using a for loop to create and add new objects into my list like this
for (int i = 0; i < id.Length; i++)
{
Cycling Cycle = new Cycling(id[i], titles[i], date[i], duration[i], difficulty[i], instructor[i],
description[i], averageRpm[i], averageResistance[i]);
// Add new objects to list
allSessions.Add(Cycle);
}
I have a dataGridView that is getting everything from my list and displays it like this:
My problem now is, that I want to display only specific data depending on what you choose in the ComboBox, but something is not working,
The overridden ToString() is not added to the list for some reason and whenever I choose a different option from the ComboBox, nothing is being displayed.
EDIT 1:
// Filter Sessions by type using Linq
var sessions = new List<Session>();
var cyclingSessions = sessions.OfType<Cycling>();
var runningSessions = sessions.OfType<Running>();
listBox1.DataSource = null;
listBox1.Items.Clear();
if (cboMenu.SelectedIndex == 0)
{
// Populate GridView with data
dataDisplay.DataSource = allSessions;
}
else if (cboMenu.SelectedIndex == 1)
{
// Populate GridView with data
dataDisplay.DataSource = cyclingSessions;
}
else
{
// Populate GridView with data
dataDisplay.DataSource = runningSessions;
}
}
You need to filter your sessions list and set that as your data source you can easily filter the list using OfType from System.Linq It would look something like this:
var sessions = new List<Sessions>();
var cyclingSessions = sessions.OfType<Cycling>();
var runningSessions = sessions.OfType<Running>();
dataDisplay.DataSource = cyclingSessions;

LINQ - Deserialize JSON column and filter

How to deserialize/serialize a property with JSON string array value and then filter (using where clause) in LINQ inside a lambda expression?
void Main()
{
var regionList = new List<Row>() {
new Row { RegionJsonList = "[\"QLD\",\"NSW\"]" },
new Row { RegionJsonList = "[\"TAZ\",\"SA\"]" },
new Row { RegionJsonList = "[\"QLD\",\"VIC\"]" }
};
var filterRegionList = new List<string>() {
"QLD", "NSW"
};
var queryable = regionList.AsQueryable();
// this is obviously wrong, i just want to find the Row that contains one on filterRegionList
var result = queryable.Where(r => JsonConvert.DeserializeObject<string[]>(r.RegionJsonList).Contains(filterRegionList));
result.Count().Dump(); // should be 2
}
class Row
{
public string RegionJsonList { get;set; }
}
Following would work:
var result =
filterRegionList.Aggregate(regionList,(current,filter) =>
current.Where( r => r.RegionJsonList.Contains(filter)).ToList())
Aggregating the filterRegionList and regionList and thus applying filters for the final result. I did not find a requirement to Deserialize the RegionJsonList, since this would work as is, but you may add that part in case you are keen.
Also we are applying And filter via aggregation, it checks for the rows which contains both the filters, and thus provide the result, you may modify filter to achieve more number of rows, like following will select two entries from original regionList
var filterRegionList = new List<string>() { "QLD" };
To filter for rows that contain at least one of the entries from filterRegionList, you can use Enumerable.Intersect and check for non-empty intersections:
var resultAny = queryable.Where(r => JsonConvert.DeserializeObject<string[]>(r.RegionJsonList).Intersect(filterRegionList).Any());
To filter for rows that contain all of the entries from filterRegionList, you can use Enumerable.Except to remove the row's entries from the filter list. If everything gets removed, it's a match:
var resultAll = queryable.Where(r => !filterRegionList.Except(JsonConvert.DeserializeObject<string[]>(r.RegionJsonList)).Any());
(It wasn't entirely clear from your question which you wanted.)

How to add multiple attributes to dropdown list at the time of population

i could solved it just by for loops this way
for loop iterate in datasource and rest of the code as follows
ListItem test = new ListItem { Text = srText, Value = srValue}
test.Attributes.Add("data-imagesrc", "xxx");
test.Attributes.Add("data-description", "xxx");
dropListUserImages.Items.Add(test);
may be there could be error in code because i have composed the above code in notepad. i guess my above code approach will solve my problem but just wondering that can i do the same with LINQ.
here i am giving a sample code which populating dropdown by LINQ but not sure that below code will allow us to add multiple attribute value coming from db?
below sample code taken from http://stackoverflow.com/questions/14710841/making-drop-down-list-in-asp-net-by-foreach-loop
var source = Enumerable.Range(1, 1000)
.Select(i => new { Text= i.ToString(), Value=i.ToString() });
test.DataSource = source;
test.DataTextField = "Text";
test.DataValueField = "Value";
test.DataBind();
looking for guidance to achieve the same with LINQ if possible. thanks
You cannot use the DataSource + DataBind approach if you want to add custom attributes. But why don't you use a simple loop?
var source = db.TableName.Take(1000) // if you only want 1000
.Select(sr => new {
srText = sr.srText,
srValue = sr.srValue,
imagesrc = "xxx", // change
description = "xxx" // change
});
foreach(var x in source)
{
ListItem test = new ListItem { Text = x.srText, Value = x.srValue };
test.Attributes.Add("data-imagesrc", x.imagesrc);
test.Attributes.Add("data-description", x.description);
dropListUserImages.Items.Add(test);
}

Lucene search not working

I have a function which searches some articles in the Sitecore content items and give me the value. So far I have build up my indexes and it is showing in my IndexViewer. But the return of the function is 0. I looked up this link: http://sitecoregadgets.blogspot.com/2009/11/working-with-lucene-search-index-in_25.html for more information.
protected IEnumerable<Item> ShowHomePageNews(int numOfArticles, string stringofCountries)
{
List<Item> items = new List<Item>();
Sitecore.Search.Index indx = SearchManager.GetIndex("newsArticles");
using (IndexSearchContext searchContext = indx.CreateSearchContext())
{
var db = Sitecore.Context.Database;
CombinedQuery query = new CombinedQuery();
QueryBase catQuery = new FieldQuery("countries", stringofCountries); //FieldName, FieldValue.
SearchHits results = searchContext.Search(catQuery); //Searching the content items by fields.
SearchResultCollection result = results.FetchResults(0, numOfArticles);
foreach (SearchResult i in result)
{
items = result
.Where(r => !r.Title.StartsWith("*"))
.Select(r => db.GetItem(new Sitecore.Data.ItemUri(r.Url).ToDataUri()))
.ToList();
//Lucene.Net.Documents.Field url = i.Document.GetField("_url");
//Sitecore.Data.ItemUri itemUri = new Sitecore.Data.ItemUri(url.StringValue());
//Sitecore.Data.Items.Item item = Sitecore.Context.Database.GetItem(itemUri.ToDataUri());
//items.Add(item);
}
}
return items;
}
Over here the result is 0. What I am doing wrond here?
This is the snapshot of what I am seeing in my IndexViewer:
EDIT:
I am passing a "NZ" in the 'catQuery' and I am getting the result back. Because in my index viewer I am seeing the Field Name = _name, which contains NZ in it. I got this part. However, I want my every field to be indexed. I am seeing only 3 fields in my IndexViewer: _url, _group & _name.
So your countries should be tokenized by the indexer. As a multilist, they will be tokenized by GUID. Searching for a single country by GUID with your code above should work. However, if you want to search for multiple countries, where any of the passed in countries can trigger a match, you need to structure your query differently.
CombinedQuery query = new CombinedQuery();
//apply other filters here to query if need be
//and country filter by creating a new clause (combinedquery) and "ORing" within it (QueryOccurance.Should)
CombinedQuery query3 = new CombinedQuery();
//here you would actually iterate over your country list
query3.Add(new FieldQuery("countries", country1GUID), QueryOccurance.Should);
query3.Add(new FieldQuery("countries", country2GUID), QueryOccurance.Should);
query.Add(query3, QueryOccurance.Must);

Categories

Resources