I have in a SearchFlyClass an Arraylist GetFly()
...
public ArrayList GetFly(int tip, string country)
{
...
var list = new ArrayList();
var reader = command.ExecuteReader();
if (reader.HasRows)
{
...
while (reader.Read())
{
decimal nr_zbor = reader.GetDecimal(cod_zbor);
string aeroport = reader.GetString(nume_aeroport);
string companie = reader.GetString(nume_companie);
list.Add(nr_zbor);
list.Add(companie);
list.Add(aeroport);
}
}
...
and I wish to put in Form1.cs the list in listview by columns[zbor(colZbor),airport(colAirport),company(colCompany)], but I don't now how
private SearchFlyClass searchFly = new SearchFlyClass();
private ArrayList fly = new ArrayList();
...
private void ShowResultFlySearch(int direction, string country)
{
fly = searchFly.GetFly(direction, country);
for (int count = 0; count < fly.Count; count++)
{
string zbor = fly[0].ToString();
string companie = fly[1].ToString();
string aeroport = fly[2].ToString();
ListViewItem searchlist = new ListViewItem();
searchlist.Items.Add(new ListViewItem(elem));
}
}
can someone help me, please?
First you have to put ListView to View mode details, which you do with following code (it is also possible with setting View property in designer):
ListView listView = new ListView();
listView.View = View.Details;
Then you have to assign columns to the listView (can also be done in designer):
listView.Columns.Add("zbor");
listView.Columns.Add("airport");
listView.Columns.Add("company");
After this you have to assign other columns to ListViewItem subitems, by modifying your function:
private void ShowResultFlySearch(int direction, string country)
{
fly = searchFly.GetFly(direction, country);
for (int count = 0; count < fly.Count; count++)
{
string zbor = fly[0].ToString();
string companie = fly[1].ToString();
string aeroport = fly[2].ToString();
ListViewItem listViewItem = new ListViewItem(zbor);
listViewItem.SubItems.Add(airport);
listViewItem.SubItems.Add(companie);
listView.Items.Add (listViewItem);
}
}
The function assumes that it is in Form1.cs and that you have listView variable instantized as class variable of type ListView. Basics of C# and object oriented programming.
There are lots of issues with this code. Firstly, is there any reason that you're using ArrayList instead of the generic collection types? E.g. List<T>
Secondly, I would create a type to store all of the related data for one instance of your entity, rather than putting the column values for the entity into an untyped collection.
Thirdly, your aren't referencing count anywhere in your for loop - presumably because the query is returning a single entity, and therefore the for loop is redundant because you know the number of items returned for a single entity. You are also using a variable elem which doesn't seem to have been defined.
Updated
Define a type that describes your entity:
public class Flight
{
public decimal Code { get; set; }
public string Company { get; set; }
public string Airport { get; set; }
}
Change your method to return an instance of your entity:
public Flight GetFlight(int tip, string country)
Create a new instance to return from the method and populate it from your database query result:
var flight = new Flight();
flight.Code = reader.GetDecimal(cod_zbor);
flight.Airport = reader.GetString(nume_aeroport);
flight.Company = reader.GetString(nume_companie);
return flight;
Now your other method can use the updated method:
var flight = searchFly.GetFlight(...);
// access flight properties here
This assumes that your query returns a single entity. If it returns a collection, then you can use List<Flight> or IEnumerable<Flight> as your return type as appropriate.
Related
I am stuck on how to show items from a list in a picker.
I can use a for loop and add the items to the Picker, is there any other way ? I have to also use bound values from the list. All I get right now is the type and not the ID or Category name i need.
Image of what I see...
private async void GetCategories(string url)
{
//get json as a string
var result = await _clientHttp.GetStringAsync(url);
var json = JsonConvert.DeserializeObject<List<CategoryList>>(result);
List<CategoryList> tempList = new List<CategoryList>();
foreach (var items in json)
{
tempList.Add(new CategoryList{CatId = items.CatId,category = items.category});
}
;
PickerCategory.ItemsSource = tempList;
}
You must override your CategoryList.ToString() method to display the appropriate values:
class CategoryList{
public string category {get;set;}
public override string ToString(){
return category;
}
}
I know this is asked many times and i am trying to implement same . I have list below
internal class GenList
{
public string Col1 { set; get; }
public string Col2 { set; get; }
}
List<GenList> MainList = new List<GenList>();
I want to copy list into other list and dont want content to change in cloned list if something is changed in main list. So i am trying to do below
List<GenList> cloned = MainList.ConvertAll(GenList => new GenList {});
I dont know what to enter inside those curly braces in above line.
dont want content to change in cloned list if something is changed in main list.
That sounds like you want a deep clone, basically. In other words, creating a new list where each element is a copy of an element in the original list, not just a reference to the same object as the original list refers to.
In your case, that's as simple as:
var cloned = MainList.ConvertAll(x => new GenList { Col1 = x.Col1, Col2 = x.Col2 });
Or with LINQ:
var cloned = MainList.Select(x => new GenList { Col1 = x.Col1, Col2 = x.Col2 })
.ToList();
But note that:
If you add a new property, you will need to change this code
If you add a property of a mutable type, you'd need to clone that too
Options to consider:
Adding a DeepClone() method to GenList, to keep the logic in one place however many places need it.
Adding a constructor instead: GenList(GenList) which copies appropriately
Using immutable types instead (e.g. make GenList immutable) at which point shallow clones of collections are sufficient.
Here is a quick deep clone solution via serialization:
[Serializable]
public class GenList
{
public string Col1 { set; get; }
public string Col2 { set; get; }
public GenList DeepClone()
{
using (var stream = new MemoryStream())
{
var formatter = new BinaryFormatter();
formatter.Serialize(stream, this);
stream.Position = 0; //reset stream
var cloned = formatter.Deserialize(stream) as GenList;
return cloned;
}
}
and a test to verify:
[TestClass]
public class DeepCloneTests
{
[TestMethod]
public void ReferencesAreNotMaintained()
{
var object1 = new GenList() { Col1 = "a", Col2 = "b" };
var cloned = object1.DeepClone();
Assert.AreEqual(object1.Col1, cloned.Col1);
Assert.AreEqual(object1.Col2, cloned.Col2);
cloned.Col1 = "c";
cloned.Col2 = "d";
Assert.AreNotEqual(object1.Col1, cloned.Col1);
Assert.AreNotEqual(object1.Col2, cloned.Col2);
}
}
I have a class GetSearchFilters_Results which has two lists:
[DataContract]
public class GetSearchFilters_Results
{
public List<ElementList> ElementList{ get; set; }
public List<Managers> ManagerList { get; set; }
}
I have a file called Service.cs:
public GetSearchFilters_Results GetSearchFilters(string DomainID)
{
//Main List return List
//List<GetSearchFilters_Results> SearchFilterResults = new List<GetSearchFilters_Results>();
//Class
GetSearchFilters_Results GSF = new GetSearchFilters_Results();
string cs = ConfigurationManager.ConnectionStrings["TestDB"].ConnectionString;
try
{
using (SqlConnection con = new SqlConnection(cs))
{
con.Open();
SqlCommand cmd = new SqlCommand("spCPMapp_GetSearchFilters", con);
cmd.Parameters.AddWithValue("#Domain_Id", DomainID);
cmd.CommandType = CommandType.StoredProcedure;
SqlDataAdapter sqlDa = new SqlDataAdapter(cmd);
DataSet Ds = new DataSet();
sqlDa.Fill(Ds);
DataTable DtWBS = new DataTable();
DataTable DTManager = new DataTable();
sqlDa.Fill(Ds);
DtWBS = Ds.Tables[0];
DTManager = Ds.Tables[1];
//Get WBS Elements List
if (DtWBS.Rows.Count > 0)
{
List<ElementList> ElementList= new List<ElementList>();
for (int i = 0; i < DtWBS.Rows.Count; i++)
{
ElementList wbs = new ElementList();
wbs.ProjectID = Convert.ToInt32(DtWBS.Rows[i]["Project_ID"].ToString());
wbs.WBSElementName = DtWBS.Rows[i]["WBSShort"].ToString();
WBSElementsList.Add(wbs);
//GSF.WBSElementsList.Add(wbs);
}
GSF.WBSElementsList = WBSElementsList;
//SearchFilterResults.Add(GSF);
}
//Get Managers List Start
if (DTManager.Rows.Count > 0)
{
List<Managers> ManagersList = new List<Managers>();
for (int i = 0; i < DTManager.Rows.Count; i++)
{
Managers Mgr = new Managers();
Mgr.TimeSheetID = Convert.ToInt32(DTManager.Rows[i]["Project_ID"].ToString());
Mgr.ManagerName = DTManager.Rows[i]["Manager"].ToString();
//GSF.ManagerList.Add(Mgr);
ManagersList.Add(Mgr);
}
GSF.ManagerList = ManagersList;
}
//Manager List End
}//Using End
//SearchFilterResults.Add(GSF);
}
catch (SqlException sqlEx)
{
sqlEx.ToString();
}
catch (FaultException ex)
{
ex.ToString();
}
catch (OverflowException e)
{
e.ToString();
}
return GSF.ManagerList; // I am getting error, how to add two lists into single objectGetSearchFilters_Results
}
And another class Elements:
[DataContract]
public class Elements
{
}
My questions are:
How can I add two separate lists into a single object?
I am getting an error if I add one list into the GetSearchFilter object that says:
Cannot implicitly convert type to System.Collection.Generic.List to System.Namespace.GetSearchFilterResult() method.
How do I fix this error?
Your problem is that you are returning a List and not a GetSearchFilter_Results.
If you intend to return a GetSearchFilter_Results object like the function header says, you can change your last line to:
return GSF;
Edit and side note:
You asked how to add two lists together. Assuming the lists are of the same object, you can use the AddRange() function like this:
List<string> stringListA = new List<string>();
List<string> stringListB = new List<string>();
stringListA.AddRange(stringListB); // stringListA now holds the elements from both A and B.
Another addition, hopefully I don't add too much
I've also noticed you don't differentiate how you catch each exception. I don't know what you need for your case, but you can eliminate several lines of code by simply saying:
catch(Exception e)
{
e.ToString();
}
Instead of multiple catch statements that all do the same thing.
You're posting an awful lot of code for this. Maybe try abstracting away a bit of your logic so it's cleaner and easier to read through?
Your problem is you're attempting to place a List<ManagerList> into a return of GetSearchFilters_Results. Though a List of ManagerList is a property of your GetSearchFilters_Results, they cannot be "implicitly converted" as the error states.
You would want to do something like this potentially:
[DataContract]
public class GetSearchFilters_Results
{
public List<ElementList> ElementList{ get; set; }
public List<Managers> ManagerList { get; set; }
public GetSearchFilters_Results
{
ElementList = new List<ElementList>();
ManagerList = new List<ManagerList>();
}
public GetSearchFilters_Results Execute()
{
this.ELementList = this.GetElementList();
this.ManagerList = this.GetManagerList();
return this;
}
public List<ElementList> GetElementList()
{
List<ElementList> list = new List<ElementList>();
// Get list information from db
return list;
}
public List<ManagerList> GetManagerList()
{
List<ManagerList> list = new List<ManagerList>();
// Get list information from db
return list;
}
}
You require the function
GetSearchFilters to return
GetSearchFilters_Results
but what you return really is
GSF.ManagerList
which is of type
List<Managers> ManagerList
That was your error. Anyway for the part 1 pf your question, you can create a class with two data members, each one is a list, then in the constructor or in a separated function, you pass two parameters each for list:
public Class TwoListsClass
{
List <type1> list1;
List <type2> list2;
public TwoListsClass (List <type1> list1, List <type2> list2)
{
this.list1 = list1;
this.list2 = list2;
}
}
then, when you finish the valuating of the two lists you can call the constructor or the function you wrote.
Wow, this is the older hard way to do things.... consider this: You already have two models.
public List<ElementList> ElementList{ get; set; }
public List<Managers> ManagerList { get; set; }
This tells me is could be generated from EF, which is good....
Now, there's a little known but very cool method in EF that looks like this:
public List<MyType> QueryThis(ViewModel vm)
{
using (var db = new MyEntities()){
var parms = GetParms(vm);
var query = Resources.QueryStrings.MyQuery;
var stuff = db.Database.SqlQuery<MyType>(query, parms);
return stuff.ToList();
}
Emphasis on the type being passed into the SQLQuery...
So all you really have to do is provide a new model that combines all the fields you want back and SQL will fill them in for you automatically. The class MyType will have all the fields from both models. SQL also knows how to populate base classes so you can inherit from one class and just enter in fields of the smaller class. No more parsing or even hitting the db more than once. Just tune up the query to get what you need in one shot.
All filtering from this point on can be done using LINQ... it's the new way to use the concepts of ADO.NET disconnected mode. When you dig into this a bit deeper you'll discover repositories, but that's for another day.
var filtered = MyTypeList.Where(p=>p.ManagerName == "SomeValue");
var filtered = MyTypeList.Where(p=>p.ElementType == "Somevalue");
I have defined variables as string arrays. I also have a form called form4 and on this form I have 1 textbox and 1 combobox.
I have this code in a class:
public class food
{
public string[] name1 = new string [20];
public string[] name2 = new string [50];
public string[] name3 = new string [40] ;
public string[] name = new string [20];
public string[] type = new string [15];
//private const int total = 11;
public int[] calories_ref;
public int i, i2;
public Form4 form = new Form4();
public food(string[] Name1, string[] Name, string[] Type1, int[] kcal)
{
name1 = Name1;
name = Name;
type = Type1;
calories_ref = kcal;
}
public food()
{
}
private void settypes()
{
type[0] = "Bebidas não alcoólicas";
type[1] = "Bebidas Alcóolicas";
type[2] = "Fruta";
type[3] = "Hidratos de Carbono";
type[4] = "Peixe";
type[5] = "Carne";
type[6] = "Cereais";
type[7] = "Lacticínios";
type[8] = "Óleos/Gorduras";
type[9] = "Leguminosas";
type[10] = "Legumes";
for (int i = 0; i < type.Length; i++)
{
form.comboBox1.Items.Add(type[i]);
}
}
In the settypes() method I define the various types of food, more concretly the food wheel. How can I can use these values as items in the combobox that is in form4?
You can add an array of strings using method AddRange(array[]) from comboBox.
form.comboBox1.Items.AddRange(type);
Here is a void you can use if you want to go beyond just one array.
public void AddToCombo(Array array, ComboBox c)
{
foreach(var a in array)
{
c.Items.Add(a);
}
}
You shouldn't be storing a Form4 object in your food class. Your code as it is creates a brand new Form4 every time the food object is created. As shown in the line:
public Form4 form = new Form4();
This won't actually be shown on screen though as you do nothing else with the form except add items to the ComboBox, which also wouldn't show on the screen.
Even if you were to get it shown on the screen, you will still get an error similar to:
Form4.comboBox1 is inaccessible due to its protection level
This is due to the fact that the ComboBox is created internally with private access modifier. (See http://msdn.microsoft.com/en-us/library/ms173121.aspx for more details).
What you need to do is get your existing Form4 to ask the food object to populate it's ComboBox by passing the ComboBox to a method on the food object similar to this example (in your Form4 code not your food code):
private void Form4_Load(object sender, EventArgs e)
{
food f = new food(); //or however you wanted to create the object
f.AddTypesToComboBox(this.comboBox1);
}
The AddTypesToComboBox method would be defined like this in your food object:
public void AddTypesToComboBox(ComboBox box)
{
for (int i = 0; i < type.Length; i++)
{
box.Items.Add(type[i]);
}
}
Also, at the moment the function won't actually add anything to the ComboBox as your type array is not being filled with data. You need to call settypes(); in the food object's constructors like this:
public food(string[] Name1, string[] Name, string[] Type1, int[] kcal)
{
settypes();
name1 = Name1;
name = Name;
type = Type1;
calories_ref = kcal;
}
public food()
{
settypes();
}
You will need to remove public Form4 form = new Form4(); from your variable declaration section as well as removing the following from your settypes() method:
for (int i = 0; i < type.Length; i++)
{
form.comboBox1.Items.Add(type[i]);
}
Your settypes() should only fill the data into the array, and not try and add it to the ComboBox.
If you want the items to be in the ComboBox just set the array as its datasource. You don't need to loop through the array and add the items one by one. It's a lot less code than the other solutions here.
public void SetTypes()
{
comboBox1.DataSource = new[]{
"Bebidas não alcoólicas",
"Bebidas Alcóolicas",
"Fruta",
"Hidratos de Carbono",
"Peixe",
"Carne",
"Cereais",
"Lacticínios",
"Óleos/Gorduras",
"Leguminosas",
"Legumes"
};
}
Not at my computer at the moment, but this should do it:
foreach(var type in type[])
{
form.comboBox1.Items.Add(type);
}
As simple as this:
public void yourMethodName() {
yourComboBoxName.removeAllItems();
for (YourObjectName object: yourArrayListName) {
yourComboBoxName.addItem(object.getWhatYouWanaGet());
}
}
Your remove the actual item from the list than you add the item you want to add :)
If this is an Array in Class1:
public static string[] session = new string[] { "2023-2024", "2022-2023","2021-2022" };
In C# (Windows Forms):
comboBox1.Items.Clear();
comboBox1.Items.AddRange(Class1.session);
I am trying to add a few rows I got from a DataTable to my list using this struct:
protected struct roleProperties
{
public string roleName { get; set; }
public string[] functionTitle { get; set; }
}
As you can see I want more strings inside the method Title string
I have been trying to do it like this:
public void getRoleFuncs(int roleId)
{
List<roleProperties> roles = new List<roleProperties>();
int i = 1;
SqlParameter ro_id = new SqlParameter("#ro_id", roleId);
string q = "SELECT ro_name, fu_title FROM roles INNER JOIN rolefunctions ON roles.ro_id = rolefunctions.fk_role_id INNER JOIN functions ON rolefunctions.fk_func_id = functions.fu_id WHERE ro_id = #ro_id";
SqlDataReader r = gm.returnReader(q, ro_id);
while (r.Read())
{
roleProperties item = new roleProperties();
item.roleName = r["ro_name"].ToString();
foreach (IDataRecord str in r)
{
item.functionTitle[i] = r["fu_title"].ToString();
i++;
}
roles.Add(item);
}
}
But I get a null reference on this line:
item.functionTitle[i] = r["fu_title"].ToString();
Can anyone see what I am doing wrong?
item.functionTitle is null because arrays are reference types and you have not initialized the property anywhere (so it has the default value: null for a reference type).
Even if that was not a problem (let's say functionTitle is an empty array) item.functionTitle[i] would again throw because it tries to access an index that is out of bounds. And finally, you have an off-by-one error: the first element in an array has the index 0, not 1.
You can fix all of the above by changing the code to
while (r.Read())
{
roleProperties item = new roleProperties();
item.roleName = r["ro_name"].ToString();
item.functionTitle = r.Select(o => o["fu_title"].ToString()).ToArray();
roles.Add(item);
}
Your array is not initialized and hence null since you do not know the size of the array you are going to need it seems a more suitable approach to use a list instead
change your struct to
protected class roleProperties
{
public string roleName { get; set; }
public IList<string> functionTitle { get; private set;}
public roleProperties(){
functionTitle = new List<string>();
}
}
and then change
item.functionTitle[i] = r["fu_title"].ToString();
to
item.functionTitle.Add(r["fu_title"].ToString());
I've changed the struct to a class because it's mutable and mutable structs are evil.
Initialize the array first.
item.functionTitle = new string[n]; // where n is an int