49.02 Xamarin Custom user controls for Dialect View (Xamarin) - chempkovsky/CS2WPF-and-CS2XAMARIN GitHub Wiki

  • Preparation steps to first run Dm04WebApp
    • Set up default constructor of LitDbContext
        public LitDbContext() : base("name=LitConnection") { }
- Set up connection strings in the Web.config
    <add name="DefaultConnection"
    connectionString="Data Source=SVR2016SQL2017;Initial Catalog=AspNetDm04WebAppSecurity;Persist Security Info=True;User ID=sa;Password=YOUR_PASSWORD"
    providerName="System.Data.SqlClient" />
    <add name="LitConnection"
    connectionString="Data Source=SVR2016SQL2017;Initial Catalog=LitStorageDm04WebApp;Persist Security Info=True;User ID=sa;Password=YOUR_PASSWORD"
    providerName="System.Data.SqlClient" />
- Db Migration is not used for this demo app. Instead the following code have been executed in the small console app to create  Data Base on the SQL server. At the moment, tables of countries, languages and dialects must be populated with data. Please add a static class to the console app:
    public static class DbHelpers
    {
        public static void PopulateCounties(this LitDbContext db)
        {
            CultureInfo[] cultureInfos = CultureInfo.GetCultures(CultureTypes.AllCultures & CultureTypes.SpecificCultures);
            foreach (CultureInfo cultureInfo in cultureInfos)
            {
                if (string.IsNullOrEmpty(cultureInfo.Name)) continue;
                RegionInfo regionInfo = new RegionInfo(cultureInfo.Name);
                if (!db.LitCountryDbSet.Any(c => (c.Iso3 == regionInfo.ThreeLetterISORegionName) && (c.Iso2 == regionInfo.TwoLetterISORegionName)))
                {
                    LitCountry сountry = new LitCountry()
                    {
                        Iso3 = regionInfo.ThreeLetterISORegionName,
                        Iso2 = regionInfo.TwoLetterISORegionName,
                        CountryName = regionInfo.EnglishName
                    };
                    db.LitCountryDbSet.Add(сountry);
                    db.SaveChanges();
                    db.Entry(сountry).State = System.Data.Entity.EntityState.Detached;
                }
            }
        }
        public static void PopulateLanguages(this LitDbContext db)
        {
            CultureInfo[] cultureInfos = CultureInfo.GetCultures(CultureTypes.NeutralCultures);
            foreach (CultureInfo cultureInfo in cultureInfos)
            {
                if (string.IsNullOrEmpty(cultureInfo.Name)) continue;
                if (!db.LitLanguageDbSet.Any(l => (l.Iso3 == cultureInfo.ThreeLetterISOLanguageName) && (l.Iso2 == cultureInfo.TwoLetterISOLanguageName)))
                {
                    LitLanguage lang = new LitLanguage()
                    {
                        Iso3 = cultureInfo.ThreeLetterISOLanguageName,
                        Iso2 = cultureInfo.TwoLetterISOLanguageName,
                        LanguageName = cultureInfo.EnglishName
                    };
                    db.LitLanguageDbSet.Add(lang);

                    db.SaveChanges();
                    db.Entry(lang).State = System.Data.Entity.EntityState.Detached;
                }
            }
        }
        public static void PopulateDialects(this LitDbContext db)
        {
            CultureInfo[] cultureInfos = CultureInfo.GetCultures(CultureTypes.AllCultures & CultureTypes.SpecificCultures);
            foreach (CultureInfo cultureInfo in cultureInfos)
            {
                if (string.IsNullOrEmpty(cultureInfo.Name)) continue;
                RegionInfo regionInfo = new RegionInfo(cultureInfo.Name);

                if (!db.LitLanguageDbSet.Any(l => (l.Iso3 == cultureInfo.ThreeLetterISOLanguageName) && (l.Iso2 == cultureInfo.TwoLetterISOLanguageName)))
                {
                    continue;
                }
                if (!db.LitCountryDbSet.Any(c => (c.Iso3 == regionInfo.ThreeLetterISORegionName) && (c.Iso2 == regionInfo.TwoLetterISORegionName)))
                {
                    continue;
                }
                if (db.LitDialectDbSet.Any(d => d.DialectId == cultureInfo.Name))
                {
                    continue;
                }
                if (!db.LitDialectDbSet.Any(d =>
                    (d.Iso3CntrRef == regionInfo.ThreeLetterISORegionName) && (d.Iso2CntrRef == regionInfo.TwoLetterISORegionName) &&
                    (d.Iso3LngRef == cultureInfo.ThreeLetterISOLanguageName) && (d.Iso2LngRef == cultureInfo.TwoLetterISOLanguageName)))
                {
                    LitDialect dialect = new LitDialect()
                    {
                        DialectId = cultureInfo.Name,

                        Iso3CntrRef = regionInfo.ThreeLetterISORegionName,
                        Iso2CntrRef = regionInfo.TwoLetterISORegionName,

                        Iso3LngRef = cultureInfo.ThreeLetterISOLanguageName,
                        Iso2LngRef = cultureInfo.TwoLetterISOLanguageName,

                        DialectName = cultureInfo.EnglishName
                    };
                    db.LitDialectDbSet.Add(dialect);
                    db.SaveChanges();
                    db.Entry(dialect).State = System.Data.Entity.EntityState.Detached;
                }
            }
        }
    }

Having "DbHelpers"-class we add four additional lines of code

        Database.SetInitializer(new DropCreateDatabaseAlways<LitDbContext>());
        LitDbContext db = new LitDbContext();
        db.LitDialectDbSet.FirstOrDefault();
        MessageBox.Show("The database was successfully created.", "Done", 
            MessageBoxButton.OK, MessageBoxImage.Information);
        Database.SetInitializer(new CreateDatabaseIfNotExists<LitDbContext>());
// four lines have been added to the code
        db.PopulateCounties();
        db.PopulateLanguages();
        db.PopulateDialects();
        MessageBox.Show("The data was inserted.", "Done", MessageBoxButton.OK, MessageBoxImage.Information);

  • To Generate C# classes for the Dialect View

    • Run Visual Studio and Open “WpfDemo” solution
    • Under ModelInterfacesClassLibrary-project create folder
      • Literature/LitDialect
    • Right Click the folder
      • Literature/LitDialect
    • And select “Wpf Forms Wizard” menu item to open the Wizard dialog
  • Note:

    • On the first page of the dialog the destination folder is shown. The destination folder is the folder in which the generated file will be saved.

picture

- Click “Next”-button
  • On the second page of the dialog the developer should select existing DbContext file. Select:
    • Dm02Context (project)
    • LitDbContext (context)

picture

- Click “Next”-button
  • On the third page of the dialog the developer should select the View. Select:
    • “LitDialectView“.
  • In the left panel select “UI List Properties” node and check "Shown" for all
  • With "Up" and "Down" buttons change the order of the fields
  • Check "New Line" for "LLanguageName"-property

picture

  • In the left panel of the same page of the dialog select “UI Form Properties” node and check "Shown" for all properties.
  • With "Up" and "Down" buttons change the order of the fields as it is shown on the slide.
  • In the left panel of the same page of the dialog select “UI Form Properties” node and check "New Line" as it is shown on the slide.
  • Set “InputType” as it is shown on the slide.

picture

- Click “Next”-button
  • On the fourth page click “batch processing”-button. “Batch actions” dialog will be shown.
    • Select “01100-Intefaces.json”
    • Click “Start”-button

picture

- Close both dialogs
  • Under ModelServicesPrismModule-project create folder

    • Literature/LitDialect
    • Right Click the folder
      • Literature/LitDialect
    • And select “Wpf Forms Wizard” menu item to open the Wizard dialog
    • Repeat all the steps until the “Batch Actions” dialog box appears.
    • Note:
      • The developer should not define again
        • “UI List Properties”
        • “UI Form Properties”
      • All settings were saved during the first batch.
  • In “Batch actions” dialog

    • Select “01400-ApiService.json”
      • Click “Start”-button
    • Select “01420-SForm.Xamarin.json”
      • Click “Start”-button
    • Select “01500-Eform.Xamarin.json”
      • Click “Start”-button
    • Select “01600-Lform.Xamarin.json”
      • Click “Start”-button
    • Select “01700-O2m.Xamarin.json”
      • Click “Start”-button
    • Select “01701-O2mPage.Xamarin.json”
      • Click “Start”-button
    • Select “01820-Redit.Xamarin.json”
      • Click “Start”-button
    • Select “01821-ReditPage.Xamarin.json”
      • Click “Start”-button
    • Select “01920-Rlist.Xamarin.json”
      • Click “Start”-button
    • Select “01921-RlistPage.Xamarin.json”
      • Click “Start”-button
    • Select “02020-Rdlist.Xamarin.json”
      • Click “Start”-button
    • Select “02021-RdlistPage.Xamarin.json”
      • Click “Start”-button
    • Close both dialogs
  • Note #1:

    • Sform is a search form for the given View
    • Eform is an Edit form for the given View
    • Lform is a wrapper for the two forms above.
  • Note #2:

    • Sform and Eform are the basic forms with all the user interface logic for the given View.
    • Other forms are wrappers for these two:
      • Derived from ContentView (viewmodel derives IRegionAware in terms of Prism). Such a controls are used for navigation inside small child window, i.e. inside separate child windows of so called "Feature"-window:
        • Lform
        • O2m
        • Redit
        • Rlist
        • Rdlist
      • Derived from ContentPage (viewmodel derives INavigationAware in terms of Prism):
        • O2mPage
        • ReditPage
        • RlistPage
        • RdlistPage
  • Under ModelServicesPrismModule-project

    • open the file "Literature/LitDialect/LitDialectViewService.cs" and take a look at the instruction at the beginning of the file. Do not follow the
/*
    In the file of IModule-class of the project for the current service the following lines of code must be inserted:

        public void RegisterTypes(IContainerRegistry containerRegistry)
        {
            ...
            containerRegistry.Register<ILitDialectViewService, LitDialectViewService>();
            ...
        }
*/
  • Under ModelServicesPrismModule-project
    • open the file "Literature/LitDialect/ViewModels/LitDialectViewSformViewModel.cs" and take a look at the instruction at the beginning of the file
    • open the file "Literature/LitDialect/ViewModels/LitDialectViewSdlgViewModel.cs" and take a look at the instruction at the beginning of the file
    • open the file "Literature/LitDialect/ViewModels/LitDialectViewEformViewModel.cs" and take a look at the instruction at the beginning of the file
    • open the file "Literature/LitDialect/ViewModels/LitDialectViewEdlgViewModel.cs" and take a look at the instruction at the beginning of the file
    • open the file "Literature/LitDialect/ViewModels/LitDialectViewLformViewModel.cs" and take a look at the instruction at the beginning of the file
    • open the file "Literature/LitDialect/ViewModels/LitDialectViewLdlgViewModel.cs" and take a look at the instruction at the beginning of the file
    • continue until the end

picture

  • Under ModelServicesPrismModule-project check that the RegisterTypes()-method of the ModelServicesPrismModuleModule.cs becomes as follows
        public void RegisterTypes(IContainerRegistry containerRegistry)
        {
            ...
            containerRegistry.Register<ModelInterfacesClassLibrary.Literature.LitDialect.ILitDialectViewService, ModelServicesPrismModule.Literature.LitDialect.LitDialectViewService>();
            Prism.Mvvm.ViewModelLocationProvider.Register<ModelServicesPrismModule.Literature.LitDialect.UserControls.LitDialectViewSformUserControl, ModelServicesPrismModule.Literature.LitDialect.ViewModels.LitDialectViewSformViewModel>();
            containerRegistry.Register<Xamarin.Forms.ContentView, ModelServicesPrismModule.Literature.LitDialect.UserControls.LitDialectViewSformUserControl>("LitDialectViewSformUserControl");
            containerRegistry.RegisterDialog<ModelServicesPrismModule.Literature.LitDialect.UserControls.LitDialectViewSdlgUserControl, CommonUserControlLibrary.ViewModels.SdlgViewModelBase>("LitDialectViewSdlgViewModel");
            Prism.Mvvm.ViewModelLocationProvider.Register<ModelServicesPrismModule.Literature.LitDialect.UserControls.LitDialectViewEformUserControl, ModelServicesPrismModule.Literature.LitDialect.ViewModels.LitDialectViewEformViewModel>();
            containerRegistry.Register<Xamarin.Forms.ContentView, ModelServicesPrismModule.Literature.LitDialect.UserControls.LitDialectViewEformUserControl>("LitDialectViewEformUserControl");
            containerRegistry.RegisterDialog<ModelServicesPrismModule.Literature.LitDialect.UserControls.LitDialectViewEdlgUserControl, CommonUserControlLibrary.ViewModels.EdlgViewModelBase>("LitDialectViewEdlgViewModel");
            Prism.Mvvm.ViewModelLocationProvider.Register<ModelServicesPrismModule.Literature.LitDialect.UserControls.LitDialectViewLformUserControl, ModelServicesPrismModule.Literature.LitDialect.ViewModels.LitDialectViewLformViewModel>();
            containerRegistry.Register<Xamarin.Forms.ContentView, ModelServicesPrismModule.Literature.LitDialect.UserControls.LitDialectViewLformUserControl>("LitDialectViewLformUserControl");
            containerRegistry.RegisterDialog<ModelServicesPrismModule.Literature.LitDialect.UserControls.LitDialectViewLdlgUserControl, CommonUserControlLibrary.ViewModels.LdlgViewModelBase>("LitDialectViewLdlgViewModel");
            Prism.Mvvm.ViewModelLocationProvider.Register<ModelServicesPrismModule.Literature.LitDialect.UserControls.LitDialectViewO2mUserControl, ModelServicesPrismModule.Literature.LitDialect.ViewModels.LitDialectViewO2mViewModel>();
            containerRegistry.RegisterForRegionNavigation<ModelServicesPrismModule.Literature.LitDialect.UserControls.LitDialectViewO2mUserControl, ModelServicesPrismModule.Literature.LitDialect.ViewModels.LitDialectViewO2mViewModel>("LitDialectViewO2mUserControl");
            containerRegistry.Register<Xamarin.Forms.ContentView, ModelServicesPrismModule.Literature.LitDialect.UserControls.LitDialectViewO2mUserControl>("LitDialectViewO2mUserControl");
            Prism.Mvvm.ViewModelLocationProvider.Register<ModelServicesPrismModule.Literature.LitDialect.Views.LitDialectViewO2mPage, ModelServicesPrismModule.Literature.LitDialect.ViewModels.LitDialectViewO2mPageViewModel>();
            containerRegistry.RegisterForNavigation<ModelServicesPrismModule.Literature.LitDialect.Views.LitDialectViewO2mPage, ModelServicesPrismModule.Literature.LitDialect.ViewModels.LitDialectViewO2mPageViewModel>("LitDialectViewO2mPage");
            containerRegistry.Register<Xamarin.Forms.ContentPage, ModelServicesPrismModule.Literature.LitDialect.Views.LitDialectViewO2mPage>("LitDialectViewO2mPage");
            Prism.Mvvm.ViewModelLocationProvider.Register<ModelServicesPrismModule.Literature.LitDialect.UserControls.LitDialectViewReditUserControl, ModelServicesPrismModule.Literature.LitDialect.ViewModels.LitDialectViewReditViewModel>();
            containerRegistry.RegisterForRegionNavigation<ModelServicesPrismModule.Literature.LitDialect.UserControls.LitDialectViewReditUserControl, ModelServicesPrismModule.Literature.LitDialect.ViewModels.LitDialectViewReditViewModel>("LitDialectViewReditUserControl");
            containerRegistry.Register<Xamarin.Forms.ContentView, ModelServicesPrismModule.Literature.LitDialect.UserControls.LitDialectViewReditUserControl>("LitDialectViewReditUserControl");
            Prism.Mvvm.ViewModelLocationProvider.Register<ModelServicesPrismModule.Literature.LitDialect.Views.LitDialectViewReditPage, ModelServicesPrismModule.Literature.LitDialect.ViewModels.LitDialectViewReditPageViewModel>();
            containerRegistry.RegisterForNavigation<ModelServicesPrismModule.Literature.LitDialect.Views.LitDialectViewReditPage, ModelServicesPrismModule.Literature.LitDialect.ViewModels.LitDialectViewReditPageViewModel>("LitDialectViewReditPage");
            containerRegistry.Register<Xamarin.Forms.ContentPage, ModelServicesPrismModule.Literature.LitDialect.Views.LitDialectViewReditPage>("LitDialectViewReditPage");
            Prism.Mvvm.ViewModelLocationProvider.Register<ModelServicesPrismModule.Literature.LitDialect.UserControls.LitDialectViewRlistUserControl, ModelServicesPrismModule.Literature.LitDialect.ViewModels.LitDialectViewRlistViewModel>();
            containerRegistry.RegisterForRegionNavigation<ModelServicesPrismModule.Literature.LitDialect.UserControls.LitDialectViewRlistUserControl, ModelServicesPrismModule.Literature.LitDialect.ViewModels.LitDialectViewRlistViewModel>("LitDialectViewRlistUserControl");
            containerRegistry.Register<Xamarin.Forms.ContentView, ModelServicesPrismModule.Literature.LitDialect.UserControls.LitDialectViewRlistUserControl>("LitDialectViewRlistUserControl");
            Prism.Mvvm.ViewModelLocationProvider.Register<ModelServicesPrismModule.Literature.LitDialect.Views.LitDialectViewRlistPage, ModelServicesPrismModule.Literature.LitDialect.ViewModels.LitDialectViewRlistPageViewModel>();
            containerRegistry.RegisterForNavigation<ModelServicesPrismModule.Literature.LitDialect.Views.LitDialectViewRlistPage, ModelServicesPrismModule.Literature.LitDialect.ViewModels.LitDialectViewRlistPageViewModel>("LitDialectViewRlistPage");
            containerRegistry.Register<Xamarin.Forms.ContentPage, ModelServicesPrismModule.Literature.LitDialect.Views.LitDialectViewRlistPage>("LitDialectViewRlistPage");
            Prism.Mvvm.ViewModelLocationProvider.Register<ModelServicesPrismModule.Literature.LitDialect.UserControls.LitDialectViewRdlistUserControl, ModelServicesPrismModule.Literature.LitDialect.ViewModels.LitDialectViewRdlistViewModel>();
            containerRegistry.RegisterForRegionNavigation<ModelServicesPrismModule.Literature.LitDialect.UserControls.LitDialectViewRdlistUserControl, ModelServicesPrismModule.Literature.LitDialect.ViewModels.LitDialectViewRdlistViewModel>("LitDialectViewRdlistUserControl");
            containerRegistry.Register<Xamarin.Forms.ContentView, ModelServicesPrismModule.Literature.LitDialect.UserControls.LitDialectViewRdlistUserControl>("LitDialectViewRdlistUserControl");
            Prism.Mvvm.ViewModelLocationProvider.Register<ModelServicesPrismModule.Literature.LitDialect.Views.LitDialectViewRdlistPage, ModelServicesPrismModule.Literature.LitDialect.ViewModels.LitDialectViewRdlistPageViewModel>();
            containerRegistry.RegisterForNavigation<ModelServicesPrismModule.Literature.LitDialect.Views.LitDialectViewRdlistPage, ModelServicesPrismModule.Literature.LitDialect.ViewModels.LitDialectViewRdlistPageViewModel>("LitDialectViewRdlistPage");
            containerRegistry.Register<Xamarin.Forms.ContentPage, ModelServicesPrismModule.Literature.LitDialect.Views.LitDialectViewRdlistPage>("LitDialectViewRdlistPage");

        }
  • Open "Views\MainFlyoutPage.xaml"-file of the PrismDemoApp-project
  • Modify content of StackLayout as shown:
                <StackLayout Padding="20" >
...
                    <Label Text="Dialect"/>
                    <Button BackgroundColor="Transparent"  Text="L Dialog"  Command="{Binding ShowDialogCommand}" CommandParameter="LitDialectViewLdlgViewModel" />
                    <Button BackgroundColor="Transparent"  Text="R Page"    Command="{Binding NavigateCommand}" CommandParameter="LitDialectViewRlistPage" />
                    <Button BackgroundColor="Transparent"  Text="Rd Page"   Command="{Binding NavigateCommand}" CommandParameter="LitDialectViewRdlistPage" />
                    <Button BackgroundColor="Transparent"  Text="O2m Page"  Command="{Binding NavigateCommand}" CommandParameter="LitDialectViewO2mPage" />
                </StackLayout>

Note

  • Here is how to get CommandParameters like [CommandParameter="LitDialectViewO2mPage"]
    • Under ModelServicesPrismModule-project navigate to RegisterTypes()-method of the ModelServicesPrismModuleModule.cs
        public void RegisterTypes(IContainerRegistry containerRegistry)
        {

            containerRegistry.RegisterForRegionNavigation<ModelServicesPrismModule.Literature.LitDialect.UserControls.LitDialectViewO2mUserControl, ModelServicesPrismModule.Literature.LitDialect.ViewModels.LitDialectViewO2mViewModel>("LitDialectViewO2mUserControl");
...
            containerRegistry.RegisterForRegionNavigation<ModelServicesPrismModule.Literature.LitDialect.UserControls.LitDialectViewReditUserControl, ModelServicesPrismModule.Literature.LitDialect.ViewModels.LitDialectViewReditViewModel>("LitDialectViewReditUserControl");
...
            containerRegistry.RegisterForRegionNavigation<ModelServicesPrismModule.Literature.LitDialect.UserControls.LitDialectViewRlistUserControl, ModelServicesPrismModule.Literature.LitDialect.ViewModels.LitDialectViewRlistViewModel>("LitDialectViewRlistUserControl");
...
            containerRegistry.RegisterForRegionNavigation<ModelServicesPrismModule.Literature.LitDialect.UserControls.LitDialectViewRdlistUserControl, ModelServicesPrismModule.Literature.LitDialect.ViewModels.LitDialectViewRdlistViewModel>("LitDialectViewRdlistUserControl");
...
        }

Look for "containerRegistry.RegisterForRegionNavigation" with "...LitDialect...".

Rebuild

  • rebuild
    • PrismDemoApp
  • run PrismDemoApp.Android
  • In the app click "R Page"-menu item of "Country"-block and add a pair of records

picture

or UWP

picture

and

picture