querying existing ListView items with LINQ - c#

The ListView I have populates through these loops resulting in four columns being filled
// Create a ResXResourceReader
ResXResourceReader rdr0 = new ResXResourceReader(textPath1.Text + ".resx");
ResXResourceReader rdr1 = new ResXResourceReader(textPath1.Text + ".es.resx");
ResXResourceReader rdr2 = new ResXResourceReader(textPath1.Text + ".fr.resx");
foreach (DictionaryEntry d in rdr0)
{
TransResource x = new TransResource();
x.id = d.Key.ToString();
x.en = d.Value.ToString();
resources.Add(x.id, x);
}
foreach (DictionaryEntry d in rdr1)
{
TransResource x = resources[d.Key.ToString()];
x.fr = d.Value.ToString();
}
foreach (DictionaryEntry d in rdr2)
{
TransResource x = resources[d.Key.ToString()];
x.es = d.Value.ToString();
}
foreach (TransResource x in resources.Values)
{
string[] row = { x.id, x.en, x.fr, x.es };
var listViewItem = new ListViewItem(row);
listResx.Items.Add(listViewItem);
}
What I want to do is query all of the results in this ListView against what is entered in textboxQuery. If any field in the entire listview contains the string from textboxQuery I want it to be displayed in a new listview (lets say listviewQueryresult). I've had many failed attempts at this but I know it is possible through LINQ.

Because ListView.Items implements IEnumerable, but does not implement IEnumerable<T> you have to cast it to IEnumerable<ListViewItem> first, to query it using LINQ to Objects:
var results = listResx.Items.Cast<ListViewItem>()
.Where(x => YourPredicate(x));
If any field in the entire listview contains the string from
textboxQuery I want it to then be displayed in a new listview (lets
say listviewQueryresult)
For that, the predicate would be just:
var results = listResx.Items.Cast<ListViewItem>()
.Where(x => x.Text.Contains(textboxQuery));

Related

GROUP BY to List<> with Linq

I'm new to using Linq so I don't understand some things or its syntax. I want to group a list and then loop through it with foreach, like my logic below. Obviously my logic doesn't work.
My code:
var final = finalv.Union(finalc);
final = final.GroupBy(x => x.Clave);
foreach (var articulo in final)
{
Articulo articulo2 = new Articulo();
articulo2.ArtID = articulo.ArtID;
articulo2.Clave = articulo.Clave;
articulo2.ClaveAlterna = articulo.ClaveAlterna;
lista.Add(articulo2);
}
First, such usage is syntactically consistent with this overloaded method of GroupBy: GroupBy<TSource,TKey>(IEnumerable<TSource>, Func<TSource,TKey>), and it will return a IEnumerable<IGrouping<TKey,TSource>> variable.
That means, if you run final.GroupBy(x => x.Clave), let's assume he returns finalWithGrouped, then finalWithGrouped.Key is the key and finalWithGrouped.ToList() is a collection of all variables with the same key(at here, it is with the same Clave).
And for your code, try this:
var final = finalv.Union(finalc);
var finalWithGrouped = final.GroupBy(x => x.Clave);
foreach (var articulosWithSameClavePair in finalWithGrouped)
{
var clave = articulosWithSameClavePair.Key;
var articulos = articulosWithSameClavePair.ToList();
foreach(var articulo in articulos)
{
Articulo articulo2 = new Articulo();
articulo2.ArtID = articulo.ArtID;
articulo2.Clave = articulo.Clave;
articulo2.ClaveAlterna = articulo.ClaveAlterna;
lista.Add(articulo2);
}
}
I suggest you read some examples of using GroupBy.
When you group a list, it will return a key and groued list and you are trying reach a single property of a list.
When you group an data, you can convert it to dictionary, It is not nessesary but better way for me. You can try this code:
var final = finalv.Union(finalc);
final = final.GroupBy(x => x.Clave).ToDictionary(s=> s.Key, s=> s.ToList();
foreach (var articulo in final)
{
foreach (var articuloItem in articulo.value)
{
Articulo articulo2 = new Articulo();
articulo2.ArtID = articuloItem.ArtID;
articulo2.Clave = articuloItem.Clave;
articulo2.ClaveAlterna = articuloItem.ClaveAlterna;
lista.Add(articulo2);
}
}

Access items in list pertaining to GroupBy() item

I am instantiating a List, derived from an ObservableCollection:
var paidTrips = PaidTrips
.GroupBy(p => new {p.LicenseHolderID})
.ToList();
Which, through a foreach loop, gives me access to the various distinct values in LicenseHolderID.
foreach (var licenseHolder in paidTrips) {
// accessing the string value of LicenseHolderID
// but no access to the other items
}
What I need help with:
How can I obtain access to the other items in paidTrips, which pertain to LicenseHolderID? (Why: I am creating invoices, one per LicenseHolderID, and I am building the invoice with the data from all the other collection properties).
To give some context, here's the full collection I am working with:
PaidTrips.Add(new PaidTrip {
LicenseHolderID = dr[0].ToString(),
VehicleID = dr[1].ToString(),
Year = dr[2].ToString(),
Month = dr[3].ToString(),
Payment = (decimal)dr[4],
PaymentNet = (decimal)dr[5],
OrderFee = (decimal)dr[6],
PaymentFee = (decimal)dr[7],
TripVATcode = (decimal)dr[8],
LicenseHolderInvoiceID = dr[9].ToString(),
TripFeeNet = (decimal)dr[10],
TripFeeVATcode = (decimal)dr[11],
RidelRegionInvoiceID = dr[12].ToString(),
});
It does depend what your looking to do with the data for each invoice? are you looking to summarise the data within each LicenseHolderID group?
var PaidTrips = new List<PaidTrip>();
var paidTrips = PaidTrips
.GroupBy(p => new { p.LicenseHolderID })
.ToList();
foreach (var group in paidTrips)
{
var licenseHolderID = group.Key.LicenseHolderID;
//ie here total payment (This sums all payments for this LicenseHolderID)
var totalPayment = group.Sum(x => x.Payment)
// count of payments made (This Counts all Payments greater than 0)
var totalPayments = group.Count(x => x.Payment > 0)
//Use variables in your invoice generation
}
or as above iterate through each group item and access it in singular form.
If I understand you correctly, you want to access each group member's property. To achieve this, you should use nested foreach to traverse each group and access its members.
var PaidTrips = new List<PaidTrip>();
var paidTrips = PaidTrips
.GroupBy(p => new { p.LicenseHolderID })
.ToList();
foreach (var group in paidTrips)
{
var licenseHolderID = group.Key.LicenseHolderID;
foreach (var paidTrip in group.ToList())
{
Console.WriteLine(paidTrip.TripFeeNet);
}
}
foreach (var licenseHolder in paidTrips) {
// accessing the string value of LicenseHolderID
if (licenseHolder.Key == desiredLicenseHolderID){
foreach (var paidItem in licenseHolder){
paidItem.VehicleID = .......
}
}
}
The .GrouBy() Returns a IGrouping object which contains the Key and the elements grouped by the key. To access the elements of the Key grouping you are after once you iterated through the items and found the one, you can simply iterate through the item as an array.

Adding an Object of class to an array of the same class C#

Hello all
I try to convert a group of ŲStrings to a class, and then add these elements to an array or list of the same class
problem
Everything is fine, only when one element is added does it change all the values in the array to the same values as the last element
TxtCookie.Text :
1=|257|9.5|1|true|true|true|true|1-From Web, 2=|259|11.5|7|false|false|false|false|232-From Web, 3=|261|9.5|5|true|false|true|true|-From Web, 4=|267|9.5|1|true|true|true|true|-From Web
This code :
//Get The Value from Text Box To list of Strings
string[] lst = TxtCookie.Text.Split(',');
//Divide each element into a set of values
var D = (from a in lst select a.Split('|')).ToList();
//Define an object from the class
TblInvoiceContent tblInvoiceContent = new TblInvoiceContent();
//Define an List from the class
List<TblInvoiceContent> TBLIC = new List<TblInvoiceContent>();
//Here I take the values and configure them according to the class structure
foreach (var item in D)
{
tblInvoiceContent.ItremID = Convert.ToInt32(item[1]);
tblInvoiceContent.SilingPrice = Convert.ToDouble(item[2]);
tblInvoiceContent.Quantity = Convert.ToInt32(item[3]);
tblInvoiceContent.mayonnaise = Convert.ToBoolean(item[4]);
tblInvoiceContent.ketchup = Convert.ToBoolean(item[5]);
tblInvoiceContent.Hot = Convert.ToBoolean(item[6]);
tblInvoiceContent.garlic = Convert.ToBoolean(item[7]);
tblInvoiceContent.Reqomindition = item[8].ToString();
//Here I add the item to the list
TBLIC.Add(tblInvoiceContent);
}
//Here I am displaying the list items
GridView1.DataSource = TBLIC;
GridView1.DataBind();
Result :
Because you only ever create one instance of your object:
TblInvoiceContent tblInvoiceContent = new TblInvoiceContent();
Then in the loop you modify the instance each time and re-add it to the list again.
Move the instance creation into the loop:
foreach (var item in D)
{
TblInvoiceContent tblInvoiceContent = new TblInvoiceContent();
tblInvoiceContent.ItremID = Convert.ToInt32(item[1]);
tblInvoiceContent.SilingPrice = Convert.ToDouble(item[2]);
tblInvoiceContent.Quantity = Convert.ToInt32(item[3]);
tblInvoiceContent.mayonnaise = Convert.ToBoolean(item[4]);
tblInvoiceContent.ketchup = Convert.ToBoolean(item[5]);
tblInvoiceContent.Hot = Convert.ToBoolean(item[6]);
tblInvoiceContent.garlic = Convert.ToBoolean(item[7]);
tblInvoiceContent.Reqomindition = item[8].ToString();
TBLIC.Add(tblInvoiceContent);
}
That way each time the loop iterates you would create a new instance of the object.
//Get The Value from Text Box To list of Strings
string[] lst = TxtCookie.Text.Split(',');
//Divide each element into a set of values
var D = (from a in lst select a.Split('|')).ToList();
//Define an List from the class
List<TblInvoiceContent> TBLIC = new List<TblInvoiceContent>();
//Here I take the values and configure them according to the class structure
foreach (var item in D)
{
//CALL IT HERE Define an object from the class
TblInvoiceContent tblInvoiceContent = new TblInvoiceContent();
tblInvoiceContent.ItremID = Convert.ToInt32(item[1]);
tblInvoiceContent.SilingPrice = Convert.ToDouble(item[2]);
tblInvoiceContent.Quantity = Convert.ToInt32(item[3]);
tblInvoiceContent.mayonnaise = Convert.ToBoolean(item[4]);
tblInvoiceContent.ketchup = Convert.ToBoolean(item[5]);
tblInvoiceContent.Hot = Convert.ToBoolean(item[6]);
tblInvoiceContent.garlic = Convert.ToBoolean(item[7]);
tblInvoiceContent.Reqomindition = item[8].ToString();
//Here I add the item to the list
TBLIC.Add(tblInvoiceContent);
}
//Here I am displaying the list items
GridView1.DataSource = TBLIC;
GridView1.DataBind();

Populating RadMenu Dynamically from Code Behind

I am trying to dynamically populate a Telerik Radmenu control in my code behind. I'm having a really hard time with it. I need to be able to bind my categories to my root elements and attributes to the child elements. I really am lost on this. If even someone has a suggestion of a better way to do this, even if it's with a different type of menu I would be very happy to try it out. Thanks in advance.
**EDIT my code has changed.
protected void createFilter(int categoryid)
{
// check cateogyrid
//get list of proudct id
List<int> productIds = new List<int>();
DataRow[] productRow = CategoriesProductsData.Tables["Products"].Select("Category_ID = " + 573);
productIds = productRow.Select(p => int.Parse(p["Product_ID"].ToString())).ToList();
//get attributes
ITCProductService pService = new TCProductServiceClient();
var productTuples = (pService.GetProductsAttributes(productIds));
List<Tuple<int, CustomAttribute>> customAttributes = new List<Tuple<int, CustomAttribute>>();
foreach (var productTuple in productTuples)
{
foreach (var attributeTuple in productTuple.m_Item2)
{
var customAttribute = new Tuple<int, CustomAttribute>(productTuple.m_Item1, new CustomAttribute(attributeTuple));
customAttributes.Add(customAttribute);
}
}
List<CustomAttributeCategory> categories = new List<CustomAttributeCategory>();
var categoryTuples = customAttributes.Select(a => a.Item2).Select(a => a.Attribute.Category).Distinct();
foreach (var categoryTuple in categoryTuples)
{
var category = new CustomAttributeCategory(categoryTuple);
var attributeByCategory = customAttributes.Select(a => a.Item2).Where(b => b.Attribute.CategoryId == categoryTuple.AttributeCategoryId).Distinct();
foreach (var attributeTuple in attributeByCategory)
{
var attribute = new CustomAttribute(attributeTuple.Attribute);
var attributeProductIds = customAttributes.Where(a => a.Item2.Attribute.AttributeId == attributeTuple.Attribute.AttributeId).Select(a => a.Item1).ToList();
attribute.ProductIds = attributeProductIds;
category.Attributes.Add(attribute);
}
categories.Add(category);
foreach (var cat in categories)
{
var itemCategory = new RadMenuItem(cat.Category.Name.ToString());
handsetMenu.Items.Add(itemCategory);
var itemAttribute = new RadMenuItem(cat.Attributes.ToString());
handsetMenu.Items.Add(itemAttribute);
}
}
}
<%--RAD MENU--%>
<telerik:RadMenu ID="handsetMenu" runat="server" ShowToggleHandle="true">
</telerik:RadMenu>
I don't think ItemDataBound is the correct place to add child items.
Do you want to add the same child items under each of the root menu items?
Try doing it in the DataBound event (which fires after all itemDataBound events have completed) by iterating all RadMenu items.

foreach with multiple DictionaryEntry

I am trying to write to a ListView using the contents of 3 three already existing resx files. Using the following loop with only one of the files yields close to what I want but I need is to use the same loop with multiple DictionaryEntrys. What I am trying to do looks like this..
ResXResourceReader rdr0 = new ResXResourceReader(textPath1.Text + ".resx");
ResXResourceReader rdr1 = new ResXResourceReader(textPath1.Text + ".es.resx");
ResXResourceReader rdr2 = new ResXResourceReader(textPath1.Text + ".fr.resx");
foreach ((DictionaryEntry d in rdr0) && (DictionaryEntry e in rdr1))
{
string[] row = { d.Key.ToString(), d.Value.ToString(), e.Value.ToString() };
var listViewItem = new ListViewItem(row);
listResx.Items.Add(listViewItem);
}
The foreach keyword cannot do that.
Instead, you can use the LINQ .Zip() method:
foreach(var item in rdr0.Zip(rdr1, (d, e)
=> new [] { d.Key.ToString(), d.Value.ToString(), e.Value.ToString() }))

Categories

Resources