Each time I add an item in the list ListData that I have created I have to check that does not exist.
This is the element:
public ObservableCollection<LabelGroup_RowItem> ListData = new
ObservableCollection<LabelGroup_RowItem>();
public class LabelGroup_RowItem
{
public int ID { get; set; }
public string Name { get; set; }
}
element.Name = TextEdit_GroupName.Text;
foreach (string x in ucLabel.ListData[0].Name)
{
if (x.Equals(element.Name))
{
MessageBox.Show("....");
}
}
How should I do?
While it's hard to know what ucLabel is, you probably meant:
foreach (var x in ucLabel.ListData)
{
if (x.Name.Equals(element.Name))
{
MessageBox.Show("....");
}
}
you can use Linq - this will match if any item in ListData(.Name) matches your text field
string TextToMatch = TextEdit_GroupName.Text;
if(ListData.Any(x => x.Name == TextToMatch))
{
MessageBox.Show(string.format("{0} already exists",TextToMatch);
}
bare in mind this is mostly psuedo, but it should work
about equals metchod
If Name property is unique try to compare it with simple '==' operator.
Also your foreach loop looks wierd. I am not sure if this: ucLabel.ListData[0].Name
is IEnumerable. Maybe you think about
foreach (var x in ucLabel.ListData){
if (x.Name==element.Name) { do something }
}
Also remember to avoid adding or removing ListData content in foreach loop becous it will crash your code.
Related
Edit/Update!!!
I wanted to update the question as the answer below only guided me in the right direction but did not completely solve the issue.
However i did manage to fix the problem by changing how items and hopefully this will help someone in the future
Add items to the class list like so
descriptionclb.Items.Add(new listItem { Name = ItemToAdd, Price = Convert.ToDouble(ItemPrice), Quantity = Convert.ToDouble(Quantity.Text) });
And iterate items like so
foreach (Listitem item in descriptionclb.Items)
{
double TotalAmmount = item.Price);
//Do stuff with Item
}
I'm trying to get the value of a list item within a listbox, I keep getting an error "'System.InvalidCastException' Unable to cast object of type 'System.String' to type 'list'."
Any help would be appreciated,and I have tried to do lots of research with no result (Maybe im not phrasing the question right on google). See my code below.
Class ListItem
public class listItem
{
public string Name { get; set; }
public double Price { get; set; }
public double Quantity { get; set; }
public override string ToString()
{
return Name;
}
}
I insert the values here
Globals.li.Name = ItemToAdd;
Globals.li.Price = Convert.ToDouble(ItemPrice);
Globals.li.Quantity = Convert.ToDouble(Quantity.Text);
descriptionclb.Items.Add(Globals.li.ToString());
Globals is a globlal class and li is the listitem li = new listItem
I get the error here
foreach (var item in descriptionclb.Items)
{
double TotalAmmount = Convert.ToDouble(((list)item).Price);
}
You are adding strings here:
descriptionclb.Items.Add(Globals.li.ToString());
So you are saving string rather than listItem object that is why you get the error.
Should be:
descriptionclb.Items.Add(Globals.li);
Also this object descriptionclb.Items should be of type listItem
And the for loop should something like:
foreach (listItem item in descriptionclb.Items)
{
double TotalAmmount = item.Price;
}
In your code you have a type called 'list'. Your foreach loop iterates over a list of strings, therefore 'var item' is a string. You can't convert the 'list' type to a string which is causing the exception.
If you're trying to add all the 'listItem' Price values up then you should try changing the type of 'descriptionclb.Items' from a list of strings to a list of 'listItem' and add the listItem directly. Then you will be able to get rid of the cast.
descriptionclb.Items.Add(Globals.li);
foreach (var item in descriptionclb.Items)
{
double TotalAmmount = item.Price;
}
Just a note; in the for loop you don't do anything with TotalAmmount.
you need to change
descriptionclb.Items.Add(Globals.li);
and
foreach (var item in descriptionclb.Items)
{
double TotalAmmount = item.Price;
}
if TotalAmmount , total fares from list cahnge it to:
double TotalAmmount=0
foreach (var item in descriptionclb.Items)
{
TotalAmmount = TotalAmmount+ item.Price;
}
I'm doing a SAT Solver (mainly the DPLL or Partial DPLL) and I have the method for Unit Propogation. Basically what it does is that it checks whether there are any standalone literals, and removes that literal, and any instance found in the other clauses. Any Example would be
(x) (x,y) (w,z)
the Unit Propogation would be 'x' and when performing the unit prop it would leave only (w,z)
In this method I have several nested foreach loops and List<literals> <literals> is a custom made class which has 2 variables hasNegation (bool) and char literalCharacter
The Coding is below, and will explain from below
foreach (clauses c1 in listOfClauses)
{
if (c1.listOfLiterals.Count == 1)
{
literals l1 = c1.listOfLiterals[0];
solved.Add(l1);
foreach (clauses c2 in listOfClauses)
{
List<literals> tempList = new List<literals>();
foreach (literals l2 in listOfLiterals)
{
if (l2.solveDPLL(l1))
{
removable.Add(c2);
}
else
{
if (c2.listOfLiterals.Count == 1)
{
UNSAT = true;
return false;
}
else
{
if (l1.solveDPLL(l2))
{
tempList.Add(l2);
}
}
}
c2.listOfLiterals.RemoveAll(tempList); //obviously giving error
}
}
}
}
return true;
}
I have 2 List <literals> which are templist and listOfLiterals where the LATTER is the "parent"
I am tryign to remove the entries of listOfLiterals that match with tempList and I use c2.listOfLiterals.RemoveAll(tempList); obviously will output an error as it is not a Delegate.
I've searched a lot,even on stackoverflow, but every one of them compares either to an ID or an integer. In my case, since I'm just comparing 2 Lists, how can I do the delegate so that, the entries that are the same in both listOfLiterals and tempList are removed from listOfLiterals?
Many thanks
EDIT:
Literals Class
public class literals
{
public char literalCharacter { get; set; }
public bool negation { get; set; }
public literals(char lc, bool neg )
{
literalCharacter = lc;
negation = neg;
}
public bool solveDPLL (literals lit)
{
return ((Object.Equals(literalCharacter, lit.literalCharacter) && (negation == lit.negation)));
}
public String toString()
{
return literalCharacter + " : " + !negation;
}
}
If you're okay with using a little LINQ magic:
c2.listOfLiterals = c2.listOfLiterals.Except(tempList).ToList();
Or loop over the tempList:
foreach (var item in tempList)
{
c2.listOfLiterals.Remove(item);
}
You may need your literals class to implement IEqualityComparer<literal> and then provide an implementation for Equals and GetHashCode. See the MSDN page for Except for a good example of this.
I'm cleaning up my code trying to short in some things
Now I've stumbled across:
ImageList.Add(test.Properties.Resources.test1);
ImageList.Add(test.Properties.Resources.test2);
ImageList.Add(test.Properties.Resources.test3);
ImageList.Add(test.Properties.Resources.test4);
ImageList.Add(test.Properties.Resources.test5);
(There are 15 of these)
Was wondering if this could be shortened with a for loop
Something like:
for(int i=1; i<=15; i++)
ImageList.Add(test.Properties.Resources.test +i);
Now ofcourse this won't work but I have no clue how to do this (if even possible)
You can iterate over resources via this code
using System.Collections;
using System.Globalization;
using System.Resources;
...
ResourceSet resourceSet = MyResourceClass.ResourceManager.GetResourceSet(CultureInfo.CurrentUICulture, true, true);
foreach (DictionaryEntry entry in resourceSet)
{
string resourceKey = entry.Key;
object resource = entry.Value;
}
You can use reflection, to get the values:
public class Something
{
public int Test1 { get; set; }
public int Test2 { get; set; }
public int Test3 { get; set; }
public int Test4 { get; set; }
}
var thing = new Something();
var imageProperties = typeof(Something)
.GetProperties()
.Where(p => p.Name.StartsWith("Test"));
var imagesToAdd = imageProperties
.Select(property => property.GetValue(thing))
.ToList();
You could define a property of type IEnumerable<Image> in the class of Resources object
public IEnumerable<Image> Images
{
get
{
yield return test1;
yield return test2;
yield return test3;
yield return test4;
yield return test5;
...
}
}
and then use it to fill ImageList
foreach(var image in test.Properties.Resources.Images)
{
ImageList.Add(image);
}
I just found out that there is a library for evaluating C# expression called Flee. Apparently you can use it to evaluate C# code so that you can loop over variable names, just like JavaScript, but the need for it most likely means a design flaw.
http://flee.codeplex.com/
I have an object that I obtained from an xml file and it contains a field of SeriesCode and ProductCodes associated with the specified Series code.
i.e.
SeriesCodeA
prodCode1
prodCode2
prodCode3
SeriesCodeA
prodCode4
prodCode5
prodCode6
I created a the following dictionary
Dictionary<string, List<string>> dictSeries = new Dictionary<string, List<string>>();
The values from the object I want to add to the dictionary. So in other words I want to, for each series code added to the Dictionary key as a string value add the corresponding product codes as string values.
something like
foreach (var s in series)
{
string code = s.SeriesCode;
if (dictSeries.ContainsKey(code))
{
foreach (var l in s.ProductCodes)
{
dictSeries[code].Add(l);
}
}
}
The above is not quite right
How can I add the SeriesCodes as keys to the dictionary with the corresponding product codes as string values(List)?
Use LINQ and ToDictionary method to make it more readable:
var dictSeries = series.ToDictionary(x => x.SeriesCode, x => x.ProductCodes);
A assumed your Series class looks like that:
class Serie
{
public string SeriesCode { get; set; }
public List<string> ProductCodes { get; set; }
}
Your code also will work, but needs few improvements:
foreach (var s in series)
{
string code = s.SeriesCode;
if (!dictSeries.ContainsKey(code))
{
dictSeries.Add(code, new List<string>());
}
foreach (var l in s.ProductCodes)
{
dictSeries[code].Add(l);
}
}
In my current project, a method I don't control sends me an object of this type:
public class SampleClass
{
public SampleClass();
public int ID { get; set; }
public List<SampleClass> Items { get; set; }
public string Name { get; set; }
public SampleType Type { get; set; }
}
public enum SampleType
{
type1,
type2,
type3
}
I display those data in a TreeView, but I would like to display only the path ending with SampleClass objects having their Type property set to type3, no matter the depth of this leaf.
I have absolutely no clue on how to do that, can someone help me ?
Thanks in advance !
Edit
To explain the problem I meet with the solutions proposed by Shahrooz Jefri and dasblinkenlight, here is a picture. The left column is the original data, without filtering, and the right one is the data filtered. Both methods provide the same result.
In red is the problem.
Use this Filter method:
public void Filter(List<SampleClass> items)
{
if (items != null)
{
List<SampleClass> itemsToRemove = new List<SampleClass>();
foreach (SampleClass item in items)
{
Filter(item.Items);
if (item.Items == null || item.Items.Count == 0)
if (item.Type != SampleType.type3)
itemsToRemove.Add(item);
}
foreach (SampleClass item in itemsToRemove)
{
items.Remove(item);
}
}
}
In addition to initially determining which items to show, if the datasize is substantial and you expect users to frequently collapse and expand sections then filtering after every click my result in slow ui response.
Consider the Decorator pattern or some other way of tagging each node with relevant info so that the filtering is not required after every click.
Try this approach:
static bool ShouldKeep(SampleClass item) {
return (item.Type == SampleType.type3 && item.Items.Count == 0)
|| item.Items.Any(ShouldKeep);
}
static SampleClass Filter(SampleClass item) {
if (!ShouldKeep(item)) return null;
return new SampleClass {
Id = item.Id
, Name = item.Name
, Type = item.Type
, Items = item.Items.Where(ShouldKeep).Select(x=>Filter(x)).ToList()
};
}
The above code assumes that Items of leaves are empty lists, rather than nulls.