how to add dynamic array of item in ExpandoObject Xamarin.forms - c#

i want to add dynamically selected items in ExpandoObject then print it in the form of json value. if i selected 2values, it is printing only the last value 2times.My problem is whatever im selecting it prints last value only.
My code:
Declaration
dynamic output = new List<dynamic>();
dynamic foo = new ExpandoObject();
List<int> selected = new List<int>();
switch toggle function:
private void Switch_Toggled(object sender, ToggledEventArgs e)
{
var switch1 = (Switch)sender;
var human = (Human)switch1.BindingContext;
var id = human.retail_modified_item_id;
var name = human.name;
var old_price = human.old_price;
var new_price = human.new_price;
if (switch1.IsToggled)
{
if (!selected.Contains(id))
{
selected.Add(id);
foo.id = id;
foo.name = name;
foo.old_price=old_price;
foo.new_price=new_price;
output.Add(foo);
}
}
else
{
if (selected.Contains(id)) selected.Remove(id);
}
}
Printing Json value ;
string json = Newtonsoft.Json.JsonConvert.SerializeObject(output);
Debug.WriteLine(json);
My output is:
[{"id":1000739,"name":"Hashbrowns","old_price":0.99,"new_price":8.5},{"id":1000739,"name":"Hashbrowns","old_price":0.99,"new_price":8.5}]
if i selected 2values, it is printing only the last value 2times.

dynamic foo = new ExpandoObject();
you declare global variables here,so the second time you call the following code, you are reassuming the first foo and adding it again, so there are two identical items in the output List.
foo.id = id;
foo.name = name;
foo.old_price=old_price;
foo.new_price=new_price;
output.Add(foo);
you could change like this :
if (!selected.Contains(id))
{
selected.Add(id);
dynamic foo = new ExpandoObject(); // local variables
foo.id = id;
foo.name = name;
foo.old_price=old_price;
foo.new_price=new_price;
output.Add(foo);
}

Related

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();

write a C# code for extracting a .csv file, if i give one of the element of first column, i get the corresponding values of the other two columns

this is my .csv file:
Apple,rose,tiger
Mango,lily,cheetah
Banana,sunflower,lion
Apple,marigold,cat
input: Mango (i write it in the text box)
desired output:
Flower = lily; Animal = cheetah
similarly,
input: Apple
desired output:
Flower = rose,marigold; Animal = tiger,cat
this is the code i have written:
private void button1_Click(object sender, EventArgs e)
{
using (var reader = new StreamReader(#"C:\asp_net\abc.csv"))
{
List<string> listA = new List<string>();
List<string> listB = new List<string>();
List<string> listC = new List<string>();
while (!reader.EndOfStream)
{
var line = reader.ReadLine();
var values = line.Split(',');
listA.Add(values[0]);
listB.Add(values[1]);
listC.Add(values[2]);
}
string checkThis = obj.SearchSenSig(textBox1.Text);
if (listA.Any(checkThis.Contains))
{
int count = listA.Where(x => x.Equals(checkThis)).Count();
if (count == 1)
{
int index = listA.IndexOf(checkThis);
var firstItem = listB.ElementAt(index);
var secondItem = listC.ElementAt(index);
MessageBox.Show(String.Format("receiver = {0}, url = {1}", firstItem, secondItem));
}
else
{
foreach (string item in listA)
{
int i = listA.IndexOf(item);
bool result = item.Equals(checkThis);
if (result)
{
List<string> myCollection1 = new List<string>();
myCollection1.Add(listB.ElementAt(i));
string firstItem = string.Join(",", myCollection1);
List<string> myCollection2 = new List<string>();
myCollection2.Add(listC.ElementAt(i));
string secondItem = string.Join(",", myCollection2);
MessageBox.Show(String.Format("Flower = {0}, Animal = {1}", firstItem, secondItem));
}
}
}
}
else
{
MessageBox.Show("The search element does not exists.");
}
}
Still i am not getting the desired output. Please help.
Instead of creating a different list for each column, create a single class to hold an entire row data:
class Data // I'll bet you can find a better name for this class...
{
public string Fruit {get;set;}
public string Flower {get;set;}
public string Animal {get;set;}
}
and populate a list of this class:
private List<Data> data = new List<Data>(); // note: this is a field, not a local variable.
Populating this list should be done only once, in the constructor or in the form_load event:
while (!reader.EndOfStream)
{
var line = reader.ReadLine();
var values = line.Split(',');
data.Add(
new Data()
{
Fruit = values[0],
Flower = values[1],
Animal = values[2]
}
);
}
Now all you have to do in the button_click event handler is get all the items corresponding to your search string. Assuming you are only searching for fruits using the FindAll method and display the results:
var result = data.FindAll(d => d.Fruit == searchString);
This will return a list of Data where the Fruit property contains the same string as searchString. use linq and string.Join to format the results into a string:
var resultString = $"Flower = {string.Join(",", result.Select(r => r.Flower))}; Animal = {string.Join(",", result.Select(r => r.Animal))}";

How do I make a combobox display a list of dictionaries and act upon the selected value?

C# / Winforms program.
I have the following class which contains my dictionaries:
public class DictionaryInit
{
public Dictionary<int, DictionaryCheckup> C = new Dictionary<int, DictionaryCheckup>()
{
{1000, new DictionaryCheckup {theGrouping="C"}},
{100, new DictionaryCheckup {theGrouping="C"}},
};
}
Where DictionaryCheckup is a class that get;sets; a string theGrouping.
In the class, I would have letters from C to T, and I wanted to display their values within a combo box. This is what I've tried:
var theDictionaries = new DictionaryInit();
List<Dictionary<int, DictionaryCheckup>> Dictionaries = new List<Dictionary<int, DictionaryCheckup>> { theDictionaries.C, etc };
cmbDictionList.DataSource = new BindingSource(Dictionaries, null);
Running this fills the box with [Collection].
The process and desired outcome:
The idea is that, the user first selects a dictionary (C-T) from the combo box and the value gets saved to a variable. I then have the following code that will make use of this:
OFD.ShowDialog();
var theDict = new DictionaryInit();
if (OFD.FileName != null)
{
using (var stream = new StreamReader(File.OpenRead(OFD.FileName)))
{
// Read our JSON from the file
var json = stream.ReadToEnd();
theDict.E = JsonConvert.DeserializeObject<Dictionary<int, DictionaryCheckup>>(json);
var files = new Dictionary<string, Dictionary<int, DictionaryCheckup>>();
}
}
As you can see in my current process, I am explicitly declaring theDict.E. I wish to be able to replace it with a variable I picked up from the combo box earlier, so that I may choose which dictionary I serialize / deserialize.
I want to be able to somehow use my DictionaryInit class as the datasource of the combo box.
The value selected will determine the dictionary I will serialize in a later method.
If all DictionaryCheckup inside DictionaryInit.C have the same letter I would do it like this:
Add Letter property to DictionaryInit
Bind ComboBox to List
Set ComboBox's DisplayMember = "Letter"
Code:
public class DictionaryInit
{
public string Letter { get; private set; }
public DictionaryInit(string letter)
{
this.Letter = letter;
C = new Dictionary<int, DictionaryCheckup>()
{
{1000, new DictionaryCheckup {theGrouping=letter}},
{100, new DictionaryCheckup {theGrouping=letter}},
};
}
public Dictionary<int, DictionaryCheckup> C { get; private set; }
}
var list = new List<DictionaryInit>();
list.AddRange(new[]{new DictionaryInit("C"), new DictionaryInit("D")});
cmbDictionList.DataSource = list;
cmbDictionList.DisplayMember = "Letter";

Get values out of an object into properties of another class

i have a gridview
INSEE1 Commune
------ -------
10002 AILLEVILLE
10003 BRUN
i have a script that return a list of object.
List<object> Temp = ASPxGridView_Insee.GetSelectedFieldValues("INSEE1");
my Temp is a list of object of INSSE1 that i have selected.
but now i add Commune also, so my script become:
List<object> Temp = ASPxGridView_Insee.GetSelectedFieldValues("INSEE1","Commune");
and my Temp is list of object of INSEE1 and Commune look at image:
how can i acces 10002 and AILLEVILLE ?
i have try with cast it of my Pers_INSEE class:
public class Pers_InseeZone
{
string _Code_Insee;
public string Code_Insee
{
get { return _Code_Insee; }
set { _Code_Insee = value; }
}
string _Commune;
public string Commune
{
get { return _Commune; }
set { _Commune = value; }
}
}
foreach (var oItem in Temp )
{
Pers_InseeZone o = (Pers_InseeZone)oItem;
}
but I not work, I can not cast it.
I have tried like this:
foreach (var oItem in Temp )
{
var myTempArray = oItem as IEnumerable;
foreach (var oItem2 in myTempArray)
{
string res= oItem2.ToString();
....
the value of res = 10002, but how can I get the value of AILEVILLE ?
the value of Temp[0].GetType(); is:
Thanks in advance
Ok I thought so, so as already mentioned in the comments you have a array of objects inside each object so you need to cast first every object in your list into an array of objects: object[] then you can access each part. Here is an example that recreates your problem:
object[] array = new object[] {10002, "AILEEVILLE"};
List<object> Temp = new List<object> {array};
And the solution:
// cast here so that the compiler knows that it can be indexed
object [] obj_array = Temp[0] as object[];
List<Pers_InseeZone> persList = new List<Pers_InseeZone>();
Pers_InseeZone p = new Pers_InseeZone()
{
Code_Insee = obj_array[0].ToString(),
Commune = obj_array[1].ToString()
};
persList.Add(p);
Applied to your code it would look something like this:
List<object> Temp = ASPxGridView_Insee.GetSelectedFieldValues("INSEE1","Commune");
List<Pers_InseeZone> persList = new List<Pers_InseeZone>();
foreach (object oItem in Temp )
{
object [] obj_array = oItem as object[];
Pers_InseeZone p = new Pers_InseeZone()
{
Code_Insee = obj_array[0].ToString(),
Commune = obj_array[1].ToString()
};
persList.Add(p);
}
The problem is down to the fact your class doesn't match the same structure as the data you are getting, so it can't be cast into it.
Instead why don't you just iterate over the results and build a new instance of the class?
var tempList = new List<Pers_InseeZone>();
foreach (var oItem in Temp)
{
tempList.Add(new Pers_InseeZone(oItem[0], oItem[1]));
}
You will need to add a constructor to your Pers_InseeZone class, and assign the variables there.

ArgumentOutOfRangeException when writing to a model

I'm trying to write to a model for the first time to use in my view: the first time I write to the model I get an ArgumentOutOfRangeException.
Getting error on first write to array:
private IAdditionalQuestionsService _service;
private SelectedAdditionalQuestionAnswerModel _model;
private void InitializeController()
{
_service = GetObject<IAdditionalQuestionsService>();
//GetPageHeaderText(inst);
ViewBag.GetPageTitle = "Additional Questions";
}
[HttpGet]
public virtual ActionResult Edit()
{
Institution inst = _service.GetInstitution(State.GetInstitutionRecordId());
_model = GetObject<SelectedAdditionalQuestionAnswerModel>();
_model.AddQuestAnswModel = new List<AdditionalQuestionAnswerModel>();
GetPageConfiguration1(inst);
return View(_model);
}
AdditionalQuestionAnswerModel m = GetObject<AdditionalQuestionAnswerModel>();
int c = 0;
foreach (var x in inst.AdditionalQuestions)
{
foreach (var y in x.AdditionalQuestionAnswers)
{
// Error is happening on next line *************
_model.AddQuestAnswModel[c].QuestionText = x.QuestionText;
_model.AddQuestAnswModel[c].InstitutionId = x.InstitutionId;
_model.AddQuestAnswModel[c].AdditionalQuestionId = x.Id;
_model.AddQuestAnswModel[c].AnswerText = y.AnswerText;
_model.AddQuestAnswModel[c].IsSelected = false;
c++;
}
}
You can't use _model.AddQuestAnswModel[c] because you never added any items to your list.
Instead of that, create a new object and set its values and then add the item to your list.
Something like this:
AdditionalQuestionAnswerModel newItem = new AdditionalQuestionAnswerModel();
//set the values here to newItem
_model.AddQuestAnswModel.Add(newItem);
You're firstly instantiating your list
_model.AddQuestAnswModel = new List<AdditionalQuestionAnswerModel>();
then you try to access to the first element
_model.AddQuestAnswModel[c] // c == 0
without adding any element to the list.
Add an element before trying to access to a list by index, or more simple:
foreach (var y in x.AdditionalQuestionAnswers)
{
AdditionalQuestionAnswerModel newObj = new AdditionalQuestionAnswerModel
{
QuestionText = x.QuestionText;
InstitutionId = x.InstitutionId;
AdditionalQuestionId = x.Id;
AnswerText = y.AnswerText;
IsSelected = false;
};
_model.AddQuestAnswModel.Add(newObj);
}
Ir means that there no item in your _model.AddQuestAnswModel at the indicated postition, and from your code, I see that _model.AddQuestAnswModel has only be initiated with new List<AdditionalQuestionAnswerModel>(), so it does not contain items (unless you're doing it in the contructor).
You need to fill it like so :
_model.AddQuestAnswModel.Add(item);

Categories

Resources