XPO para Xamarin Forms, May 15 2019 (Lenguaje Español)

XPO para Xamarin Forms, May 15 2019 (Lenguaje Español)

En el seminario web, aprenderá a aprovechar los conocimientos existentes de XPO y a usarlos para desarrollar aplicaciones móviles con Xamarin Forms

Fecha

Miercoles 15, 2019, 10:00 A. M hora de los Angeles (UTC-7)

Duracion

3 Horas

Lenguaje

Español

¿Qué obtendrá después del webinar?

  • Acceso al repositorio privado de GitHub con ejemplos de código para cada tema
  • La sesión de Webinar grabada

Lista de temas

  1. Instalación de XPO para Xamarin Forms (Android e iOS)
  2. Inicializar la base de datos local y el esquema
  3. Conexiones locales con SQLite: instalación de paquetes necesarios para Android e iOS
  4. Conexiones locales con XML: creación de un archivo XML base
  5. Conexiones remotas: conexión de base de datos directa con TCPIP (red LAN)
  6. Conexiones remotas: la capa de acceso a datos de WCF
  7. Inicializar la capa de datos
  8. Enlace (binding) de datos MVVM
  9. Enlace de propiedades primitivas
  10. Enlace de propiedades de navegación
  11. Cargando colecciones (la forma tradicional)
  12. Cargando colecciones asincrónicas
  13. Cargando un solo objeto de forma asíncrona
  14. Las paginaciones en colecciones
  15. Como reducir la carga de datos con XPView
  16. Colecciones observables con BIT. Xpo. observables

Requisitos previos

  • Comprensión básica de Xamarin Forms
  • Comprensión básica del patrón de diseño MVVM
  • Conocimiento básico de XPO

Precio

€99,00 EUROS

[wpecpp name=”xamarin xpo es” price=”99.00″ align=”left”]

Nota

Si está interesado en este curso o tiene alguna duda póngase en contacto con nosotros en training@bitframeworks.com

 

XPO para Xamarin Forms, May 15 2019 (Lenguaje Español)

XPO for Xamarin Forms, May 22, 2019 (English language)

In the webinar, you will learn how to leverage your existing knowledge of XPO and using it to develop mobile applications using Xamarin Forms

Date

May 22, 2019, 10:00 A.M Los Angeles time (UTC -7)

Language

English

What will you get after the webinar?

  • Access to the private GitHub repository with code examples for each subject
  • The recorded webinar session

Subject list

  1. Installing XPO for Xamarin forms (Android and iOS)
  2. Initializing local database and schema
  3. Local connections with SQLite: Installing packages necessary for Android and iOS
  4. Local connections with XML: Creating a base XML file
  5. Remote connections: Direct database connection with TCPIP (LAN network)
  6. Remote connections: WCF Data access layer
  7. Initializing Data layer
  8. MVVM Data binding
  9. Primitive properties
  10. Navigation properties
  11. Loading collections (the traditional way)
  12. Loading collections async
  13. Loading single object async
  14. Paging collections
  15. Reducing data loading with XPView
  16. Observables Collections with BIT.Xpo.Observables

Prerequisites

  • Basic understanding of Xamarin Forms
  • Basic understanding of MVVM design pattern
  • Basic understanding of XPO

Price

€99,00 EUROS

[wpecpp name=”xamarin xpo en” price=”99.00″ align=”left”]
 



Signup

If you are interested in this course or you have any doubt please contact us at training@bitframeworks.com

 

Migrating XAF projects to the new version of csproj (SDK project VS2017)

Migrating XAF projects to the new version of csproj (SDK project VS2017)

For a while now I have been trying to create a framework for XAF (yes I know XAF is already a framework) but it was too difficult to handle the different version of XAF and upgrade the solution from version to version.

Luckily for me, DevExpress team decided to publish all their DLLs as nuget packages, you can learn more about that here. But there was still one problem for me, at that time they did not include the nugets for XAF, later that year (2018) they decided to publish the nugets for XAF, you can read about it here

Now I have all the pieces to create the project template for the modules of my framework, at least that is what I thought, there was still one more stone in my path and it was the csproj file. At this moment (version 18.2.x) XAF project templates are based on visual studio 2015 project format, so the way the projects handles nuget references is based on the old standard packages.config, another problem is that if you want to package your module as a nuget you have to use the old package.nuspec.

So let’s migrate our XAF module project to the new version of csproj, but first take a look to the old version of the file in the image below

 

Once you have a XAF solution open on visual studio these are the steps to do the migration

1) Right click on your module file and select “Unload Project”

2) Now that the project us unloaded it will appear unavailable in the solution explorer, so we can right click over it and select “edit”

4) Delete all the content of your csproj and replace it with this XML, you can also change the version of nuget files, in this case, I’m using 18.2.6


<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFramework>net452</TargetFramework>
    <GenerateAssemblyInfo>true</GenerateAssemblyInfo>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="DevExpress.ExpressApp.Security.Xpo" Version="18.2.6" />
    <PackageReference Include="DevExpress.ExpressApp.Validation" Version="18.2.6" />
    <PackageReference Include="DevExpress.Persistent.BaseImpl" Version="18.2.6" />
  </ItemGroup>

  <ItemGroup>
    <Folder Include="Properties\" />
  </ItemGroup>
</Project>

5)Delete the file AssemblyInfo.cs from the properties folder

 

Congratulations you have successfully migrated your csproj file

Now some advantages and disadvantages of this new csproj format

Advantages
  1. Smaller project file easy to edit
  2. improved usage of nuget packages
  3. its easier to pack your module as a nuget
Disadvantages
  1. You can not use the Devexpress add item context menu because it will add references to local assemblies
  2. The module designer stop working so you have to do all your module configuration in code

 

 

 

 

 

 

 

XAF javascript callback made easy

Sometimes we need to have clientside events and handle them on the server side code behind, that in a simple asp.net web page is really easy, you just have to execute a javascript that executes an HTTP request to the server. Now the question is, how do we do that in XAF?

Well, the concept is basically the same but you need to know XAF architecture the problem is that most of the code needed is not documented, but after a while, I manage to figure it out, so let’s get started.

1)  Create a XAF web application

2) On your web module add a view controller

3) Implement the interface IXafCallbackHandler on the controller you just added in step 2, this is the method that will be called as a callback from javascript. This interface is not documented on the DevExpress website

4) In your view controller add a property to access XafCallbackManager

5) Override the OnViewControlsCreated method and register your callback, in this example, the name of the callback is “MyScript”

6) Now add a simple action and wire the execute event, on the execute event cast the frame as a web window and register a startup script. The code surrounded with the blue line is the javascript that triggers the callback in the callback manager, the code surrounded with red is the id if the script that we are listening for, it should match the name of the script registered on the handler in the previous step.

To execute the callback somewhere in your javascript you have to execute the following function RaiseXafCallback, this function is not documented on the DevExpress website

RaiseXafCallback(globalCallbackControl, 'TheIdOfYourHandler', 'AnyStringThatRepresentsTheValuesYouWantToPassToTheCallBack', '', false);

7) Run your application and execute the simple action added in step 6, when the javascript finish executing, the method you implemented on step 3 will be executed.

 

The code for this article is here  the full example is in GitHub

 

 

 

 

Xamarin Forms UWP / UAP Broad File System Access (Permissions)

For a long time now, I have wanted to access the file system when I create a Xamarin Forms UAP/UWP application but that was actually impossible … till now. After the Windows 10 build 17134 update its possible to access the broad file system, the approach is not straight forward.

To gain access to the file system in your Xamarin Forms UAP/UWP application follow these steps

1) Go the properties of your UAP/UWP application and check the targeting, the minimum should be at least 16299, what I recommend is 171344

You can also change the targets unloading the project and editing the csproj file

2) In your solution explorer edit your Package.appxmanifest by selecting it and press F7, looking the file from the top should look like the image below

Add this namespace xmlns:rescap=”http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities and update the IgnorableNamesSpaces like this IgnorableNamespaces=”uap mp rescap” after the changes your file should look like the image below

3) Lookup for the capabilities node in the manifest and add a new capability  <rescap:Capability Name=”broadFileSystemAccess” /> your capabilities section should look like the image below

4) Rebuild your application, then select it on the solution explorer, right click over it and click on deploy, this will register the application in your OS

5) on your Windows OS go to settings>File system privacy settings and you will see all the UAP/UWP applications that are registered  in your OS and have access to the file system, here you can allow/deny the access to the file system in general or by application

6) now everything is ready for your app to access the file system, but there is a little catch, in most cases, you cannot use the classes in system.io to access the file system you have to use Windows.Storage.Storagefolder below is a code snippet that illustrates how to use such class

public async void GetDirectories(string sDir)
{
    
    var folder = await StorageFolder.GetFolderFromPathAsync(sDir);   
    foreach (var file in await folder.GetFilesAsync())
    {
        Debug.WriteLine(file.Name);
        
    }

}

 

I have created a sample app using these steps, you can download the source from GitHub

 

 

 

 

 

CodeRush Entity Framework Code Templates

Don’t waste your time writing boilerplate code, just use Code Rush from DevExpress

 

Entity Framework Class (shortcut efc)

Entity Framework Property (shortcut efpr)

Entity Framework Property (shortcut efnp)

Entity Framework Collection (shortcut efcol)

Entity Framework extensions (shortcut efext)

Entity Framework ModelBuilder Association (shortcut efrom)

 

You can download all these amazing code templates here [download id=”241″]

 

What is an application framework?

Let’s try to define what is an application framework, for that we will check how famous website defines the term “Application Framework”

From Wikipedia 

In computer programming, an application framework[1] consists of a software framework used by software developers to implement the standard structure of application software.[2]

From techopedia

An application framework is a software library that provides a fundamental structure to support the development of applications for a specific environment. An application framework acts as the skeletal support to build an application.

Now my own definition of an application framework

An application framework is a set of tools, components and design patterns that allow the programmer to develop an application for a well define pourpose (like a business application, a game etc..). The main pourpse of an application framework should be reduce the development time and allow the developer to focus on the main pourpouse of the application instead of the application infrastructure

That is all for now, as you can see the concept is really simple but as they say “devil lies on the details”. In the upcoming post, we will define the parts of an application framework.

 

XAF FilterController case insensitive search

Sometimes you are asked by a customer to implement a functionality that you have already created in the past from someone else.

In this case, a customer and dear friend from Italy asked me “Jose, can we make the XAF filter case insensitive?”

And my answer was yes, I have done in the past for a customer in El Salvador. At that time the approach we used was to save everything in uppercases and do all the searches in uppercases also

I didn’t like that approach at all, so it was time get creative again.

As always I start my research by spending some time reading tickets at https://www.devexpress.com/Support/Center/ which is the greatest source of information for all things related to DevExpress

Here is what I found

  1. https://www.devexpress.com/Support/Center/Question/Details/Q356778/how-can-i-activate-case-insensitive-search-in-lookup-views this approach actually works but the problem is that the name of the fields are hardcoded
  2. https://www.devexpress.com/Support/Center/Question/Details/Q343797/root-listview-filterbytext-include-the-collection-propertys this second approach just append extra nodes to the criteria so its also not good but what I have learned with this example is when is the right moment to alter the criteria.

My first idea was to edit the criteria that were sent to the collection source that means that I need a way to get the values of each node on the criteria, so I can edit them one by one. After some more research, this is what I have found

https://www.devexpress.com/Support/Center/Question/Details/Q539396/criteriaoperator-how-to-get-list-of-parameters-and-their-values

this approach seems perfect to get the properties and values of each node till test it and find out this

Michael (DevExpress Support)6 years ago

It is possible to write a hierarchy walker or visitor, but only for a specific subset of criteria operators.

What Michael means is that only you can only get the values of simple criteria and by simple, I mean the ones that do not involve functions. So, I was set back to step one again.

So, I’m back to step one but let’s see what I’ve learned from the other tickets

  1. I know the exact moment when the criteria are evaluated
  2. I know the criteria that are evaluated and how many nodes it contains
  3. I know which the possible properties are involved in the creation of the criteria

Now this is the flow that I will use to make the search case insensitive

  1. Locate the controller where the search action lives, for that, I can use the property frame and the method get controller
  2. Interrupt the search action, for that, I will wire the event execute of the FilterController FullTextFilterAction action
  3. Find out what are the possible properties that I can use to build the search criteria for that I will use GetFullTextSearchProperties
  4. Build the new criteria, this is somehow tricky because the properties shown in the list view might represent complex objects and that is shown in the column is either the object default property or any other property that can be deep inside the properties tree. Also this step involve find out what is the type of the value being displayed on the list view, if the value is a string I will evaluate its value converted to upper cases using the function upper from the criteria language, if the search value is not a string but a number I will try to cast it to the type of the display column, if the cast is not invalid I will evaluate the search value as a number
  5. Set the new filter to the list view

You can cross reference the points above with the sample code below

 

   using System;
   using System.Collections.Generic;
   using System.Diagnostics;
   using System.Linq;
   using System.Text;
   using DevExpress.Data.Filtering;
   using DevExpress.ExpressApp;
   using DevExpress.ExpressApp.Actions;
   using DevExpress.ExpressApp.Editors;
   using DevExpress.ExpressApp.Layout;
   using DevExpress.ExpressApp.Model;
   using DevExpress.ExpressApp.Model.NodeGenerators;
   using DevExpress.ExpressApp.SystemModule;
   using DevExpress.ExpressApp.Templates;
   using DevExpress.ExpressApp.Utils;
   using DevExpress.Persistent.Base;
   using DevExpress.Persistent.Validation;

   public class FilterControllerCaseInsensitive : ViewController<ListView>
   {
       public FilterControllerCaseInsensitive()
       {

       }
       FilterController standardFilterController;
       protected override void OnActivated()
       {
           standardFilterController = Frame.GetController<FilterController>();
           if (standardFilterController == null)
               return;

           //we should wire the execution of the filter
           standardFilterController.FullTextFilterAction.Execute += FullTextFilterAction_Execute;



       }
       protected override void OnDeactivated()
       {
           base.OnDeactivated();
           if (standardFilterController == null)
               return;

           //we should unwire the execution of the filter
           standardFilterController.FullTextFilterAction.Execute -= FullTextFilterAction_Execute;
       }


       private void FullTextFilterAction_Execute(object sender, ParametrizedActionExecuteEventArgs e)
       {
           //we locate filter with the key FilterController.FullTextSearchCriteriaName then we convert it to case insensitive
           if (!string.IsNullOrEmpty(e.ParameterCurrentValue as string) && View.CollectionSource.Criteria.ContainsKey(FilterController.FullTextSearchCriteriaName))
               View.CollectionSource.Criteria[FilterController.FullTextSearchCriteriaName] = GetCaseInsensitiveCriteria(e.ParameterCurrentValue, View.CollectionSource.Criteria[FilterController.FullTextSearchCriteriaName]);
       }


       private CriteriaOperator GetCaseInsensitiveCriteria(object searchValue, CriteriaOperator initialCriteria)
       {

           //we get a list of all the properties that can be involved in the filter
           var SearchProperties = standardFilterController.GetFullTextSearchProperties();
           //we declare a model class and a property name,the values on this variables will change if we property involve is a navigation property (another persistent object)
           IModelClass ModelClass = null;
           string PropertyName = string.Empty;

           //we declare a list of operators to contains new operators we are going to create
           List<CriteriaOperator> Operator = new List<CriteriaOperator>();
           //we iterate all the properties
           foreach (var CurrentProperty in SearchProperties)
           {
               //here we split the name with a dot, if length is greater than 1 it means its a navigation properties, beware that this may fail with a deep tree of properties like category.subcategory.categoryname
               var Split = CurrentProperty.Split('.');
               if (Split.Length > 1)
               {

                   Debug.WriteLine(string.Format("{0}","its a complex property"));
                   var CurrentClass = this.View.Model.ModelClass;
                   for (int i = 0; i < Split.Length; i++)
                   {

                       //if its a navigation property we locate the type in the BOModel
                       IModelMember member = CurrentClass.OwnMembers.Where(m => m.Name == Split[i]).FirstOrDefault();
                       //then we set the model class and property name to the values of the navigation property like category.name where category is the model class and name is the property
                       CurrentClass = this.Application.Model.BOModel.GetClass(member.Type);
                       if (CurrentClass == null)
                           continue;

                       ModelClass = CurrentClass;
                       PropertyName = Split[i + 1];
                     

                   }
                   Debug.WriteLine(string.Format("{0}:{1}", "ModelClass", ModelClass.Name));
                   Debug.WriteLine(string.Format("{0}:{1}", "PropertyName", PropertyName));
                   
                   
                  

               }
               else
               {
                   //else the model class will be the current class where the filter is executing, and the property will be the current property we are evaluating
                   ModelClass = this.View.Model.ModelClass;
                   PropertyName = CurrentProperty;
               }

               //we look for the property on the class model own member
               var Property = ModelClass.OwnMembers.Where(m => m.Name == PropertyName).FirstOrDefault();
               if (Property != null)
               {
                   //if the property is a string it means that we can set it to upper case
                   if (Property.Type == typeof(string))
                   {
                       searchValue = searchValue.ToString().ToUpper();
                       //we create an operator where we set the value of the property to upper before we compare it, also we change the comparison value to upper
                       CriteriaOperator Operand = CriteriaOperator.Parse("Contains(Upper(" + CurrentProperty + "), ?)", searchValue);
                       //we added to the list of operators that will concatenate with OR
                       Operator.Add(Operand);
                   }
                   else
                   {
                       //if the property is not a string we need to try to cast the value to the correct type so we do a catch try, if we manage to cast the value it will be added to the operators list
                       try
                       {

                           var ConvertedType = Convert.ChangeType(searchValue, Property.Type);
                           CriteriaOperator operand = new BinaryOperator(CurrentProperty, ConvertedType, BinaryOperatorType.Equal);
                           Operator.Add(operand);
                       }
                       catch (Exception)
                       {

                           //silent exception, this will happen if the casting was not successful so we won't add the operand on this case
                       }
                   }




               }
           }

           //we concatenate everything with an OR 
           var alloperators = CriteriaOperator.Or(Operator.ToArray());
           Debug.WriteLine(string.Format("{0}:{1}", "alloperators", alloperators));
           return alloperators;
       }


   }

 

 

 

BIT.Xpo.Observables Nuget

An observable implementation of XpCollection and XPPageSelector.

After 15 years, DevExpress has finally made XPO available free-of-charge. If you’re not familiar with XPO, you can learn more about its feature set here. If you’ve used XPO in the past or are familiar with capabilities, you will love this.

As we already know a Xamarin ListView is populated with data using the ItemsSource property, which can accept any collection implementing IEnumerable but if we want the ListView to automatically update as items are added, removed or changed in the underlying list, you’ll need to use an ObservableCollection. Here is where XpoObservableCollection becomes the best friend for all the XPO fans out there.

XpoObservableCollection inherit from an XPCollection so to use, it is exactly as you would use an XPCollection, the only difference is that the XpoObservableCollection refresh the state of ListViews on Xamarin Forms.

XamarinXpoPageSelector takes it a step further by internally implementing XPPageSelector and presenting the XpoObservableCollection as a pageable collection. With this in mind, on the constructor of the XamarinXpoPageSelector  you need to pass the following parameters:

SortingCollection sorting = new SortingCollection();
sorting.Add(new SortProperty("Your Property", SortingDirection.Ascending));
XPCollection <Your Class> Collection = new XPCollection <YourClass>(UnitOfWork);
Collection.Sorting = sorting;

XamarinXpoPageSelector <YourClass> selector = new XamarinXpoPageSelector <YourClass> (Collection,10, XpoObservablePageSelectorBehavior.AppendPage);
       
this.listView.ItemsSource = selector.ObservableData;
  • Collection = An instance of XPCollection.
  • 10 = Page Size by default.
  • XpoObservablePageSelectorBehavior = AppendPage or SinglePage.

Use Append in case you want to add the results of the new page to the collection or Single page to clear the last page results before showing the new page.

And that’s it. The same awesome ObservableRangeCollection (from MVVM Helpers) that adds important methods such as AddRange, RemoveRange, Replace, and ReplaceRange, it is now available in XPO and of course, it is open source so go and take a look behind the curtains.

https://github.com/egarim/BIT.Xpo.Observables

https://www.nuget.org/packages/BIT.Xpo.Observables/

Until next time. Xpo out!