2015-08-30 47 views
3

我使用WPF MVVM,Caliburn Micro和WCF服務來構建我的第一個生產應用程序。如何檢測viewmodel模型中屬性的更改?

我已經到了一個地步,我需要我的ViewModel來跟蹤模型中各個屬性的變化。我給你一個例子。我的VM具有的屬性是這樣的:

public OrdenesTransporteWCFModel OrdenTransporte { get; set; } 
public List<EnumeradorWCFModel> TiposCarga { get; set; } 
public List<EnumeradorWCFModel> TiposCamion { get; set; } 
public List<EnumeradorWCFModel> MediosContacto { get; set; } 

OrdenesTransporteWCFModel是來自於WCF服務模式,我的觀點可能看起來是這樣的:

<ComboBox ItemsSource="{Binding Path=TiposCarga}" SelectedValuePath="ID" DisplayMemberPath="Descripcion" SelectedValue="{Binding Path=OrdenTransporte.ID_TipoCarga}"></ComboBox> 

<ComboBox ItemsSource="{Binding Path=TiposCamion}" SelectedValuePath="ID" DisplayMemberPath="Descripcion" SelectedValue="{Binding Path=OrdenTransporte.ID_TipoMovil}"></ComboBox> 

<ComboBox ItemsSource="{Binding Path=MediosContacto}" SelectedValuePath="ID" DisplayMemberPath="Descripcion" SelectedValue="{Binding Path=OrdenTransporte.ID_MedioContacto,ValidatesOnDataErrors=True}"></ComboBox> 

<TextBox IsEnabled="False" Text="{Binding Path=OrdenTransporte.Numero}"></TextBox> 

<DatePicker SelectedDate="{Binding Path=OrdenTransporte.FechaConfeccion}"></DatePicker> 

正如你看到的,我結合我的控制到我的模型中的單個屬性(OrdenTransporte)。

現在我需要的是我的VM跟蹤這個性質的改變:比如我在VM財產HasChange一個布爾值,我需要的,如果任何字段已更改爲被激活。另外,我有一個方法TipoCamionChange,如果ID_TipoCamion屬性更改,我需要觸發。

有沒有什麼辦法可以實現? 謝謝!

編輯

正如馬丁建議,我在我的模型實現INotifyPropertyChange並嘗試我的模型訂閱PropertyChange事件對我的模型是這樣的:

OrdenTransporte = _svc.OrdenesTransporte_GetById(IDOrden);    
OrdenTransporte.PropertyChanged += Model_PropertyChanged; 

private void Model_PropertyChanged(object sender, PropertyChangedEventArgs e) 
    { 
     if (e.PropertyName == "ID_Cliente") 
     { 
      CargarDirecciones(); 
     } 
    } 

的問題是,當我訂閱我的虛擬機模型PropertyChange,模型中的數據已經改變,所以PropertyChanged永遠不會被調用。如果我這樣做:因爲整個對象被替換爲WCF服務返回的一個,incluiding INotifyPropertyChange事件

OrdenTransporte.PropertyChanged += Model_PropertyChanged; 
OrdenTransporte = _svc.OrdenesTransporte_GetById(IDOrden);    

事件無論如何都不會被解僱。有任何想法嗎?

+0

請參閱http://www.codeproject。com/Articles/15822/Bind-Better-with-INotifyPropertyChanged或https://msdn.microsoft.com/en-us/magazine/dd419663.aspx或只搜索'INotifyPropertyChanged' –

+0

感謝@philsoady。我當然知道INotifyPropertyChange。但是爲了做到這一點,我需要重新編寫我的模型,至少我不能這樣做,因爲它們來自WCF服務,或者完全複製我的viewmodel中的模型屬性,這完全不切合實際。我正在尋找更通用的方法。不管怎麼說,還是要謝謝你。 – ericpap

+0

您的視圖模型通常與服務模型或POCO分開。也許您的視圖模型可以包含服務模型或基礎POCO是某種方式。 –

回答

1

模型類是否實現了INotfiyPropertyChanged

然後,你可以在你的視圖模型設置事件處理程序的模型類的變化:

modelObject.PropertyChanged += ViewModelOnPropertyChanged; 

    private void ViewModelOnPropertyChanged(object sender, PropertyChangedEventArgs propertyChangedEventArgs) 
    { 
     // react to object change here 
    } 

您可以鏈接了幾個模型對象均相同的事件處理程序的事件,然後設置你的HasChange例如,查看模型屬性。

如果您的模型對象不執行INotfiyPropertyChanged我不知道解決方案。

+0

謝謝你,但它不起作用。請看我的更新。 – ericpap

1

您可以使用Dynamic Castle(將實例封裝在代理中)或Fody(在編譯時在後續步驟中修改IL)自動將IPNC支持添加到模型屬性。

更新:如果您的模型來自Web服務引用,那麼他們將已經擁有IPCN支持,您可以通過轉到他們在您的項目中自動生成的源代碼來看到這一點。您也可以在代碼中確認它:

using (var client = new ServiceReference1.Service1Client()) 
{ 
    var data = client.GetData(); 

    data.PropertyChanged += (s, e) => 
    { 
     Debug.Assert(false, "PropertyChanged handler invoked."); 
    }; 

    data.SomeMember = false; // <-- will cause the assert to trigger 
} 
+0

什麼是IPNC支持? – ericpap

+0

拼寫錯誤,對不起。我的意思是INPC即INotifyPropertyChanged。 –

+0

謝謝你,但它不起作用。請看我的更新? – ericpap

相關問題