2017-12-18 280 views
0

我有一个类似BindingContext的页面,类似于类。具有类属性的Xamarin绑定上下文

private WorkOrderDettaglioSpesa _WoSpesaDett = new WorkOrderDettaglioSpesa(); 
public WorkOrderDettaglioSpesa WoSpesaDett { 
    get { return _WoSpesaDett; } 
    set { 
     _WoSpesaDett = value; 
     RaisePropertyChanged(() => WoSpesaDett); 
    } 
} 

BindingContext="{Binding .}"BindingContext

在XAML页面我这样使用:

<Label Text="{core:Translate LbLImporto}" 
     Grid.Row="0" 
     Grid.Column="0" 
     Style="{StaticResource LblDescrizione}" />   
<Entry IsEnabled="{Binding WoSpesaDett.DatiArticoloSelezionato.AbilitaImporto}" 
     Keyboard="Numeric" 
     Text="{Binding WoSpesaDett.Importo, Mode=TwoWay}" 
     Grid.Row="0" 
     Grid.Column="1" > 
</Entry> 

视图模型里面我有一个功能,就是触发哪里此条目改变了它的价值和检查值,但该值永远是第一位设定的价值。

private void ControllaMassimale() 
{ 
    if (!string.IsNullOrWhiteSpace(WoSpesaDett.LimitePerSingolaSpesa)) 
    { 
     RaisePropertyChanged(() => WoSpesaDett); 

     double? Massimale = Convert.ToDouble(WoSpesaDett.LimitePerSingolaSpesa); 
     double? Valore = WoSpesaDett.Importo/WoSpesaDett.Quantita; // <<-- WoSpesaDett.Importo is always 0 (the default value) 

     if (Valore != null && Valore > Massimale) 
     { 
      WoSpesaDett.FuoriMassimale = true; 
      var Params = new { 
       Titolo = "MyTitle", 
       Messaggio = "MyMessaggio", 
      }; 

      MessagingCenter.Send(Me, Costanti.ChiaviMessaggi.MessaggioGenerico.ToString(), Params); 
     } 
     else 
      WoSpesaDett.FuoriMassimale = false; 
    } 
} 

我在做什么错了? 为什么当输入的值发生变化时,我班的各个属性不会更新?

谢谢!

编辑 - 有我的代码类:

WorkOrderDettaglioSpesa

public class WorkOrderDettaglioSpesa : WorkOrderDettaglioListaSpese { 

    public class DatiTipoSpesa { 
     public string UnitaDiMisura { get; set; } = string.Empty; // TBS TRT str1 
     public bool MassimaliSiNo { get; set; } = false; // str2 
     public bool AbilitaQuantita { get; set; } = false; // str3 
     public string PagamentoDiDefault { get; set; } = string.Empty; // str4 
     public bool AbilitaPagamento { get; set; } = true; // str5 
     public bool KmSiNo { get; set; } = false; // str7 
     public string CostoTRX { get; set; } = string.Empty; // str8 
     public bool AbilitaImporto { get; set; } = false;// Mi serve per il template 
     public bool AbilitaTipoSpesa { get; set; } = false;// Mi serve per il template 
    } 

    public string DaFatturare { get; set; } 
    public string DaFatturareDefault { get; set; } // Serve per fare i controlli al cambio del check 
    public string NotaFatturare { get; set; } 
    public string LimitePerSingolaSpesa { get; set; } 

    [IgnoreMapping] 
    public DatiTipoSpesa DatiArticoloSelezionato { get; set; } = new DatiTipoSpesa(); 

    #region Installatore 
    public string Installatore_Cod { get; set; } 
    [IgnoreMapping] 
    public Combo Installatore { 
     get { 
      Combo wRet = new Combo(); 
      if (DsInstallatore != null) wRet = DsInstallatore.Find(ele => ele.Codice == Installatore_Cod); 
      return wRet; 
     } 
     set { if (value != null) Installatore_Cod = value.Codice; } 
    } 
    #endregion 

    #region Tecnico 
    public string Tecnico_Cod { get; set; } 
    [IgnoreMapping] 
    public Combo Tecnico { 
     get { 
      Combo wRet = new Combo(); 
      if (DsTecnico != null) wRet = DsTecnico.Find(ele => ele.Codice == Tecnico_Cod); 
      return wRet; 
     } 
     set { if (value != null) Tecnico_Cod = value.Codice; } 
    } 
    #endregion 

    #region AreaSpesa 
    public string AreaSpesa_Cod { get; set; } 
    [IgnoreMapping] 
    public Combo AreaSpesa { 
     get { 
      Combo wRet = new Combo(); 
      if (DsAreaSpesa != null) wRet = DsAreaSpesa.Find(ele => ele.Codice == AreaSpesa_Cod); 
      return wRet; 
     } 
     set { if (value != null) AreaSpesa_Cod = value.Codice; } 
    } 
    #endregion 

    #region TipoSpesa 
    public string TipoSpesa_Cod { get; set; } 
    [IgnoreMapping] 
    public Combo TipoSpesa { 
     get { 
      Combo wRet = new Combo(); 
      if (DsTipoSpesa != null) wRet = DsTipoSpesa.Find(ele => ele.Codice == TipoSpesa_Cod); 
      return wRet; 
     } 
     set { if (value != null) TipoSpesa_Cod = value.Codice; } 
    } 
    #endregion 

    #region Valuta 
    public string Valuta_Cod { get; set; } 
    [IgnoreMapping] 
    public Combo Valuta { 
     get { 
      Combo wRet = new Combo(); 
      if (DsValuta != null) wRet = DsValuta.Find(ele => ele.Codice == Valuta_Cod); 
      return wRet; 
     } 
     set { if (value != null) Valuta_Cod = value.Codice; } 
    } 
    #endregion 

    #region TipoPagamento 
    public string TipoPagamento_Cod { get; set; } 
    [IgnoreMapping] 
    public Combo TipoPagamento { 
     get { 
      Combo wRet = new Combo(); 
      if (DsTipoPagamento != null) wRet = DsTipoPagamento.Find(ele => ele.Codice == TipoPagamento_Cod); 
      return wRet; 
     } 
     set { if (value != null) TipoPagamento_Cod = value.Codice; } 
    } 
    #endregion 

    #region DataSource Combo 
    [IgnoreMapping] 
    public List<Combo> DsInstallatore { get; set; } 

    [IgnoreMapping] 
    public List<Combo> DsTecnico { get; set; } 

    [IgnoreMapping] 
    public List<Combo> DsAreaSpesa { get; set; } 

    [IgnoreMapping] 
    public List<Combo> DsTipoSpesa { get; set; } 

    [IgnoreMapping] 
    public List<Combo> DsValuta { get; set; } 

    [IgnoreMapping] 
    public List<Combo> DsTipoPagamento { get; set; } 
    #endregion 
} 

WorkOrderDettaglioListaSpese

public class WorkOrderDettaglioListaSpese : BaseModel { 
    public DateTime? DataSpesa { get; set; } 

    public string InstallatoreTecnico { 
     get { 
      return string.Join(" ", _Installatore, _Tecnico); 
     } 
    } 

    public string TipoSpesaDescrizione { get; set; } // codart_descr 
    public string SpesaValore { 
     get { 
      return $"{SpeseViaggioDescrizione} {Quantita}"; 
     } 
    } 

    public string SpesaImporto { 
     get { 

      string wRet = string.Empty; 

      string FuoriMassimaleTemplate = "FUORI-MAX"; 
      string NoCambioTemplate = "NO-CAMBIO"; 

      if (FuoriMassimale) { 
       wRet = $"{Importo?.ToString("F2")} {ValutaDescrizione} {FuoriMassimaleTemplate}"; 
      } else { 
       wRet = $"{Importo?.ToString("F2")} {ValutaDescrizione}"; 
      } 

      if (NoCambio) wRet += $" {NoCambioTemplate}"; 

      return wRet; 
     } 
    } 

    public string SpeseViaggioDescrizione { get; set; } // cod_trt_descr 
    public string ValutaDescrizione { get; set; } // cod_val_descr 

    public double? Quantita { get; set; } = 1; // qta 
    public double? Importo { get; set; } 

    public string _Installatore { get; set; } 
    public string _Tecnico { get; set; } 
    public bool Rimborsata { get; set; } 
    public bool FuoriMassimale { get; set; } 
    public bool NoCambio { get; set; } 
} 

BaseModel

public class BaseModel { 
    internal TranslateExtension ts = new TranslateExtension(); 

    public string Cod_div { get; set; } 
    public string Cod_soc { get; set; } 
    public string Cod_fil { get; set; } 
    public string Guid_servizio { get; set; } 
    public string FlagTratt { get; set; } 

    public bool IsNew { 
     get { 
      return string.IsNullOrWhiteSpace(Guid_servizio); 
     } 
    } 

    internal class FiltroAttribute : Attribute { } 
    internal class IgnoreMappingAttribute : Attribute { } 


    private static IEnumerable<T> ReflectionFilter<T>(IEnumerable<T> collection, string property, object value) { 
     if (collection.Count() == 0) return new List<T>(); 

     PropertyInfo pInfo = collection.First().GetType().GetProperty(property); 

     return collection.Where(c => ((string)pInfo.GetValue(c))?.IndexOf((string)value, StringComparison.InvariantCultureIgnoreCase) > -1).ToList(); 
    } 

    public static List<T> FiltraListaTipizzata<T>(List<T> ListaDaFiltrare, string Filtro) { 
     try { 
      List<T> wRet = new List<T>(); 
      Type Classe = typeof(T); 
      List<PropertyInfo> PropToFilter = Classe.GetProperties().Where(prop => Attribute.IsDefined(prop, typeof(FiltroAttribute))).ToList(); 

      // TODO: Da ottimizzare e cercare di utilizare il PredicateBuilder 
      if (string.IsNullOrWhiteSpace(Filtro)) { 
       wRet = ListaDaFiltrare; 
      } else { 
       foreach (PropertyInfo Prop in PropToFilter) { 
        IEnumerable<T> TmpList = ReflectionFilter(ListaDaFiltrare, Prop.Name, Filtro); 
        wRet = wRet.Union(TmpList).ToList(); 
       } 
      } 

      return wRet; 
     } catch (Exception ex) { 

      throw ex; 
     } 
    } 

} 
+0

如果WoSpesaDett是你的BindingContext,那么你只需要编写'项的IsEnabled = “{结合DatiArticoloSelezionato.AbilitaImporto}”',这同样适用于'文本=“{结合Importo ,Mode = TwoWay}“' – Csharpest

+0

感谢您的回复!对不起,我的BindingContext是:BindingContext =“{Binding。}” – Hikari

回答

1

您的类WoSpesaDett确实继承自INPC。但是,当类内部的property发生更改时,这并不会更新视图。 WoSpesaDett中的属性必须调用INotifyPropertyChanged事件。

因此,像这样:

public class WoSpesaDett : INotifyPropertyChanged 
{ 

    private string importo; 
    public string Importo 
    { 
     get { return fuoriMassimale; } 
     set 
     { 
      fuoriMassimale = value; 
      OnPropertyChanged(); 
     } 
    } 
} 
+0

谢谢。但是我的班级有很多属性,我必须为每个属性做这件事? – Hikari

+0

是的,您必须为每个您希望通过视图更新的属性执行此操作。 – Csharpest

+0

但其他属性正确更改。这可能是因为proopery“importo”是在WoSpesaDett的基类中声明的? WoSpesaDett的类型是由WorkOrderDettaglioListaSpese派生的WorkOrderDettaglioSpesa,而在WorkOrderDettaglioListaSpese类中是“importo”。 – Hikari