редактирование объектов и флаг isDirty()

Я работаю над системой, когда пользователь может редактировать существующие объекты (точнее," фильтровать " объекты домена) через GUI. В качестве подсказки пользовательского интерфейса мы хотим включить кнопку сохранения, только если пользователь действительно изменил что-то в объекте. Мне было интересно, есть ли у кого-нибудь опыт работы с этой проблемой и как лучше всего подойти к этому.

Я думал о добавлении флага isDirty () к объекту домена. Когда пользователь начинает редактировать фильтр, я бы сделал копию, передал это к GUI и пусть пользователь вносит изменения в копию. Привязка к флагу isDirty () затем включит/отключит кнопку Сохранить. При сохранении различия затем объединяются в исходный объект и сохраняются.

кроме того, я думал, что произойдет, если пользователь отменит изменения, которые он внес в объект. Затем флаг isDirty () должен возвращать false. Поэтому я думаю, что единственный способ достичь этого-сохранить исходное значение каждого свойства внутри домена объект.

какие идеи?

7 ответов


правильно!

кроме того, вы можете выставить два метода: BeginEdit-в этом методе ваш флаг IsDirty помечается как True. Это означает, что вы делаете модификацию. Вызовите этот метод, когда вы собираетесь внести изменения

CancelEdit-в этом методе сбросьте флаг IsDirty на False. Значит, у вас есть arborted процесс редактирования и возвращается в исходное состояние. Вызовите этот метод при отмене любых внесенных изменений.

и один раз любой изменения сохраняются, вы также сбрасываете флаг IsDirty в False.

надеюсь, это поможет.


Если вы используете .NET framework, вы можете взглянуть на CSLA .NET framework от Rockford Lhotka:http://www.lhotka.net/cslanet/Default.aspx

CSLA-это зрелый фреймворк, который включает в себя управление состоянием объекта (IsDirty), функциональность отмены, привязку данных и многое другое, а также бесплатный и с открытым исходным кодом.


есть несколько интерфейсов, которые вы можете реализовать, чтобы помочь с отслеживанием изменений и отменить: INotifyPropertyChanged и IEditableObject. Оба этих интерфейса позволяют объекту хорошо играть с привязкой данных.

public class Person : INotifyPropertyChanged, IEditableObject
{
    private bool isDirty;

    public bool IsDirty
    {
        get { return isDirty; }
    }

    private string firstname = string.Empty;

    public string Firstname
    {
        get { return firstname; }
        set
        {
            if (firstname == value) return;
            firstname = value;
            NotifyPropertyChanged("Firstname");
        }
    }

    private string lastname = string.Empty;

    public string Lastname
    {
        get { return lastname; }
        set
        {
            if (lastname == value) return;
            lastname = value;
            NotifyPropertyChanged("Lastname");
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    public void NotifyPropertyChanged(string propertyName)
    {
        isDirty = true;

        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }

    private bool inTrans;
    private Person copy;

    public void BeginEdit()
    {
        if (!inTrans)
        {
            if (copy == null)
                copy = new Person();

            copy.isDirty = isDirty;
            copy.Firstname = Firstname;
            copy.Lastname = Lastname;


            inTrans = true;
            isDirty = false;
        }
    }

    public void CancelEdit()
    {
        if (inTrans)
        {
            isDirty = copy.isDirty;
            Firstname = copy.Firstname;
            Lastname = copy.Lastname;

            inTrans = false;
        }
    }

    public void EndEdit()
    {
        if (inTrans)
        {
            copy = null;
            inTrans = false;
        }
    }
}

Если у вас есть набор объектов, которые редактируются, вам, вероятно, понадобится что-то большее, чем логический флаг для isDirty(). Эта проблема не отличается от подсчета ссылок, т. е. увеличивает грязный счет при редактировании и уменьшает при отмене. Если вы поддерживаете undo, я подозреваю, что вы закончите с довольно волосатой логикой. Я бы держал его подальше от ваших объектов домена.


Да, это хорошо работает. Вместо отмены я использую метод IsDirty для обозначения того, что что-то могло изменить запись, а затем это вызывает мою "логику изменения записи". Я разработал свою собственную структуру, где каждое поле таблицы фактически является свойством объекта. Каждый раз, когда поле записывается в объекты, устанавливается флаг "isDirty". В методе "SaveObject" объекта (на самом деле его вспомогательный класс, но может быть легко в объекте, но я хотел, чтобы возможность сохранения объектов в различные манеры, как xml, база данных, ect.), Я проверяю IsDirty, и если его false, то я пропускаю сохранение. Это упрощает логику, поскольку каждый раз, когда у меня была возможность изменить объект, я вызываю SaveObject и позволяю фреймворку обрабатывать его.


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

преимущество этого предложения заключается в том, что он не придерживается определенных функций GUI (флаг isDirty ()) на ваших объектах домена, но YMMV


Если вы поддерживаете операцию отмены на уровне детализации больше, чем "отменить все с момента последнего сохранения", я бы предложил стек отмены. Когда что-то редактируется, оно (или это функтор операции отмены или делегат) добавляется в стек. Когда вы отменяете, вы просто поп стек и отменить операцию выскочил. Ваш флаг isDirty () - это просто проверка, содержит ли стек отмены элементы, а не дополнительное хранилище и логику для обновления.