I have a program that is working except that my data is contained in an array; however, I have found out from you people that I cannot load a dataGridView from an array.
If I had code like this, how would I load a List for the source of the dataGridView1...
// Load some date to indicate what I'm trying to do.
int nColName = 0;
int nColNumberOfOccurances = 1;
int nColTotalTime = 2;
int nColAverageTime = 3;
string[,] strMyArray = new string[2,4];
// load array with test data
for (int i = 0; i < strMyArray.Length; i++)
{
switch (i)
{
case 0:
strMyArray.SetValue("file1.log".ToString(), i, nColName);
strMyArray.SetValue("10".ToString(), i, nColNumberOfOccurances);
strMyArray.SetValue("8989".ToString(), i, nColTotalTime);
strMyArray.SetValue("898.9".ToString(), i, nColAverageTime);
break;
case 1:
strMyArray.SetValue("file2.log".ToString(), i, nColName);
strMyArray.SetValue("5".ToString(), i, nColNumberOfOccurances);
strMyArray.SetValue("4494.5".ToString(), i, nColTotalTime);
strMyArray.SetValue("898.9".ToString(), i, nColAverageTime);
break;
}
}
// convert an array like the above into a List so that I can say...
// myNewListFromArray = strMyArray
// dataGridView1.DataSource = myNewListFromArray;
Arrays works with DataGridView. Your problems is - you using two dimensional array which cannot be used as DataSource.
Instead of array, create a class with properties which represent your data.
Note: important to use a property, because DataGridView binding works with properties only.
public class MyData
{
public string Name { get; set; }
public string NumberOfOccurances { get; set; }
public string TotalTime { get; set; }
public string AverageTime { get; set; }
}
Then use this class in the List
var list = new List<MyData>
{
new MyData
{
Name = "file1.log",
NumberOfOccurances = "10",
TotalTime = "8989",
AverageTime = "898.9"
},
new MyData
{
Name = "file2.log",
NumberOfOccurances = "5",
TotalTime = "4494.5",
AverageTime = "898.9"
},
}
dataGridView1.DataSource = list;
Related
I basically want to take the following example text and put it into a list.
The multiline text looks like this
12182718271827
Example
More Text
WEUIWEU
12718271892781
Example 2
More Text
WUQIWUQ
...
My list class looks like this:
public class Data {
public string id { get; set; }
public string employee { get; set; }
public string position { get; set; }
public string access { get; set; }
}
Can this be achieved?
Try this. Code not tested.
//Line position counter
int idCount = 0;
int employeeCount = 1;
int positionCount = 2;
int accessCount = 3;
//Create collection for data
ObservableCollection<Data> empData = new ObservableCollection<Data>();
//Read lines from text file and add them to an array
//Make sure the text file does not contain an empty lines
string[] lines = System.IO.File.ReadAllLines(#"C:\TestFolder\Data.txt");
//Loops through the array and add every set of 4 items to collection
while(accessCount <= lines.Count())
{
empData.Add(new Data { id = lines[idCount], employee = lines[employeeCount], position = lines[positionCount], access = lines[accessCount]});
idCount += 4;
employeeCount += 4;
positionCount += 4;
accessCount += 4;
}
The button 1-10 are the items;
the pos screenshot
codes i used but doesn't work maybe it's wrong but i can't find answers on the internet
private void enterPayment_Click(object sender, EventArgs e)
{
label1.Text = "Payment";
//price.ReadOnly = false;
//price.Text = "0.00";
//price.Focus();
//Kukunin ko yung total ng List Items
double total = 0;
int ilan = orders.Items.Count;
for (int i = 0; i >= ilan; i++)
{
string item = orders.Items[i].ToString();
int Index = item.IndexOf("#");
int Length = item.Length;
string presyoString = item.Substring(Index + 1, Length - Index - 1);
double presyoDouble = double.Parse(presyoString);
total += presyoDouble;
//price.Text = (total + ".00");
}
price.Text = (total + ".00");
}
I strongly recommend that you use the listbox as a view only, not to be use to perform the mathematical operation. The data can be use in collection such as List so that you can perform better operation.
For example, at program load, I will add product information on List<T> and on form, I place a tag in the button consider it as product Id. So, when I click on the button, it will pass the tag property and from there, I will search the product information on list regarding my Id and add into another final List<T> and get the sum of it.
public partial class Form1 : Form
{
private List<ProductDisplay> listProductDisplay = new List<ProductDisplay>();
private List<ProductInformation> listProductInfo = new List<ProductInformation>();
public Form1()
{
InitializeComponent();
LoadProduct();
}
private void LoadProduct()
{
listProductDisplay = new List<ProductDisplay>()
{
new ProductDisplay{ProdID = 1,ProdName = "Chargrilled Burger",ProdPrice = 330.00m},
new ProductDisplay{ProdID = 2,ProdName = "Mushroom N' Swish",ProdPrice = 330.00m},
new ProductDisplay{ProdID = 3,ProdName = "Chicken Burger",ProdPrice = 250.00m},
new ProductDisplay{ProdID = 4,ProdName = "Steak Loader",ProdPrice = 220.00m},
new ProductDisplay{ProdID = 5,ProdName = "Cookie Sandwich",ProdPrice = 125.00m},
new ProductDisplay{ProdID = 6,ProdName = "Cookie Sundae",ProdPrice = 175.00m},
new ProductDisplay{ProdID = 7,ProdName = "Chicken Nuggets",ProdPrice = 145.00m},
new ProductDisplay{ProdID = 8,ProdName = "Curly Fries",ProdPrice = 75.00m},
new ProductDisplay{ProdID = 9,ProdName = "Sprite",ProdPrice = 50.00m},
new ProductDisplay{ProdID = 10,ProdName = "Coke",ProdPrice = 50.00m}
};
}
private void InsertOrder_ButtonClick(object sender, EventArgs e)
{
try
{
Button btn = (Button)sender;
int number = Convert.ToInt32(btn.Tag);
var itemProduct = listProductDisplay.First(x => x.ProdID == number);
ProductInformation prod = new ProductInformation
{
ProdID = itemProduct.ProdID,
ProdName = itemProduct.ProdName,
ProdPrice = itemProduct.ProdPrice,
ProdQty = 1
};
prod.ProdDisplayName = $"{prod.ProdQty}x {prod.ProdName} #{prod.ProdPrice.ToString("F")} = {(prod.ProdPrice * prod.ProdQty).ToString("F")}";
listProductInfo.Add(prod);
listBoxItem.DataSource = null;
listBoxItem.DataSource = listProductInfo;
listBoxItem.DisplayMember = "ProdDisplayName";
listBoxItem.ValueMember = "ProdID";
var price = listProductInfo.Sum(t => (t.ProdPrice * t.ProdQty));
txtPayment.Text = price.ToString("F");
}
catch (Exception ex)
{
MessageBox.Show("Failed to insert order");
throw;
}
}
}
public class ProductDisplay
{
public int ProdID { get; set; }
public string ProdName { get; set; }
public decimal ProdPrice { get; set; }
}
public class ProductInformation
{
public int ProdID { get; set; }
public string ProdName { get; set; }
public string ProdDisplayName { get; set; }
public decimal ProdPrice { get; set; }
public int ProdQty { get; set; }
}
Parsing and extracting values from a string like that is very error prone and brittle. What happens if the order of fields in your line changes? Or if you add currency symbols?
#Luiey's solution is the smartest way to go ahead. But if for some reason you cannot make so many changes to your code, the bare minimum you want to do is store the items in a list as a custom object with statically typed fields for price, quantity and total. The ListBox class invokes a ToString() at the time of rendering items. So you can easily override this method to prepare the output string according to your needs.
private class LineItem
{
public LineItem()
{
Quantity = 0;
Description = string.Empty;
Price = 0;
}
public int Quantity
{
get;
set;
}
public string Description
{
get;
set;
}
public int Price
{
get;
set;
}
public int Total
{
get
{
return Quantity * Price;
}
}
public override string ToString()
{
return $"{Quantity} × {Description} # {Price} = {Total}";
}
}
Then you add an item to your ListBox like this.
var item = new LineItem()
{
Quantity = 1,
Description = "Foo bar",
Price = 10
};
listBox1.Items.Add(item);
And add them up like this.
var items = listBox1.Items.Cast<LineItem>().ToArray();
var accumulator = 0;
accumulator = items.Aggregate(accumulator, (a, i) => a + (i.Quantity * i.Price), (a) => a);
I have a class Devices
public class Devices
{
public string nombre { get; set; }
public string valueY { get; set; }
public string valueZ { get; set; }
}
and have a function
private void fillData(JArray arrData)
{
var data = new List<Devices>();
for(int i = 0; i<arrData.Count; i++)
{
data.Add(new Devices
{
nombre = "X",
valueY = "Y",
valueZ = "Z"
});
}
list.ItemsSource = data;
}
When check 'data' I just have 'Non-public members' instead of real values.
Please help.
Obviously, arrData.Count is 0 and the loop never iterated. Check the arrData. It would add items if you set const limit for loop.
for(int i = 0; i < 1; i++)
{
data.Add(new Devices
{
nombre = "X",
valueY = "Y",
valueZ = "Z"
});
}
I think you are trying to access the data from ViewModel. Non-public member simply mean that the access modifier is not public. In your case it is private. Try changing it to public.
I'm trying to find out the index of a string in an array within a JObject object. For example, you could give frc610 and it would return 0.
// Get rankings JSON file from thebluealliance.com
string TBArankings = #"https://www.thebluealliance.com/api/v2/district/ont/2017/rankings?X-TBA-App-Id=frc2706:ONT-ranking-system:v01";
var rankings = new WebClient().DownloadString(TBArankings);
string usableTeamNumber = "frc" + teamNumberString;
string team_key = "";
int rank = 0;
dynamic arr = JsonConvert.DeserializeObject(rankings);
foreach (dynamic obj in arr)
{
team_key = obj.team_key;
rank = obj.rank;
}
int index = Array.IndexOf(arr, (string)usableTeamNumber); // <-- This is where the exception is thrown.
Console.WriteLine(index);
// Wait 20 seconds
System.Threading.Thread.Sleep(20000);
Here's the json file I'm using.
I've tried multiple different solutions, none of which worked.
You could just keep the index in variable.
string usableTeamNumber = $"frc{teamNumberString}";
string team_key = "";
int rank = 0;
int index = 0;
int count = 0;
dynamic arr = JsonConvert.DeserializeObject(rankings);
foreach (dynamic obj in arr)
{
team_key = obj.team_key;
rank = obj.rank;
if (usableTeamNumber.Equals(team_key) {
index = count;
}
count++;
}
Console.WriteLine(index);
Create a class that mimics your data structure, like such (only has 3 of the root fields):
public class EventPoints
{
public int point_total { get; set; }
public int rank { get; set; }
public string team_key { get; set; }
}
Then you can Deserialize the object into a list of those objects and you can use LINQ or other tools to query that list:
string teamNumberString = "frc2056";
string TBArankings = #"https://www.thebluealliance.com/api/v2/district/ont/2017/rankings?X-TBA-App-Id=frc2706:ONT-ranking-system:v01";
var rankings = new WebClient().DownloadString(TBArankings);
List<EventPoints> eps = JsonConvert.DeserializeObject<List<EventPoints>>(rankings);
EventPoints sp = eps.Where(x => x.team_key.Equals(teamNumberString)).FirstOrDefault();
Console.WriteLine(eps.IndexOf(sp));
Console.ReadLine();
My problem is that I have a list that contains a few strings and inside this list another list of decimals, something like this:
public class excelInventario
{
public excelInventario() { cols = new List<decimal>); }
public string codigo { get; set; }
public string nombre { get; set;} .
public List<decimal> cols { get; set; } //Lista de columnas
public decimal suma { get; set; }
public decimal stock { get; set; }
public decimal diferencia { get; set; }
public decimal precio { get; set; }
}
and now I need to put this in Excel. The problem is that when I use the method LoadFromCollection(MyList) the strings appear well in Excel, but the list of decimals is not put correctly, but:
System.Collections.Generic.List`1[System.Decimal].
Can I adapt this method or do I need to use a loop and put "manually" the row values one by one?
I suspect this second option it will be inefficient.
---------------EDIT TO ADD MORE CODE--------------
int tamcolumnas=excelin[0].cols.Count;
using (ExcelPackage package = new ExcelPackage(file))
{
ExcelWorksheet hoja = package.Workbook.Worksheets.Add("Comparativo unidades contadas VS stock");
hoja.Cells["A1"].Value = "CODART";
hoja.Cells["B1"].Value = "NOMBRE";
for(int i=0;i<tamcolumnas;i++)
{ hoja.Cells[1, i+3].Value = "COL"+(i+1); }
var MyList = new List<excelInventario>();
hoja.Cells.LoadFromCollection(MyList,true);
hoja.Cells[2, 3].LoadFromArrays(MyList.Select((r) => r.cols.Cast<object>).ToArray()));
in this last line is where fails.
Say:
System.ArgumentOutOfRangeException
The specified argument is outside the range of valid values.
Since those are Lists the closest you can get to automation is the LoadFromArray since those are not true objects. Its not exactly pretty since it requires casting so check for performance hits. Otherwise, it may be best to use plain old loops. Here is what I mean:
[TestMethod]
public void ListOfList_Test()
{
//http://stackoverflow.com/questions/33825995/how-to-use-loadfromcollection-in-epplus-with-a-list-containing-another-list-insi
//Throw in some data
var MyList = new List<TestExtensions.excelInventario>();
for (var i = 0; i < 10; i++)
{
var row = new TestExtensions.excelInventario
{
codigo = Path.GetRandomFileName(),
nombre = i.ToString(),
cols = new List<decimal> {i, (decimal) (i*1.5), (decimal) (i*2.5)}
};
MyList.Add(row);
}
//Create a test file
var fi = new FileInfo(#"c:\temp\ListOfList.xlsx");
if (fi.Exists)
fi.Delete();
int tamcolumnas = 10; // excelin[0].cols.Count;
using (ExcelPackage package = new ExcelPackage(fi))
{
ExcelWorksheet hoja = package.Workbook.Worksheets.Add("Comparativo unidades contadas VS stock");
hoja.Cells["A1"].Value = "CODART";
hoja.Cells["B1"].Value = "NOMBRE";
for (int i = 0; i < tamcolumnas; i++)
{
hoja.Cells[1, i + 3].Value = "COL" + (i + 1);
}
//var MyList = new List<TestExtensions.excelInventario>();
hoja.Cells.LoadFromCollection(MyList, true);
//hoja.Cells[2, 3].LoadFromArrays(MyList.Select((r) => r.cols.Cast<object>).ToArray()));
hoja.Cells[2, 3].LoadFromArrays(MyList.Select((r) => r.cols.Cast<object>().ToArray()));
package.Save();
}
}