Что состоит в том, чтобы реализовать путь, Сохраняют / функциональность Загрузки?

Использование eval - самый простой способ сделать это, прочитайте текстовый файл в строку и сделайте следующее:

obj = eval(datastring.replace(", tzinfo=tzlocal()", "")

Поскольку часть datetime не является допустимым кодом Python из-за части tzinfo будучи неопределенным, вы можете просто заменить его ничем, чтобы избежать разбора этого бита. Это исправление будет работать только в том случае, если все данные отформатированы одинаково.

Тем не менее, кажется, что легче и чище пытаться получить входные данные в более дружественном формате. Либо как чистый объект Python, либо как JSON.

5
задан Ryan Gates 31 January 2014 в 21:48
поделиться

6 ответов

Вот пример, который связывает объект и некоторых предков к UI; использование C# 3.0 здесь просто для краткости - все работало бы с C# 2.0 также.

Большая часть кода здесь настраивает форму и/или имеет дело с уведомлениями изменения свойства - значительно, нет никакого кода, посвященного обновлению UI от объектной модели или объектной модели от UI.

Обратите внимание, что также IDE может сделать много кода привязки данных для Вас, просто путем отбрасывания BindingSource на форму и установки DataSource на тип через диалоговое окно в сетке свойства.

Обратите внимание, что не важно предоставить уведомления об изменении свойства (материал PropertyChanged) - однако, привязка UI наиболее с 2 путями будет работать значительно лучше при реализации этого. Не то, чтобы PostSharp имеет некоторые интересные способы сделать это с минимальным кодом.

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));
    }
}
6
ответ дан 18 December 2019 в 13:20
поделиться

Идеально, Вы не должны сохранять состояние UI; необходимо сохранять состояние некоторой объектной модели, представляющей данные. За исключением TreeView, это довольно тривиально для использования привязки данных для связи объектной модели с UI. Это могло быть любой a DataTable- основанный подход или пользовательская иерархия классов (мое предпочтение).

После того как Вы разделили данные из UI, сохранение данных просто. Существует много примеров для XmlSerializer и т.д.

6
ответ дан 18 December 2019 в 13:20
поделиться

Вот большая статья о том, как сделать Ваш классом или структурой сериализуемый. Я создал бы класс, который позволит Вам хранить все данные, которых Вы желаете. Сделайте класс serialable. Этот путь во всего нескольких строках кода можно сохранить все данные в файл. Затем еще с всего несколькими строками кода можно получить данные из файла.

http://www.codeproject.com/KB/cs/objserial.aspx

0
ответ дан 18 December 2019 в 13:20
поделиться

Альтернатива сериализации Ваших классов должна использовать Набор данных ADO.NET для хранения данных, которое создало в средствах для сохранения к XML-файлу. Код будет минимален, и можно хранить только соответствующие данные, в которых Вы нуждаетесь путем разработки таблиц, которые соответствуют модели операции, которую Вы выполняете. Кроме того, Вы сможете использовать тот же код, если Вы решите позже сохранить состояние UI к базе данных вместо локального файла. У Вас должна была бы только быть альтернативная функция для сохранения Набора данных.

0
ответ дан 18 December 2019 в 13:20
поделиться

Да, необходимо определенно использовать сериализацию XML для этого. Но поскольку Marc Gravell отметил, у Вас должны быть объекты, которые содержат данные, отображенные Вашими компонентами графического интерфейса пользователя сначала. Затем можно практически сделать (de) сериализацию автоматической с минимальными строками кода.

1
ответ дан 18 December 2019 в 13:20
поделиться

это довольно тривиально для использования привязки данных для связи объектной модели с UI.

Как я могу связать объект управлением GUI без персистентного устройства хранения данных? Если я делаю это вручную, который означает, что я должен записать смешной объем кода для каждого объекта в памяти. У меня уже есть своего рода устройство хранения данных класса для этих данных, но это не, связывают сценарий вида, это - как чтение эта запись здесь.

Я, как предполагается, пишу загрузчик, который загружает сериализированный XML, и получите объект и затем считайте объект и заполните целый GUI? Очевидно, это больше как загрузка руководства, не связывающая. Я пропускаю что-то?

0
ответ дан 18 December 2019 в 13:20
поделиться
Другие вопросы по тегам:

Похожие вопросы: