2015-08-30 46 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

相关问题