实施保存/加载功能的方式是什么? [英] What's the way to implement Save / Load functionality?

查看:79
本文介绍了实施保存/加载功能的方式是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试为Windows Forms应用程序实现加载/保存功能.

I'm trying to implement a Load / Save function for a Windows Forms application.

我有以下组件:

  • 树状视图
  • 几个列表视图
  • 几个文本框
  • 几个对象(其中有一个大词典列表)

我想实现一种将所有这些保存到文件中,并在以后恢复/加载的方法.

I want to implement a way to save all of this into a file, and resume/load it later on.

执行此操作的最佳方法是什么?

What's the best way to do this?

我认为XML序列化是必经之路,但我不确定如何或从何开始.还是需要一个非常复杂的解决方案才能做到这一点?

I think XML serialization is the way to go, but I'm not quite sure how, or where to start. Or will it require a really complex solution to be able to do this?

推荐答案

以下是绑定对象和某些祖先的示例 到用户界面;这里使用C#3.0纯粹是为了简洁- 一切也可以在C#2.0中使用.

Here's an example that binds an object and some ancestors to the UI; the use of C# 3.0 here is purely for brevity - everything would work with C# 2.0 too.

此处的大多数代码是设置表单,和/或 处理财产变更通知- 重要的是,没有任何代码专门用于更新 来自对象模型的UI或来自对象模型的对象模型 用户界面.

Most of the code here is setting up the form, and/or dealing with property-change notifications - importantly, there isn't any code devoted to updating the UI from the object model, or the object model from the UI.

请注意,IDE可以执行很多数据绑定代码 为您服务,只需将BindingSource放到 表单,并通过以下方式将DataSource设置为类型 在属性网格中的对话框.

Note also the IDE can do a lot of the data-binding code for you, simply by dropping a BindingSource onto the form and setting the DataSource to a type via the dialog in the property grid.

请注意,提供属性更改不是必需的 通知(PropertyChanged的东西)-但是, 大多数2向UI绑定将工作得更好 如果您确实实现了这一点.并不是说PostSharp有一些 最少的代码就能做到这一点的有趣方法.

Note that it isn't essential to provide property change notifications (the PropertyChanged stuff) - however, most 2-way UI binding will work considerably better if you do implement this. Not that PostSharp has some interesting ways of doing this with minimal code.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Windows.Forms;
using System.Xml.Serialization;
static class Program { // formatted for vertical space
    [STAThread]
    static void Main() {
        Application.EnableVisualStyles();

        Button load, save, newCust;
        BindingSource source = new BindingSource { DataSource = typeof(Customer) };
        XmlSerializer serializer = new XmlSerializer(typeof(Customer));
        using (Form form = new Form {
            DataBindings = {{"Text", source, "Name"}}, // show customer name as form title
            Controls = {
                new DataGridView { Dock = DockStyle.Fill, // grid of orders
                    DataSource = source, DataMember = "Orders"},
                new TextBox { Dock = DockStyle.Top, ReadOnly = true, // readonly order ref
                    DataBindings = {{"Text", source, "Orders.OrderRef"}}},
                new TextBox { Dock = DockStyle.Top, // editable customer name
                    DataBindings = {{"Text", source, "Name"}}},
                (save = new Button { Dock = DockStyle.Bottom, Text = "save" }),
                (load = new Button{ Dock = DockStyle.Bottom, Text = "load"}),
                (newCust = new Button{ Dock = DockStyle.Bottom, Text = "new"}),   
            }
        })
        {
            const string PATH = "customer.xml";
            form.Load += delegate {
                newCust.PerformClick(); // create new cust when loading form
                load.Enabled = File.Exists(PATH);
            };
            save.Click += delegate {
                using (var stream = File.Create(PATH)) {
                    serializer.Serialize(stream, source.DataSource);
                }
                load.Enabled = true;
            };
            load.Click += delegate {
                using (var stream = File.OpenRead(PATH)) {
                    source.DataSource = serializer.Deserialize(stream);
                }
            };
            newCust.Click += delegate {
                source.DataSource = new Customer();
            };
            Application.Run(form);
        } 
    }
}

[Serializable]
public sealed class Customer : NotifyBase {
    private int customerId;
    [DisplayName("Customer Number")]
    public int CustomerId {
        get { return customerId; }
        set { SetField(ref customerId, value, "CustomerId"); }
    }

    private string name;
    public string Name {
        get { return name; }
        set { SetField(ref name, value, "Name"); }
    }

    public List<Order> Orders { get; set; } // XmlSerializer demands setter

    public Customer() {
        Orders = new List<Order>();
    }
}

[Serializable]
public sealed class Order : NotifyBase {
    private int orderId;
    [DisplayName("Order Number")]
    public int OrderId  {
        get { return orderId; }
        set { SetField(ref orderId, value, "OrderId"); }
    }

    private string orderRef;
    [DisplayName("Reference")]
    public string OrderRef {
        get { return orderRef; }
        set { SetField(ref orderRef, value, "OrderRef"); }
    }

    private decimal orderValue, carriageValue;

    [DisplayName("Order Value")]
    public decimal OrderValue {
        get { return orderValue; }
        set {
            if (SetField(ref orderValue, value, "OrderValue")) {
                OnPropertyChanged("TotalValue");
            }
        }
    }

    [DisplayName("Carriage Value")]
    public decimal CarriageValue {
        get { return carriageValue; }
        set {
            if (SetField(ref carriageValue, value, "CarriageValue")) {
                OnPropertyChanged("TotalValue");
            }
        }
    }

    [DisplayName("Total Value")]
    public decimal TotalValue { get { return OrderValue + CarriageValue; } }
}

[Serializable]
public class NotifyBase { // purely for convenience
    [field: NonSerialized]
    public event PropertyChangedEventHandler PropertyChanged;

    protected bool SetField<T>(ref T field, T value, string propertyName) {
        if (!EqualityComparer<T>.Default.Equals(field, value)) {
            field = value;
            OnPropertyChanged(propertyName);
            return true;
        }
        return false;
    }
    protected virtual void OnPropertyChanged(string propertyName) {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
    }
}

这篇关于实施保存/加载功能的方式是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆