Xamarin Memory Limitation or? - xamarin

Can anyone tell me if they have run into any "memory" limitations with Xamarin Forms App for Android?
I recently decided to give Xamarin another go... A few years back I ran into far too many hurdles and went a different route. I hoped things had changed.
I have an empty Xamarin Forms App for Android ONLY at this point (no OSX or UWP support). I created and updated the initial app (4.3 Xamarin Forms). I modified the mainpage.xaml and the mainpage.xaml.cs. Simple 3 row grid... 2 columns... first row, small header image centered columnspan="2"... Second row is also centered, with a CollectionView to "horizontally" scroll some simple small icon/images... Third row of gird is for detail (not yet implemented). So, with this, you can see the application is still quite small and has no real magic going on... Here is the delimma...
I have 8 c# Objects that are a c# Class... I began building the application using a simplified version of the class... Name, and ImageName only for the purpose of testing the 4.3 CollectionView for a navigation UI... After I had the functionality I wanted and it was running and tested for deployment to device, Everything seemed fine... So, I continued and built out the full class objects (13 fields, all strings no real data entered, just empty quotes for value = "". The only fields I have filled in are the original Name and ImageName is code read only... Running the App in the emulator, it now fails on load... and the emulator asks if I would like to close or try and reload...
It seems that my display class, when the class has more than the first few fields filled in causes some sort of overload:
var displaylist = new List<"DisplayClass"> ();
var dc = New DisplayClass({Name = "This Icon"})... add all 8 and things are working...
var dc = new DisplayClass({Name="This Icon", State="MA", Style="", Definition="", ... all others empty string});
--- add all 8 classes with names only and all empty fields... fails to load app...
public class DisplayClass
{
public string Name { get; set; }
public string State { get; set; }
public string Style { get; set; }
public string Definition { get; set; }
public string Days { get; set; }
public string Time { get; set; }
public DateTime StartDate { get; set; }
public string Imageurl { get; set; }
public string Dataurl { get; set; }
public string Retrievalurl { get; set; }
public string LastRetrievalDate { get; set; }
public string LastInfoData { get; set; }
public string Quantity { get; set; }
public string ImageName
{
get { return Name.Replace(" ", string.Empty).ToLower(); }
}
}
I updated the emulator to use 4GB instead of 1GB, but that had no effect. There are no code errors that I can tell, if I remark out the full object classes and implement the stripped out version it works without error... I do not get an error, only a App failed to start dialog from Android...
Can anyone shed light on this?

My bad... I had an un-instantiated datetime in my class... oops... sorry folks!

Related

Suppress implicit required attribute

Consider the following simple model:
public class TestClass {
[MyRequired(ErrorMessage = "Some error message")]
public int TestVariable { get; set; }
}
This will implicitly add the [Required] attribute and the rendered html will contain data-val attributes for both [Required] and [MyRequired].
I found 2 possible solutions:
// Solution #1 (.net 5 only)
DataAnnotationsModelValidatorProvider.AddImplicitRequiredAttributeForValueTypes = false;
// Solution #2
services.AddControllers(options => options.SuppressImplicitRequiredAttributeForNonNullableReferenceTypes = true);
Unfortunately the first solution is not available for .net 6 and the second solution doesn't seem to work (propably because int is a value type and not a reference type?)
Finally I was able to solve this by making the TestVariable nullable:
public int? TestVariable { get; set; }
Not sure if this is good practice. Is there any way to disable this behavior globally without making everything nullable?

Getting a clash on casting using Xamarin Preferences

I am getting a strange issue with xamarin essentials preferences documentation I am getting a time out the issue at present.
var warehouseFromId = Preferences.Get("WarehouseFromId", "");
WarehouseFromId = Convert.ToInt64(warehouseFromId);
I am setting the value as such using a constructor method called savedSettings but sometimes that won't be called till the user has clicked a button, so why is my getting a cast exception.
public string WarehouseFromName { get; set; }
public long WarehouseFromId { get; set; }
warehouseFromName="TT";
WarehouseFromId=1839;
Preferences.Set("WarehouseFrom", warehouseFromName);
Preferences.Set("WarehouseFromId", WarehouseFromId);
So I thought may have been because I am using "" which would denote a string so i tried the following.
var warehouseFromId = Preferences.Get("WarehouseFromId", 0);
I got the bellow
Unhandled Exception:
Java.Lang.ClassCastException: then i got this after my test above
Unhandled Exception:
System.MissingMethodException: Method not found: int
Xamarin.Essentials.Preferences.Get(string,int)
According to your code, you could need to take a care Convert.ToInt64(), Converts a specified value to a 64-bit signed integer, it is not a empty or null.
Preferences.Get() is to retrieve a value from preferences or a default if not set, so If you want to use Preferences.Get() to set vakue firstly, then retrive this value, please confirm you don't use Preferences.Set("my_key", "my_value") to set value before, otherwise it will report a error.
public string WarehouseFromName { get; set; }
public long WarehouseFromId { get; set; }
public long Id { get; set; }
Preferences.Clear();
WarehouseFromName = "TT";
WarehouseFromId = 1839;
Preferences.Set("WarehouseFrom", WarehouseFromName);
Preferences.Set("WarehouseFromId", WarehouseFromId);
Console.WriteLine("the WarehouseFromId is {0}",Convert.ToInt64(WarehouseFromId));
Id= Preferences.Get("Id", 0);
Console.WriteLine("the value is {0}",Convert.ToInt64(Id));

Skype Converting Item Numbers to Emoji

My bot is displaying in Skype, but the 6 and 8 appear as emoji.
This is just a normal FormFlow form:
public class WeightsForm
{
public Weight FromUnitType { get; set; }
public double Amount { get; set; }
public Weight ToUnitType { get; set; }
public static IForm<WeightsForm> BuildForm()
{
return new FormBuilder<WeightsForm>()
.Message("Now you can select weight conversion details.")
.AddRemainingFields()
.Build();
}
}
with Weights based on an enum:
public enum Weight
{
None,
Ton,
Slug,
Pound,
Ounce,
Grain,
Picogram,
Nanogram,
Microgram,
Milligram,
Centigram,
Decigram,
Gram,
Dekagram,
Hectogram,
Kilogram,
Megagram,
Gigagram,
Teragram
}
What is the best way to get this to display, on Skype, without the emoji?
To fix this you need to change the template used for generating the numbers so that Skype does not interpret this as an emoji. If you add this annotation on your class:
[Template(TemplateUsage.EnumSelectOne, ChoiceFormat = "{0}. {1}")]
That would fix the problem for single selections. Alternatively you could change the default template in builder.Configuration.Templates. If you wanted to fix EnumSelectMany you could add that as well.
What version of the SDK are you running? If you are running the latest and unless you have tweaked the choice style you should get buttons on skype by default. (The next release will have more style options as well.)

Combining Linq Expressions for Dto Selector

We have a lot of Dto classes in our project and on various occasions SELECT them using Expressions from the entity framework context. This has the benefit, that EF can parse our request, and build a nice SQL statement out of it.
Unfortunatly, this has led to very big Expressions, because we have no way of combining them.
So if you have a class DtoA with 3 properties, and one of them is of class DtoB with 5 properties, and again one of those is of class DtoC with 10 properties, you would have to write one big selector.
public static Expression<Func<ClassA, DtoA>> ToDto =
from => new DtoA
{
Id = from.Id,
Name = from.Name,
Size = from.Size,
MyB = new DtoB
{
Id = from.MyB.Id,
...
MyCList = from.MyCList.Select(myC => new DtoC
{
Id = myC.Id,
...
}
}
};
Also, they cannot be reused. When you have DtoD, which also has a propertiy of class DtoB, you would have to paste in the desired code of DtoB and DtoC again.
public static Expression<Func<ClassD, DtoD>> ToDto =
from => new DtoD
{
Id = from.Id,
Length = from.Length,
MyB = new DtoB
{
Id = from.MyB.Id,
...
MyCList = from.MyCList.Select(myC => new DtoC
{
Id = myC.Id,
...
}
}
};
So this will escalate pretty fast. Please note that the mentioned code is just an example, but you get the idea.
I would like to define an expression for each class and then combine them as required, as well as EF still be able to parse it and generate the SQL statement so to not lose the performance improvement.
How can i achieve this?
Have you thought about using Automapper ? You can define your Dtos and create a mapping between the original entity and the Dto and/or vice versa, and using the projection, you don't need any select statements as Automapper will do it for you automatically and it will project only the dto's properties into SQL query.
for example, if you have a Person table with the following structure:
public class Person
{
public int Id { get; set; }
public string Title { get; set; }
public string FamilyName { get; set; }
public string GivenName { get; set; }
public string Initial { get; set; }
public string PreferredName { get; set; }
public string FormerTitle { get; set; }
public string FormerFamilyName { get; set; }
public string FormerGivenName { get; set; }
}
and your dto was like this :
public class PersonDto
{
public int Id { get; set; }
public string Title { get; set; }
public string FamilyName { get; set; }
public string GivenName { get; set; }
}
You can create a mapping between Person and PersonDto like this
Mapper.CreateMap<Person, PersonDto>()
and when you query the database using Entity Framework (for example), you can use something like this to get PersonDto columns only:
ctx.People.Where(p=> p.FamilyName.Contains("John"))
.Project()
.To<PersonDto>()
.ToList();
which will return a list of PersonDtos that has a family name contains "John", and if you run a sql profiler for example you will see that only the PersonDto columns were selected.
Automapper also supports hierachy, if your Person for example has an Address linked to it that you want to return AddressDto for it.
I think it worth to have a look and check it, it cleans a lot of the mess that manual mapping requires.
I thought about it a little, and I didn't come up with any "awesome" solution.
Essentially you have two general choices here,
Use placeholder and rewrite expression tree entirely.
Something like this,
public static Expression<Func<ClassA, DtoA>> DtoExpression{
get{
Expression<Func<ClassA, DtoA>> dtoExpression = classA => new DtoA(){
BDto = Magic.Swap(ClassB.DtoExpression),
};
// todo; here you have access to dtoExpression,
// you need to use expression transformers
// in order to find & replace the Magic.Swap(..) call with the
// actual Expression code(NewExpression),
// Rewriting the expression tree is no easy task,
// but EF will be able to understand it this way.
// the code will be quite tricky, but can be solved
// within ~50-100 lines of code, I expect.
// For that, see ExpressionVisitor.
// As ExpressionVisitor detects the usage of Magic.Swap,
// it has to check the actual expression(ClassB.DtoExpression),
// and rebuild it as MemberInitExpression & NewExpression,
// and the bindings have to be mapped to correct places.
return Magic.Rebuild(dtoExpression);
}
The other way is to start using only Expression class(ditching the LINQ). This way you can write the queries from zero, and reusability will be nice, however, things get harder & you lose type safety. Microsoft has nice reference about dynamic expressions. If you structure everything that way, you can reuse a lot of the functionality. Eg, you define NewExpression and then you can later reuse it, if needed.
The third way is to basically use lambda syntax: .Where, .Select etc.. This gives you definitely better "reusability" rate. It doesn't solve your problem 100%, but it can help you to compose queries a bit better. For example: from.MyCList.Select(dtoCSelector)

Self referring hierarchical data binding

I'm using Extensions for ASP.NET MVC Q3 2011(open source version) with Razor engine and Asp.net MVC3 architecture.
I want to bind a grid to a entity in my database which has self referring structure (like a tree). Therefore, I can not define it like examples with fixed levels, because I do not know how many levels this grid has. So, I want to bind my grid dynamically to a model.
public class Category : Entity
{
public virtual int Id {private set; get; }
public virtual string Title { set; get; }
public virtual string Description { set; get; }
public virtual string ParentsPath { set; get; }
public virtual IList<Category> Children { get; private set; }
public virtual Category Parent { get; set; }
}
I'm also using Fluent NHibernate and because of that I store children and parent in my entity.
Is there a way to do this? I couldn't find anything in documentations.
Am I missing something? because in Ajax and Winform components, it has been implemented.
Thanks.
You cannot do it automatically, You need a foreach iteration and generating the items and then add them to the tree manually.
I did it for PanelBar when I needed to show a hierarchicy.
Here is an example :
#(Html.Telerik().PanelBar()
.Name("Details")
.ExpandMode(PanelBarExpandMode.Multiple)
.Items(items =>
{
var parent = Model.ParentWorkItem;
List<WorkItem> lst = new List<WorkItem>();
while (parent != null)
{
lst.Add(parent);
parent = parent.ParentWorkItem;
};
for (int i = lst.Count-1; i >=0;i-- )
{
parent = lst[i];
items.Add()
.Expanded(false)
.Text("...")
.LoadContentFrom(...);
}
items.Add()
.Expanded(true)
.Text(...)
.Content(....);
})
)
Hope to be helpful.

Resources