Show / Hide Table of Contents

    Model

    Model classes are non-visual classes that encapsulate the app's data. Therefore, the model can be thought of as representing the app's domain model, which usually includes a data model along with business and validation logic. Examples of model objects include data transfer objects (DTOs), Plain Old CLR Objects (POCOs), and generated entity and proxy objects. Model classes are typically used in conjunction with application services or repositories that encapsulate data access and caching.

    Data Object

    Data object is the object wrapper that contains simple mechanisms for object extensions with the aggregations. For example:

    var data = new DataObject<Account>(account);
    
    data["ArrangementProfile"] = arrangementProfile;
    

    It also allows the object value formatting,

    data["NumberOfUnclearedChecks"] = arrangementProfile?.UnclearedChecks.GetValueOrDefault() ?? 0;
    

    while the binding is done through view:

    <Label Text="{TemplateBinding  Path=BindingContext.Data[NumberOfUnclearedChecks].Value}" Style="{StaticResource ValueLabel}" /> 
    

    Read-only functionality view is expanded so that object can be connected to the list:

                <ListView x:Name="propertyList" ItemsSource="{Binding Data.DisplayCollection}" SelectionMode="None"
                        ItemTemplate="{StaticResource DataObjectItemTemplate}" VerticalOptions="FillAndExpand" SeparatorVisibility="None"
                        HorizontalOptions="EndAndExpand" HasUnevenRows="True" CachingStrategy="RecycleElementAndDataTemplate">
                </ListView>
    

    This collection is created based on the following configuration:

         detailsDisplaySettings = new DisplaySettings<Transaction>();
    
                //Osnovno podesavanje prikazi polje kako I jeste
                detailsDisplaySettings.AddOrUpdate("TransactionId");
    
                //Dodatno podesavanje sa DisplayPattern-om koji kaze prikazi polje u vise redova
                detailsDisplaySettings.AddOrUpdate(new DisplayParametar<Transaction>() { PropertyName = "Description", DisplayPattern = "Multiline" });
    
                //Dodatno podesavanje sa DisplayPattern-om koji kaze prevedi vrednost iz polja pogodno za enumeracije itd.
                detailsDisplaySettings.AddOrUpdate(new DisplayParametar<Transaction>() { PropertyName = "Status", DisplayPattern = "TranslateValue" });
    
                //Dodatno podesavanje da se postavi konverter na vrednost
                detailsDisplaySettings.AddOrUpdate(new DisplayParametar<Transaction>() { PropertyName = "BookDate", ValueConverter = new DateToStringConverter() });
    
                //Dodatno podesavanje da se vrednost formatira pre prikaza sto ubrzava samo renderovanje, plus prikazi se u desno
                detailsDisplaySettings.AddOrUpdate(new DisplayParametar<Transaction>() { PropertyName = "Amount", DisplayPattern = "Amount", ConvertTo = (x) => { return x.Amount.FormatCurrencyAmount(x.Currency); } });
    
                //Dodatno podesavanje da se doda kljuc za vrednsot labele 
                detailsDisplaySettings.AddOrUpdate(new DisplayParametar<Transaction>() { PropertyName = "CreditorName", CaptionTranslationKey= "accountdata_creditorname" });
    

    And of course, it is allowed to have more than one of them, for example, different transaction types have different configurations.

        public class TransactionCardDisplaySettings : TransactionDisplaySettings, ITransactionDisplaySettings
        {
            public TransactionCardDisplaySettings()
                : base("Card")
            {
                detailsDisplaySettings.AddOrUpdate(new DisplayParametar<Transaction>() { PropertyName = "FeeAmount", DisplayPattern = "Amount" });
            }
        }
    
        public class TransactionTransferDisplaySettings : TransactionDisplaySettings, ITransactionDisplaySettings
        {
            public TransactionTransferDisplaySettings()
                 : base("Transfer")
            {
                detailsDisplaySettings.AddOrUpdate(new DisplayParametar<Transaction>() { PropertyName = "CreditorName", CaptionTranslationKey= "accountdata_creditorname" });
                detailsDisplaySettings.AddOrUpdate(new DisplayParametar<Transaction>() { PropertyName = "CreditorAccount", CaptionTranslationKey = "accountdata_creditoraccount"  });
                detailsDisplaySettings.AddOrUpdate(new DisplayParametar<Transaction>() { PropertyName = "CreditorReference", CaptionTranslationKey = "accountdata_creditorreference" });
    
                detailsDisplaySettings.AddOrUpdate(new DisplayParametar<Transaction>() { PropertyName = "DebtorName", CaptionTranslationKey = "accountdata_debtorname" });
                detailsDisplaySettings.AddOrUpdate(new DisplayParametar<Transaction>() { PropertyName = "DebtorAccount", CaptionTranslationKey = "accountdata_debtoraccount" });
                detailsDisplaySettings.AddOrUpdate(new DisplayParametar<Transaction>() { PropertyName = "DebtorReference", CaptionTranslationKey = "accountdata_debtorreference" });
    
                detailsDisplaySettings.AddOrUpdate(new DisplayParametar<Transaction>() { PropertyName = "Amount", DisplayPattern = "Amount", ConvertTo = (x) => { return x.Amount.FormatCurrencyAmount(x.Currency); } });
                detailsDisplaySettings.AddOrUpdate(new DisplayParametar<Transaction>() { PropertyName = "Purpose", CaptionTranslationKey = "accountdata_purpose" }); 
            }
    
            protected override void AddOnBeging()
            {
                base.AddOnBeging();
    
                detailsDisplaySettings.Remove("Amount");
            }
        }
    
        public class TransactionExchangeDisplaySettings : TransactionDisplaySettings, ITransactionDisplaySettings
        {
            public TransactionExchangeDisplaySettings()
                : base("Exchange")
            {
                detailsDisplaySettings.AddOrUpdate(new DisplayParametar<Transaction>() { PropertyName = "StatusDate", DisplayPattern="Date" });
    
                isAddedEnd = true;
            }
        }
    

    They are registered as in example provided below:

                    new AppServiceInfo<Usecases.Transactions.TransactionCardDisplaySettings, ITransactionDisplaySettings>(){ IsSingleInstance = true},
                    new AppServiceInfo<Usecases.Transactions.TransactionExchangeDisplaySettings, ITransactionDisplaySettings>(){ IsSingleInstance = true},
                    new AppServiceInfo<Usecases.Transactions.TransactionTransferDisplaySettings, ITransactionDisplaySettings>(){ IsSingleInstance = true}
    

    The interface looks like this:

        public interface IDisplaySettingsProvider<TSource> : IApplicationService
        {
            DisplaySettings<TSource> GetSettings();
        }
    
        public interface ITransactionDisplaySettings : IDisplaySettingsProvider<Transaction>
        {
            string Name { get; }
        }
    

    And then it is chosen and applied base on the name:

                var implemntaion = settings?.Where(t => t.Name == type).FirstOrDefault();
    
                var detailsDisplaySettings = implemntaion?.GetSettings() ?? new TransactionDisplaySettings("Default").GetSettings();
    

    This is how it is called from ViewModel:

            protected virtual async Task TappedOnListItem(Xamarin.Forms.ItemTappedEventArgs arg)
            {
                Data = arg.Item as DataObject<Transaction>;
    
                Data.DisplaySettings = TransactionDetailsDisplaySettingsProvider.GetByType(Data.GetPropertyValue<string>("TransactionType"));
    
                Data.BuildDisplayCollection();
    
                await App.Navigation.NavigateToAsync(this, "TransactionDetailsPage");
            }
    

    As a result, the implementation can be changed and upgraded independently.

    The design is regulated through themes and views that also can be changed and improved:

        <ControlTemplate x:Key="AmountDataObjectItemDisplay">
            <StackLayout Padding="20">
                <Label Text="{TemplateBinding  Path=BindingContext.Caption, Converter={StaticResource BindingValueTranslateConverter}}" Style="{StaticResource TitleLabel}" />
                <Label Text="{TemplateBinding  Path=BindingContext.StringValue}" Style="{StaticResource ValueRightLabel}" />
                <BoxView Style="{StaticResource DisplayValueBox}" />
            </StackLayout>
        </ControlTemplate>
    
        <ControlTemplate x:Key="TranslateValueDataObjectItemDisplay">
            <StackLayout Padding="20">
                <Label Text="{TemplateBinding  Path=BindingContext.Caption, Converter={StaticResource BindingValueTranslateConverter}}" Style="{StaticResource TitleLabel}" />
                <Label Text="{TemplateBinding  Path=BindingContext.StringValue, Converter={StaticResource BindingValueTranslateConverter}}" Style="{StaticResource ValueLabel}" />
                <BoxView Style="{StaticResource DisplayValueBox}" />
            </StackLayout>
        </ControlTemplate>
    
        <ControlTemplate x:Key="DateDataObjectItemDisplay">
            <StackLayout Padding="20">
                <Label Text="{TemplateBinding  Path=BindingContext.Caption, Converter={StaticResource BindingValueTranslateConverter}}" Style="{StaticResource TitleLabel}" />
                <Label Text="{TemplateBinding  Path=BindingContext.Value, Converter={StaticResource DateToStringConverter}, ConverterParameter='{0:d}'}" Style="{StaticResource ValueLabel}" />
                <BoxView Style="{StaticResource DisplayValueBox}" />
            </StackLayout>
        </ControlTemplate>
    
        <ControlTemplate x:Key="MultilineDataObjectItemDisplay">
            <StackLayout Padding="20">
                <Label Text="{TemplateBinding  Path=BindingContext.Caption, Converter={StaticResource BindingValueTranslateConverter}}" Style="{StaticResource TitleLabel}" />
                <Label Text="{TemplateBinding  Path=BindingContext.StringValue}"  Style="{StaticResource ValueLabel}"
                       LineBreakMode="WordWrap" LineHeight="1.8" VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand" />
                <BoxView Style="{StaticResource DisplayValueBox}" />
            </StackLayout>
        </ControlTemplate>
    
        <ControlTemplate x:Key="DefaultDataObjectItemDisplay">
            <StackLayout Padding="20">
                <Label Text="{TemplateBinding  Path=BindingContext.Caption, Converter={StaticResource BindingValueTranslateConverter}}" Style="{StaticResource TitleLabel}" />
                <Label Text="{TemplateBinding  Path=BindingContext.StringValue}" Style="{StaticResource ValueLabel}" />
                <BoxView Style="{StaticResource DisplayValueBox}" />
            </StackLayout>
        </ControlTemplate>
    
        <DataTemplate x:Key="DataObjectItemTemplate">
            <ViewCell>
                <ViewCell.View>
                    <ContentView MinimumHeightRequest="200" VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand">
                        <ContentView.Triggers>
                            <DataTrigger TargetType="ContentView" Binding="{Binding Path=DisplayPattern}" Value="Amount">
                                <Setter Property="ControlTemplate" Value="{StaticResource AmountDataObjectItemDisplay}" />
                            </DataTrigger>
                            <DataTrigger TargetType="ContentView" Binding="{Binding Path=DisplayPattern}" Value="Multiline">
                                <Setter Property="ControlTemplate" Value="{StaticResource MultilineDataObjectItemDisplay}" />
                            </DataTrigger>
                            <DataTrigger TargetType="ContentView" Binding="{Binding Path=DisplayPattern}" Value="Date">
                                <Setter Property="ControlTemplate" Value="{StaticResource DateDataObjectItemDisplay}" />
                            </DataTrigger>
                            <DataTrigger TargetType="ContentView" Binding="{Binding Path=DisplayPattern}" Value="TranslateValue">
                                <Setter Property="ControlTemplate" Value="{StaticResource TranslateValueDataObjectItemDisplay}" />
                            </DataTrigger>                        
                            <DataTrigger TargetType="ContentView" Binding="{Binding Path=DisplayPattern}" Value="">
                                <Setter Property="ControlTemplate" Value="{StaticResource DefaultDataObjectItemDisplay}" />
                            </DataTrigger>
                        </ContentView.Triggers>
                    </ContentView>
                </ViewCell.View>
            </ViewCell>
        </DataTemplate>
    
    Back to top Copyright 2020 Asseco SEE