2017-12-18 282 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