Convert multiline text into List every Xth line in WPF - c#

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;
}

Related

How to return value of items in Listbox to Textbox

my situation is that I need to add up all prices of items in a Listbox and have the total price in the textbox. I am using c# WinForms. This what I have so far but it is not working correctly by showing total, it is showing the price of the last item I press and not the total of all items
public class SelectedPizza
{
public string Size { get; set; }
public string Name { get; set; }
public string Price { get; set; }
public string Format() => $"{Size} {Name} {Price}"; // Format inside Listbox
}
private void ButtonSizeClick(object sender, EventArgs e)
{
var button = (Button)sender;
_selectedPizza.Size = button.Tag.ToString(); // Adds pizza size to order listbox
if (_selectedPizza.Name != null)
_selectedPizza.Price = GetPrice(_selectedPizza.Size);
}
private void ButtonNameClick(object sender, EventArgs e)
{
var button = (Button)sender;
_selectedPizza.Name = button.Tag.ToString();
if (_selectedPizza.Size != null)
_selectedPizza.Price = GetPrice(_selectedPizza.Size);
listBox1.Items.Add(_selectedPizza.Format()); // Adds pizza name to order listbox
}
private string GetPrice(string sSize)
{
string sPrice = "0.00";
if (sSize == "Large")
sPrice = "11.90";
TxtbxTotal.Text = sPrice; // Displays price in order total textbox
return sPrice;
}
I won't go deep into your problem but I will address the main question.
Finally, you want to sum up the Listbox items.
So to do that, add the below piece to your code:
for (int i = 0; i < listboxname.Items.Count; i++)
{
sum += Convert.ToDecimal(listboxname.Items[i].Text);
}
textBoxtotal.Text = Convert.ToString(sum);
I roughly read the entire code and couldn't find any event relating to total of the listbox. Maybe you missed to write the click event of the total button.
you seem writing a decent program but you are killing it doing this listBox1.Items.Add(_selectedPizza.Format());
you need to use this technology
public interface IFoodItem // all list box items must have certain properties
{
public int Id { get; set; }
string Name { get; set; }
string Price { get; set; }
public string Display { get; }
}
public class Pizza : FoodItem
{
public int Id { get; set; }
public string Size { get; set; }
public string Name { get; set; }
public string Price { get; set; }
public string Display
{
get { return $"{Size} {Name} {Price}"; }
}
}
// another example
public class Sandwhich : FoodItem
{
// . . . . .
}
//. . . . . .
// Get the list
var listData = new List<IFoodItem>();
listData.Add( . . . );
// . . . . .
// this is how you should set the list - DataSource always last
lstList.ValueMember = "Id";
lstList.DisplayMember = "Display";
lstList.DataSource = listData;
// Get selected item info
IFoodItem item = (IFoodItem)lstList.SelectedItem;
txtItemPrice.Text = item.Price;
// Get Total using LINQ
txtTOTALPrice.Text = ((List<IFoodItem>)lstList.DataSource).Sum(item => item.Price);
UPDATE
From OP: "i have to stick to a specification for school, so all I need to know is how to do it with the code that I have got already"
your value is public string Format() => $"{Size} {Name} {Price}"; added here listBox1.Items.Add(_selectedPizza.Format());
In this case you do this (your sum is third part of the string item in the list)
var sum = 0m;
foreach (object item in listBox1.Items)
{
string[] itemParts =
((string)item).Split(default(char[]), StringSplitOptions.RemoveEmptyEntries);
// price is last index
sum += decimal.Parse(itemParts[itemParts.Length - 1]); // get last item
}
txtTotal.Text = sum;
Here is the working unit test
using System;
using System.Collections.Generic;
public class Program
{
public static void Main()
{
var list = new List<object>();
list.Add("aaa xxx 5 10.99");
list.Add("bbb yyy 7 11.99");
list.Add("ccc zzz 8 12.99");
var sum = 0m;
foreach (object item in list)
{
string[] itemParts =
((string)item).Split(default(char[]), StringSplitOptions.RemoveEmptyEntries);
// price's index is 2
sum += decimal.Parse(itemParts[itemParts.Length - 1]);
}
Console.WriteLine(sum);
}
}

Join sub variables in a List

I have my variables class with constructor
public class Gdf2Lines
{
public string line { get; set; }
public int linenumber { get; set; }
public string columnNumber { get; set; }
public string columnName { get; set; }
public Gdf2Lines()
{
line = "";
linenumber = -1;
columnNumber = ""; // prefer to keep as the string read from the text source
columnName = "";
}
}
I have my class that creates of list of the above class and populates the variables within for each line from a file
class GDF2
{
Gdf2Lines Data = new Gdf2Lines();
List<Gdf2Lines> gdf2 = new List<Gdf2Lines>();
public GDF2(string[] arrFile)
{
int count = 0;
foreach (String line in arrFile)
{
Data.line = line;
Data.linenumber = count;
Data.columnNumber = GetColumnNumber(line);
Data.columnName = GetColumnName(line);
count++;
gdf2.Add(Data);
}
}
}
I know a "normal" list can be joined into a string by:
String.Join(Environment.Newline.ToString(), List);
But is there an equally easy way to join one of the (sub) variables within my list, such as
String.Join(",", gdf2.columnName);
Currently I am using a for loop.
Something like this should work:
String.Join(",", gdf2.Select(x => x.columnName));
This uses LINQ to extract a list of columnName values from the list of Gdf2Line.

Load a list from an array

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;

C# Linq "Entity with the same key '0' already added." when inserting multiple rows

I am trying to insert data in bulk, database is MySQL connection is done using Devart LinqConnect.
Here is a code:
DataContext db = new DataContext();
List<XYData> XYDList = new List<XYData>(); // Data Type
List<xydata> xyToBeInsrted = new List<xydata>(); // Database table
XYDList = XYData.genXYData(12, 1234); // Generates 12 example records
foreach (XYData oneXY in XYDList)
{
// Create clear row representation
xydata xy_row = new xydata();
// Assign data from object
xy_row.id = oneXY.Id;
xy_row.Batchid = (int)oneXY.BatchId;
xy_row.Ch = oneXY.Channel;
xy_row.Value = oneXY.Value;
xy_row.Pos = (int)oneXY.Position;
xy_row.Dtm = oneXY.Time;
// Add to list of rows to be inserted
xyToBeInsrted.Add(xy_row);
}
db.xydatas.InsertAllOnSubmit<xydata>(xyToBeInsrted);
db.SubmitChanges();
Last line gives an error "Entity with the same key '0' already added."
When I lower number of items to be generated to 1 then it works. Anything above 1 gives error.
Table has set Auto Increment on record Id field.
Trying to solve that for 2 hours without success.
EDIT:
Data Class:
public class XYData
{
[Column(IsPrimaryKey = true, IsDbGenerated = true)]
public int Id { get; set; }
public int BatchId { get; set; }
public int Channel { get; set; }
public String Value { get; set; }
public double Position { get; set; }
public DateTime Time { get; set; }
private static Random rand = new Random();
public XYData(int channel = 0, string val = "")
{
Channel = channel;
Value = val;
Position = 0;
Time = DateTime.Now;
}
public static List<XYData> genXYData(int howMany, int batchId)
{
List<XYData> _allXYData = new List<XYData>();
for (int i = 0; i < howMany; i++)
{
XYData _singleXY = new XYData();
_singleXY.BatchId = batchId;
for (int j = 64 * (1 << i); j > 0; j--)
{
uint k = (uint)rand.Next(int.MaxValue);
_singleXY.Value += k.ToString("X8");
}
_allXYData.Add(_singleXY); // Add to list
}
return _allXYData; // Return list of generated data.
}
}
Something like this may be needed on your model definition -
[Column(IsPrimaryKey=true, IsDbGenerated=true)]
public int Id { get; set; }
http://www.devart.com/linqconnect/docs/PrimaryKeyMapping.html

What is the best way to declare a class with properties and populate those properties at the same time

Here is an example of what the code could look like from the Model
public static class SomeClass
{
// Description
public const string String1 = "String One"
public const string String2 = "String Two";
public const string String3 = " String Three";
public const string String4 = " String Four";
// Position
public const int String1Position = 0;
public const int String2Position = 1;
public const int String3Position = 2;
public const int String4Position = 3;
// Filter Ranges
public const int String2Minimum = 0100;
public const int String2Maximum = 0199;
public const int String3Minimum = 1000;
public const int String3Maximum = 1099;
public const int String4Unknown = 9999;
private class SomeClassData
{
public string Description { get; set; }
public int Position { get; set; }
public int FilterMinimum { get; set; }
public int FilterMaximum { get; set; }
}
}
I want to be able to populate the properties of this class for each of the different Descriptions, Positions and Filter Range(s) where the Description, the Position and the Filter are all related to each other.
SomeClassData.Description = "String Two";
SomeClassData.Position = 1;
SomeClassData.String2Minimum = 0100;
SomeClassData.String2Maximum = 0199;
Where the Description and the Position are being used in the Controller to be able to give the View the the properties to populate a drop down box using Javascript/JQuery.
The Filter Range(s) will be used by the controller to be able to accept the Position value from drop down box as a parameter from the ActionResult to generate linq queries to get the data back from the database.
I started to think that the best way to go would be to populate a List for each of the different types and then use each of the lists together but then would get messy trying to link the lists together properly.
I have this feeling I might need to use a Dictionary<string, object> or a Dictionary<int, object> where the object is the SomeClassData populated. Not sure if I'm way off on this thought or not at this point.
Yes you can use Dictionary<string,SomeClassData>
var col = Dictionary<string, SomeClassData>
{
{ "Desc1", new SomeClassData{Position =1, String2Minimum =0100, String2Maximum = 0199}},
{ "Desc2", new SomeClassData{Position =1, String2Minimum =0100, String2Maximum = 0199}},
....
};
Select Linq operator
var fix = from entry in col
where entry.Key == "Desc1"
select new entry.Value;
You must create a list of the class you call SomeClassData. Each element will have each corresponding set of values.

Categories

Resources