0

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

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# 将其存储在文本文件中?还有我怎样才能让它回来以便将它存储在另一个列表中?

4

3 回答 3

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");

请注意,要使其正常工作,您需要将Imagena更改BitmapImage为其基类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>
于 2013-11-11T23:47:23.287 回答
3

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

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

string json = JsonConvert.SerializeObject(items1);

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

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

这个stackoverflow 帖子中提供了一个简单的解决方案。

编辑:

这是一个基于上面那个 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);
        }
    }
}
于 2013-11-11T23:33:52.000 回答
2

如果您只有基本类型,您需要做的就是[Serializable]在您的类上放置一个属性,然后您可以使用 aXmlSeralizer将其写入文件。

[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);
                }
            }
        }
    }
于 2013-11-12T00:00:33.273 回答