2011-05-10 50 views
0

我有綁定到一個WPF形式的XML結構,並擁有這一切建立在按下按鈕將更改提交到數據庫。簡單的地方捕捉更改綁定的XML在WPF

我找檢測到用戶在模型改變任何東西的方式,要知道,以使「保存」按鈕,設置形式「髒」等,我寧願在數據面上的東西,因爲XAML視圖乾淨地綁定並且基本上沒有邏輯,並且ViewModel作爲一個結果是非常不實際的,所以我想表明模型處於需要對數據庫進行提交的狀態。

一個「黑客」,我認爲是在加載時,捕獲XML,然後做一個簡單的比較到DataContext的副本,以確定表單是否是髒的。

回答

1

像這樣創建一個視圖模型:

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> 

綁定您的按鈕(或任何)至SaveCommand

當你XmlData屬性設置爲XmlDocument(其綁定到XmlDataViewModel之前或之後,你可以做到),它會創建一個新的XmlDataProvider,提高PropertyChanged,所以視圖的控件將全部刷新,數據將按照你的期望推出。對綁定控件的更改將增加NodeChanged,該設置將設置CanSave,這將啓用SaveCommand

如果隨後設置XmlData到不同XmlDocument,綁定控件將刷新和SaveCommand將被禁用,直到用戶在新XmlDocument變化的數據。並且之前的XmlDocumentNodeChanged事件將被取消註冊,以便可以丟棄該對象。

我得說,這對什麼是真正的非常少的代碼相當複雜的行爲。感謝您提出這個問題。

+0

感謝@Robert - 我實現了這一點,它似乎運作良好,雖然東西在我的XAML觀點必須改變我的XML,因爲它吸引,因爲它激發了XMLNodeChanged事件,而它的繪製。 – Runonthespot 2011-05-11 11:15:15

+0

我認爲這是我的問題@Erno的回答。我嘗試了他的方法,獲得了類似的結果。 – Runonthespot 2011-05-11 11:16:23

+0

兩次修改上面的代碼,我不得不添加OnPropertyChanged(「CanSave」);到XmlData_NodeChanged事件處理程序,以便通知用戶界面CanSave已更改並知道要更新,當然,我必須跟蹤RelayCommand的實現(很簡單,但[在此](http://msdn.microsoft.com/zh-cn/ .com/en-us/magazine/dd419663.aspx)如果有人需要, – Runonthespot 2011-05-11 13:57:40

1

如果XML被包含在一個XDocument可以使用the Changed event.

XmlDocument類具有a couple of events,你可以對註冊。

+0

看起來就像那種東西。我附加該事件時的任何想法,因爲目前似乎找不到在綁定後添加它的方式,例如,事件在表單初始加載時會多次觸發。我試過.Loaded(這是一個WPF樹視圖),但沒有奏效。 – Runonthespot 2011-05-10 16:00:53

+0

通過創建特定的調用來加載XDocument,然後添加事件處理程序,而不是從開始/構造函數加載xml權限。或者我錯過了什麼? – 2011-05-10 19:59:36

+0

不@Erno - 我覺得我是缺少一些東西的人。在我看來,在完成繪圖之前發射了一個XMLNodeChanged事件。無法解決如何/爲什麼,但必須是有約束力的事情。 – Runonthespot 2011-05-11 11:17:21