如何存储我的List <list <class>&gt;在WPF中使用C#的文本文件?</list <class>

时间:2013-11-11 23:26:53

标签: c# wpf file text

我正在尝试使用C#将List<List<Class>>存储到文本文件中,我的类就像

public class cEspecie
{
    private string nombre;
    private BitmapImage imagen;
    private int tiempodevida;
    private int movilidad;
    private int decaimiento;
    private int tipo;
    private string colordelagrafica;
    private bool seleccion;


    public int Tipo
    {
        get
        {
            return tipo;
        }
        set
        {
            tipo = value;
        }
    }

    public string Nombre
    {
        get
        {
            return nombre;
        }
        set
        {
            nombre = value;
        }
    }

    public BitmapImage Imagen
    {
        get
        {
            return imagen;

        }
        set
        {
            imagen = value;
        }
    }

    public int TiempoDeVida
    {
        get
        {
            return tiempodevida;
        }
        set
        {
            tiempodevida = value;
        }
    }

    public int Movilidad
    {
        get
        {
            return movilidad;
        }
        set
        {
            movilidad = value;
        }
    }

    public int Decaimiento
    {
        get
        {
            return decaimiento;
        }
        set
        {
            decaimiento = value;
        }
    }

    public string ColorDeLaGrafica
    {
        get
        {
            return colordelagrafica;
        }
        set
        {
            colordelagrafica = value;
        }
    }

    public bool Seleccion
    {
        get
        {
            return seleccion;
        }
        set
        {
            seleccion = value;
        }
    }
}

 List<List<cEspecie>> items1 = new List<List<cEspecie>>();

如何从“items1”中获取所有数据,以便使用C#将其存储在文本文件中?以及如何将其存回以便将其存储在另一个列表中?

3 个答案:

答案 0 :(得分:4)

我能想到的最简单的方法是使用Xaml实际保存数据。这是一个合适的解决方案,因为您已经在使用WPF。

简单示例:

List<List<cEspecie>> items1 = new List<List<cEspecie>>();
// ... add items...
XamlServices.Save(@"c:\path\to\file.xaml", items1);

然后加载:

var items2 = XamlServices.Load(@"c:\path\to\file.xaml");

请注意,为了实现此目的,您需要将ImagenBitmapImage更改为其基类BitmapSource。这仅在图像加载了URI或文件路径时才有效,并且将使用该URI /路径保存。如果您想阻止Imagen属性保存在Xaml中,您可以使用[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]注释该属性。

这是我的测试代码创建的Xaml文件:

<List x:TypeArguments="List(w:cEspecie)"
      Capacity="4"
      xmlns="clr-namespace:System.Collections.Generic;assembly=mscorlib"
      xmlns:w="clr-namespace:WpfXUnit;assembly=WpfXUnit"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
  <List x:TypeArguments="w:cEspecie"
        Capacity="4">
    <w:cEspecie ColorDeLaGrafica="zomg"
                Decaimiento="42"
                Imagen="file:///w:/dump/test.png"
                Movilidad="76"
                Nombre="'ello gov'na"
                Seleccion="True"
                TiempoDeVida="32"
                Tipo="1" />
  </List>
</List>

答案 1 :(得分:3)

我会考虑使用XMLJSON来序列化/反序列化您的数据。这样,您可以轻松地将数据存储在文件中,通过Web服务等发送。

使用Json.NET会很简单,唯一的问题是存储位图。

string json = JsonConvert.SerializeObject(items1);

根据您决定存储位图的方式,Json.NET无法将其存储为JSON,除非您做了一些魔术。

最简单的方法是不反序列化Bitmap属性,而是在反序列化字符串时加载Image。

this stackoverflow post中提供了一个简单的解决方案。

修改

这是一个基于上面的stackoverflow帖子的示例,使用您的代码。

[JsonObject(MemberSerialization.OptIn)]
public class Especie
{
    private string m_imagePath;

    [JsonProperty]
    public Tipo { get; set; }

    [JsonProperty]
    public string Nombre { get; set; }

    [JsonProperty]
    public int TiempoDeVida { get; set; }

    [JsonProperty]
    public int Movilidad { get; set; }

    [JsonProperty]
    public int Decaimiento { get; set; }

    [JsonProperty]
    public string ColorDeLaGrafica { get; set; }

    [JsonProperty]
    public bool Seleccion { get; set; }

    // not serialized because mode is opt-in
    public Bitmap Imagen { get; private set; }

    [JsonProperty]
    public string ImagePath
    {
        get { return m_imagePath; }
        set
        {
            m_imagePath = value;
            Imagen = Bitmap.FromFile(m_imagePath);
        }
    }
}

答案 2 :(得分:2)

如果您拥有的只是基本类型,那么您需要在您的课程中添加[Serializable]属性,并且可以使用XmlSeralizer将其写入文件。

[Serializable]
public class cEspecie
{
   //...Snip...
}

然而,为了实现这一目标,班级中的所有元素也必须标记为[Serializable],遗憾的是BitmapImage不是。

要解决此问题,我们标记要跳过的不可分割对象,然后我们提供一个可以表示图像的新属性

[Serializable]
public class cEspecie
{
   //...Snip...

    [XmlIgnore] //Skip this object
    public BitmapImage Imagen
    {
        get { return imagen;  }
        set { imagen = value; }
    }

    [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] //This creates a secret hidden property that does not show up in intellisense
    [XmlElement("Imagen")] //It uses the name of the real property for it's name
    public BitmapImageSearalizer ImagenSerialized
    {
        get
        {
            return new BitmapImageSearalizer(imagen);
        }
        set
        {
            imagen = value.GetSearalizedImage();
        }
    }
}

[Serializable]
internal BitmapImageSearalizer
{
    public BitmapImageSearalizer(BitmapImage sourceImage)
    {
        //...Snip...
    }

    public BitmapImage GetSearalizedImage()
    {
        //...Snip...
    }

    //...Snip...
}

我留给你写BitmapImageSearalizer我没有和班级一起工作,写得不够。

为了向您展示一个更完整的已知工作示例,这里是我的一个项目的片段,我只用一个普通的Bitmap对象做了这个精确的技巧

    /// <summary>
    /// 1 bit per pixel bitmap to use as the image source.
    /// </summary>
    [XmlIgnore]
    public Bitmap BitmapImage
    {
        get { return _Bitmap; }
        set
        {
            if (value.PixelFormat != System.Drawing.Imaging.PixelFormat.Format1bppIndexed)
                throw new FormatException("Bitmap Must be in PixelFormat.Format1bppIndexed");
            _Bitmap = value;
        }
    }

    [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
    [XmlElement("Bitmap")]
    public byte[] BitmapSerialized
    {
        get
        { // serialize
            if (BitmapImage == null) return null;
            using (MemoryStream ms = new MemoryStream())
            {
                BitmapImage.Save(ms, ImageFormat.Bmp);
                return ms.ToArray();
            }
        }
        set
        { // deserialize
            if (value == null)
            {
                BitmapImage = null;
            }
            else
            {
                using (MemoryStream ms = new MemoryStream(value))
                {
                    BitmapImage = new Bitmap(ms);
                }
            }
        }
    }