我对编程很新,所以请耐心等待我尝试解释!我一直在寻找这个特定方法一段时间,它可能只是简单,但是,我想将列表框中的所有项目显示为.txt文件。但是它只在我的文本文件中显示以下内容:
System.Collections.Generic.List`1[QA.OrderItem]
我的保存方法在一个类中,我在一个单独的类中有一个覆盖 .ToString,它正确显示列表框中的列表项而不是:
System.Collections.Generic.BlahBlahBlah
我虽然可以使用foreach循环(将使用我的覆盖.ToString),它将迭代我的列表并写入文本文件,但是,这似乎不起作用!
非常感谢任何帮助,感谢您的时间(请参阅下面的所有必要代码)。
在ShoppingBasket
类中保存方法:
public bool SaveBasket(string fileName)
{
// A string that specifies a subfolder to be made.
string path = @"C:\Users\Public\BasketSaves";
// Create the subfolder.
if (!System.IO.Directory.Exists(path)) {
System.IO.Directory.CreateDirectory(path);
}
// Combine the filename to the end of the path.
path = System.IO.Path.Combine(path, fileName + ".txt");
// Check that the file doesn't exsist. If it doesn't, create
// the file and write the list box to it.
if (!System.IO.File.Exists(path)) {
System.IO.File.WriteAllText(path, OrderItems.ToString());
// Return true when the file doesn't exsist.
return true;
}
else {
// Return false when the file exsists.
return false;
}
}
在.ToString()
课程中覆盖OrderItem
:
public override string ToString()
{
return string.Format("{0}\t {1}\t {2}",ProductName, LatestPrice, Quantity);
}
修改
OrderItem
上课:
public class OrderItem : IOrderItem {
public OrderItem(string productName, decimal latestPrice):this(productName, latestPrice, 1) {
}
public OrderItem(string productName, decimal latestPrice, int quantity) {
this.ProductName = productName;
this.LatestPrice = latestPrice;
this.Quantity = quantity;
}
/******************* Properties *******************/
public string ProductName { get; private set; }
public decimal LatestPrice { get; private set; }
public decimal TotalOrder { get; private set; }
public int Quantity { get; private set; }
/*************************************************/
/// <summary>
/// Add multiple items to a basket with a new latest price
/// </summary>
/// <param name="latestPrice">Takes the latest price of a specified product</param>
/// <param name="numberOfItems">Takes the amount you wish to add</param>
/// <returns>The quantity</returns>
public int AddItems(decimal latestPrice, int numberOfItems) {
if (numberOfItems <= 0 || latestPrice < 0) {
throw new ArgumentOutOfRangeException();
}
LatestPrice = latestPrice;
Quantity += numberOfItems;
// Return the Quantity value.
return Quantity;
}
/// <summary>
/// Add multiple items (no price change functionality)
/// </summary>
/// <param name="numberOfItems">Takes the amount you wish to add</param>
/// <returns>The quantity</returns>
public int AddItems(int numberOfItems) {
if (numberOfItems <= 0) {
throw new ArgumentOutOfRangeException();
}
return Quantity += numberOfItems;
}
/// <summary>
/// Adds an item with incrementation
/// </summary>
/// <returns>Incrementation then the Quantity value</returns>
public int AddItem() {
return ++Quantity;
}
/// <summary>
/// Add multiple items
/// </summary>
/// <param name="numberOfItems">Takes the amount you wish to subtract</param>
/// <returns>The quantity</returns>
public int RemoveItems(int numberOfItems) {
Quantity -= numberOfItems;
if (numberOfItems <= 0) {
throw new ArgumentOutOfRangeException();
}
if (Quantity < 0) {
return Quantity = 0;
}
// Return the Quantity if the above is false.
return Quantity;
}
/// <summary>
/// Adds an item with decrementation
/// </summary>
/// <returns>Decrement then the Quantity value</returns>
public int RemoveItem() {
return --Quantity;
}
public override string ToString()
{
return string.Format("{0}\t {1}\t {2}",ProductName, LatestPrice, Quantity);
}
}
ShoppingBasket
上课:
public class ShoppingBasket : IShoppingBasket
{
public ShoppingBasket()
{
OrderItems = new List<OrderItem>();
}
public List<OrderItem> OrderItems { get; private set; }
public int NumberOfProducts {
get {
return OrderItems.Count();
}
}
public decimal BasketTotal { get; private set; }
public int NumberOfItems {
get {
return OrderItems.Count();
}
}
public void AddProduct(string productName, decimal latestValue, int quantity = 1) {
OrderItems.Add(new OrderItem(productName, latestValue));
}
public void RemoveProducts(string productName, int quantity = 1) {
OrderItems.Remove(new OrderItem (productName, quantity));
}
public void ClearBasket() {
OrderItems.Clear();
}
public bool SaveBasket(string fileName)
{
// A string that specifies a subfolder to be made.
string path = @"C:\Users\Public\BasketSaves";
// Create the subfolder.
if (!System.IO.Directory.Exists(path)) {
System.IO.Directory.CreateDirectory(path);
}
// Combine the filename to the end of the path.
path = System.IO.Path.Combine(path, fileName + ".txt");
// Check that the file doesn't exsist. If it doesn't, create
// the file and write the list box to it.
if (!System.IO.File.Exists(path)) {
System.IO.File.WriteAllText(path, OrderItems.ToString());
// Return true when the file doesn't exsist.
return true;
}
else {
// Return false when the file exsists.
return false;
}
}
}
这允许用户将项目添加到购物篮:
private void btnAdd_Click(object sender, EventArgs e) {
OrderItem item = new OrderItem(txtName.Text, Convert.ToDecimal(txtLatestPrice.Text), Convert.ToInt32(txtQuantity.Value));
lbBasket.Items.Add(item.ToString());
}
答案 0 :(得分:1)
我建议的一种方法是在你的收藏中循环写出每个项目。
var sb = new StringBuilder();
foreach(var item in OrderItems)
{
// send item to the text file or build a string using StringBuilder
sb.AppendLine(item.ToString());
}
// now dump sb.ToString() to your text file
MSDN有一个很好的例子,说明如何将文本写入文件:
答案 1 :(得分:1)
尝试以下
System.IO.File.WriteAllLines(path, (IEnumerable<string>)OrderItems.Items);
这是我的头脑,所以不确定它是否会起作用。
否则只做
StringBuilder builder = new StringBuilder();
using(System.IO.StreamWriter writer = new System.IO.StreamWriter(path)
{
foreach(string item in OrderItems.Items)
{
builder.append(string.format("{0}{1}", item, Environment.NewLine));
}
writer.write(builder.ToString());
}
答案 2 :(得分:1)
您在循环中调用WriteAllText
,因此在每次迭代时用当前项替换整个文件。
.NET中的每个类型都从ToString()
别名System.Object
继承方法object
。 ToString()
的默认实现是显示类型名称。 object
以外的其他类型如果要提供其他行为,则必须覆盖ToString()
。
OrderItems
是一个集合(List<T>
)。集合通常不会覆盖ToString()
,因此在转换为字符串时会显示其类型名称。您必须遍历集合并连接其项目的字符串表示形式,以便获得集合内容的足够字符串表示。
由于您已在ToString()
中覆盖了OrderItem
,因此您可以像这样转换List<OrderItem>
:
// Until .NET 3.5
string s = String.Join("\r\n", OrderItems.Select(o => o.ToString()).ToArray());
// From .NET 4.0
string s = String.Join("\r\n", OrderItems.Select(o => o.ToString()));
从.NET Framework 4.0开始File.WriteAllLines
的重载版本也接受枚举。这比使用ToArray()
优势的是,懒惰地计算枚举,并且结果不能作为一个整体保存在内存中。
File.WriteAllLines(filename, OrderItems.Select(o => o.ToString()));
或者您可以遍历列表并将项目逐个写入文件。
<强>更新强>
由于您在将项目添加到列表框时将项目转换为字符串(由于列表框在显示项目时会自动执行,因此您还可以编写如下文件:
File.WriteAllLines(filename, lbBasket.Cast<string>());
您仍然需要演员,因为ObjectCollection
使用的ListBox
不是通用集合,即它实现IEnumerable
但不实现IEnumerable<T>
。
答案 3 :(得分:0)
目前正在撰写
OrderItems.ToString():
到文件并且不会循环项目
它只会给出OrderItems
在您的其他循环代码中,您循环访问文件
最好建立内容,然后写一次
试试这个
if(OrderItems != null && OrderItems.Count > 0)
{
StringBuilder sb = new StringBuilder();
foreach (var item in OrderItems)
{
Debug.WriteLine(item.ToString());
sb.AppendLine(item.ToString());
}
System.IO.File.WriteAllText(path, sb.ToString());
}
else
{
Debug.WriteLine("Nothing to write.");
System.IO.File.WriteAllText(path, "No items");
}
答案 4 :(得分:0)
你的循环没有用,因为WriteAllText方法为每个文件写入文本。 如果您真的想使用此方法,请将所有值连接成一个字符串 在写之前。或者改用StreamWriter。