通过类</t>在.txt文件中显示List <t>的内容

时间:2014-01-03 14:32:50

标签: c# .net listbox

我对编程很新,所以请耐心等待我尝试解释!我一直在寻找这个特定方法一段时间,它可能只是简单,但是,我想将列表框中的所有项目显示为.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());
    }

5 个答案:

答案 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有一个很好的例子,说明如何将文本写入文件:

Write text to a file

答案 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继承方法objectToString()的默认实现是显示类型名称。 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。