Простое место для записи изменений в связанный XML в WPF - PullRequest
0 голосов
/ 10 мая 2011

У меня есть структура XML, связанная с формой WPF, и она настроена для фиксации изменений в базе данных нажатием кнопки.

Я ищу способ определить, что пользователь что-то изменил в модели, чтобы узнать, как включить кнопку «сохранить», установить форму как «грязную» и т. Д. Я бы предпочел что-то на стороне данных, поскольку представление XAML является чисто связанным и в значительной степени свободным от логики, и в результате ViewModel является довольно несущественным, поэтому я хочу указать, что модель находится в состоянии, которое требует фиксации в базе данных.

Один «хак», который я рассмотрел, - это время загрузки, захват XML, а затем простое сравнение с копией DataContext, чтобы определить, не является ли форма грязной.

Ответы [ 2 ]

1 голос
/ 10 мая 2011

Создайте модель представления следующим образом:

public class XmlDataViewModel : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    private void OnPropertyChanged(string propertyName)
    {
        PropertyChangedEventHandler h = PropertyChanged;
        if (h != null)
        {
            h(this, new PropertyChangedEventArgs(propertyName));
        }
    }

    private XmlDocument _XmlData;
    public XmlDocument XmlData
    {
        get { return _XmlData; }
        set
        {
            if (value != _XmlData)
            {
               if (_XmlData != null)
               {
                  // it's not likely you'll need this, but why take chances?
                  _XmlData.NodeChanged -= XmlData_NodeChanged;
               }
               _XmlData = value;
               _XmlData.NodeChanged += XmlData_NodeChanged;
               CanSave = false;
               Provider = new XmlDataProvider { Document = XmlData };
               OnPropertyChanged("Provider");
            }
        }
    }

    private void XmlData_NodeChanged(object sender, XmlNodeChangedEventArgs e)
    {
        CanSave = true;
    }

    public XmlDataProvider Provider { get; private set; }

    public RelayCommand SaveCommand
    {
        get
        {
            return new RelayCommand(x => Save(), x => CanSave);
        }
    }

    private bool CanSave { get; set; }

    private void Save() { }
}

Установите DataContext вашего представления для экземпляра этого объекта и привяжите элементы управления следующим образом:

<StackPanel DataContext="{Binding Provider}">
   <TextBox Text="{Binding XPath=/Data/Field1}"/>
   <TextBox Text="{Binding XPath=/Data/Field2}"/>
</StackPanel>

BindВаша кнопка (или любая другая) имеет значение SaveCommand.

Когда вы установите для свойства XmlData значение XmlDocument (которое вы можете сделать до или после привязки к XmlDataViewModel), оно будетсоздайте новый XmlDataProvider и поднимите PropertyChanged, чтобы все элементы управления представлением обновились, а данные были вытеснены, как вы ожидаете.Изменения в связанных элементах управления вызовут NodeChanged, который устанавливает CanSave, что позволяет SaveCommand.

Если впоследствии вы установите XmlData на другое XmlDocument, связанные элементы управления обновятся и SaveCommand будут отключены до тех пор, пока пользователь не изменит данные в новом XmlDocument.И предыдущее XmlDocument событие NodeChanged будет незарегистрировано, так что объект можно будет удалить.

Должен сказать, что это довольно сложное поведение для того, что на самом деле очень мало кода.Спасибо, что задали этот вопрос.

1 голос
/ 10 мая 2011

Если XML содержится в XDocument, вы можете использовать событие Changed.

В классе XmlDocument есть пара событий , для которых вы можете зарегистрироваться.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...