Xamarin Binding Context with class properties

Hikari

I have a Page that have BindingContext like a class.

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

BindingContext="{Binding .}" is the BindingContext.

In the XAML page I use this in this way:

<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>

Inside the ViewModel I have a function that is trigger where this Entry changed it's value and check the value, but the value is always the first value setted.

 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;
    }
}

What I'm doing wrong? Why when the value of the input change, the respective property in my class isn't updated?

Thank you!

EDIT - There are my code classes:

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;
        }
    }

}
Csharpest

Your class WoSpesaDett does inherit from INPC. But that doesn't update the View when a property inside the class changes. Your properties in WoSpesaDett must call the INotifyPropertyChanged event.

So something like this:

public class WoSpesaDett : INotifyPropertyChanged
{

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

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

Xamarin Forms Binding Context

Properties of Class Properties of Model not binding

xamarin binding class property

Xamarin Forms Binding to Object Properties

Binding to Attached Properties in Xamarin Forms

Binding class properties to UserControl in MVVM

Xamarin forms understanding ObservableCollection binding context

Binding BackgroundColor properties ContentPage in Xamarin Forms

Binding properties to a ListView in Xamarin, does not update the View

How to set Binding Context of ListView button to the binding context of parent in Xamarin Forms

Binding boolean properties of a Set of a certain class to checkboxes

WPF DataGrid, How to binding class properties as row?

Xamarin Android Java Binding: Missing class (XMLReader)

Xaml Binding To Custom Class in Xamarin Forms

How to access class properties from child context

Set controls DataContext while binding other properties to parent context

Binding Context inside Data Template view cell in Xamarin Forms

Xamarin Multiple Binding Context on same View with different ViewModels

Xamarin.Forms: Access layout individually when it has a binding context

Looking for right way to implement multiple properties dependency for binding in Xamarin View

Xamarin Forms Binding two properties from a single control to different contexts

How to bind class properties in XAML of xamarin forms

How to share step binding class in SpecFlow with context injection

Replace ScenarioContext.Current in non binding class using context injection

{Binding .} in Xamarin

Access Properties from a class into another class in Xamarin Forms

react component method binding with arrow function (class properties)

Referencing properties of Observable class in Android Data Binding layout

Third party library is binding callbacks, but I need to access class properties