I'm going crazy for hours on an evil problem!!!
I've created a new Xamain Forms prj on Visual Studio for Mac (last version and last update).
I have three AppResources files for corrispondent languages:
- AppResources.resx (for default)
- AppResources.it.resx (for italian)
- AppResources.es.resx (for spanish)
On IOS simulator, works all good. On Android I see always the default string.
This is my simple data on AppResources file:
AppResources.resx:
<data name="test" xml:space="preserve">
<value>Default</value>
</data>
AppResources.es.resx:
<data name="test" xml:space="preserve">
<value>Espanol</value>
</data>
AppResources.it.resx:
<data name="test" xml:space="preserve">
<value>Italiano</value>
</data>
Why on IOS works perfectly and on Android I can see only "default"?!?
The problem started for me after the last visual studio (MAC) update (Version 8.6 (build 4520))
Look this:
https://github.com/xamarin/xamarin-android/issues/4664#issuecomment-632986668
This workaround solved my problem.
As a response to your comment above you could have a LocalizationService in which you will set and update your current culture (CultureInfo object). You can also use the static CultureInfo.InstalledUICulture to get the device culture.
public CultureInfo CurrentCulture
{
get => cultureInfo;
set
{
if(cultureInfo?.Equals(value) ?? false)
{
return;
}
cultureInfo = value;
Thread.CurrentThread.CurrentCulture = value;
Thread.CurrentThread.CurrentUICulture = value;
}
}
Related
How can we store and retrieve App settings as key,value pair in Xamarin.Forms?
Like when the app is closed we can store the user preferences and on restarting of the App we are able to get those values.
It can be done this way too using Properties Dictionary
for storing data:
Application.Current.Properties ["id"] = someClass.ID;
for fetching data:
if (Application.Current.Properties.ContainsKey("id"))
{
var id = Application.Current.Properties ["id"] as int;
// do something with id
}
ref: https://developer.xamarin.com/guides/xamarin-forms/working-with/application-class/#Properties_Dictionary
The Application object (in VS you get an App class that inherits from it, I think the Xamarin Studio template might be slightly different) has a Properties dictionary that is specifically for this. If you need to make sure your properties get saved right away, there is a Application.SavePropertiesAsync method you can call.
I use Settings Plugin for Xamarin And Windows for Xamarin.Forms, the upside since this is implemented at the device-level, you can access these settings from any Forms project, PCL library OR your native project within your app.
Nuget: Xam.Plugins.Settings
private const string UserNameKey = "username_key";
private static readonly string UserNameDefault = string.Empty;
public static string UserName
{
get { return AppSettings.GetValueOrDefault<string>(UserNameKey, UserNameDefault); }
set { AppSettings.AddOrUpdateValue<string>(UserNameKey, value); }
}
You can use the preferences included with Xamarin.Essential.
/* You need to using Xamarin.Essentials
If you do not have Xamarin.Essentials installed,
install it from (NuGet Package Manager)
*/
// Add a reference to Xamarin.Essentials in your class
using Xamarin.Essentials;
// To save a value for a given key in preferences
Preferences.Set("my_key", "my_value");
// To retrieve a value from preferences or a default if not set
var myValue = Preferences.Get("my_key", "default_value");
// To check if a given key exists in preferences
bool hasKey = Preferences.ContainsKey("my_key");
// To remove the key from preferences
Preferences.Remove("my_key");
// To remove all preferences
Preferences.Clear();
Have a look at this link:
https://learn.microsoft.com/en-us/xamarin/essentials/preferences?tabs=android
If the settings are more of configurations which are not changed at runtime (e.g. sort of web.config for the app) you can use App.xaml and store values in dictionary like that:
<Application.Resources>
<ResourceDictionary>
<Style x:Key="SmallLabel" TargetType="Label">
<Setter Property="TextColor" Value="Gray" />
<Setter Property="Font" Value="{StaticResource FontItalicSmall}" />
</Style>
</ResourceDictionary>
</Application.Resources>
And retrieve them in C# code like that:
var style = (Style)Application.Current.Resources["SmallLabel"];
I'm trying to display and embedded image in a shared project resource (as explained here on microsoft documentation).
I created the ImageResourceExtension, the project compiles, but I get the following error when I start the project :
Could not load type 'Xamarin.Forms.Xaml.IReferenceProvider' from
assembly 'Xamarin.Forms.Core, Version=2.0.0.0
Here's my code :
MainPage.xaml
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:App1"
x:Class="App1.MainPage">
<StackLayout>
<Image x:Name="imgTest" Source="{local:ImageResource img.jpg}" />
</StackLayout>
</ContentPage>
EmbeddedImage.cs
namespace App1
{
[ContentProperty(nameof(Source))]
public class ImageResourceExtension : IMarkupExtension
{
public string Source { get; set; }
public object ProvideValue(IServiceProvider serviceProvider)
{
if (Source == null)
return null;
// Do your translation lookup here, using whatever method you require
var imageSource = ImageSource.FromResource(Source, typeof(ImageResourceExtension).GetTypeInfo().Assembly);
return imageSource;
}
}
}
You can try this, it works for me
xyz.xaml.cs
imgName.Source = ImageSource.FromResource("ProjectName.Images.backicon.png");
xyz.xaml
<Image x:Name="imgName" />
Hope this code helps you!!
Not knowing if the answer is still valid for you, but I usually have an Assets folder outside my solution which contains Android specific folders (drawables), iOS specific folders (Resource with #2x and #3x) and a Common folder for shared images.
In my solution I add these files as a link in the folders they should be associated with. On Android in the Resources/Drawable and iOS in the Resource. In this case Common files can be shared across both platforms without physically copying them.
As a bonus, updates to these Assets can be overwritten in the folder outside my solution and will be used within my solution without any additional action to be taken.
Replace:
<Image x:Name="imgTest" Source="{local:ImageResource img.jpg}" />
With:
<Image x:Name="imgTest" Source="{local:ImageResource 'Project.Folder.img.jpg'}" />
And Replace:
var imageSource = ImageSource.FromResource(Source, typeof(...));
With:
var imageSource = ImageSource.FromResource(Source);
If you add the Image to your Android drawable folder, or to the iOS Resource folder, you don't need any extension. You can simply do:
<Image x:Name="imgTest" Source="img.jpg" />
I am creating a xamarin forms app and i want to change the transition when navigating between pages. I couldnt use https://components.xamarin.com/view/customnavpage because im using ContentPage. I also read the famous thread on xamarin forums but nothing worked for me. here is the link.
https://forums.xamarin.com/discussion/18818/custom-page-transitions-with-xamarin-forms
i'm using xamarin forms 2.3.4.247 and android api level 25 and appCompat 23.3.0.
any idea?
I found a workaround and I answer my own question maybe it helps someone else.
First we need to create a custom renderer for any platform(in this case android)
. create a new class under your Renderers folder in Droid target.
CustomTransitionsRenderer.cs
[assembly:ExportRenderer(typeof(NavigationPage),typeof(CustomTransitionsRenderer))]
namespace TesarSmartwatchForms.Droid.Renderers
{
public class CustomTransitionsRenderer : Xamarin.Forms.Platform.Android.AppCompat.NavigationPageRenderer
{
//SwitchContentAsync
protected override void SetupPageTransition(Android.Support.V4.App.FragmentTransaction transaction, bool isPush)
{
if (isPush)
transaction.SetCustomAnimations(Resource.Animator.move_in_left, 0);
else //prevView enter:
transaction.SetCustomAnimations(Resource.Animator.side_in_right, 0);
}
}
}
and then add your custom animations under Droid>Resources>animator like these:
move_in_left.xml
<?xml version="1.0" encoding="UTF-8" ?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="#android:anim/accelerate_interpolator">
<translate
android:fromXDelta="-100%p"
android:toXDelta="0"
android:duration="300"/>
</set>
and slide_in_right.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="#android:anim/linear_interpolator">
<translate
android:fromXDelta="100%p"
android:toXDelta="0"
android:duration="300" />
</set>
then we need to modify our android theme just adding this line
<item name="android:windowBackground">#android:color/transparent</item>
and remember to navigate between pages with the default navigation transition, just like this
Navigation.PushAsync(page);
I created an ImageResourceExtension class in a under Common Assembly name. I checked the name under the Reference in Property window setting. Namespace for this extension is Extension.Common.
The xaml of the working project which using this Common Assembly have a declaration as:
xmlns:common="clr-namespace:Extension.Common;assembly:Common"
The element was written as :
<common:BooleanToObjectConverter x:Key="boolToStyleImage"
x:TypeArguments="Style">
<common:BooleanToObjectConverter.FalseObject>
<Style TargetType="Image">
<Setter Property="HeightRequest" Value="20" />
<Setter Property="Source" Value="{common:ImageResource Common.Images.error.png}" />
</Style>
</common:BooleanToObjectConverter.FalseObject>
The images was stored in a Common project folder inside Images directory
I named the ImageResource file as ImageResourceExtension.cs and tried ImageResource.cs but none of it work. It just give me an exception saying:
MarkupExtension not found for common:ImageResource
I have no idea what go wrong. Have follow all the steps for a blog.
The project that I placed those xaml stuff are in a shared project. Don't know will it make any difference
I hope I understand good your question !
look at this code:
[ContentProperty("Source")]
public class ImageSourceExtension : IMarkupExtension
{
public string Source { get; set; }
public object ProvideValue(IServiceProvider serviceProvider)
{
if (Source == null)
{
return null;
}
// Do your translation lookup here, using whatever method you require
var imageSource = ImageSource.FromResource("Project.Images." + Source);
return imageSource;
}
}
Now, if you want to use an image as you did in your xaml, something like that should work:
<Image Source="{extension:ImageSource LogoProject.png}"/>
Note 1: I only put the name of the image because in the extension, the path is put automatically ;)
Note 2: You have to put the assembly/namespace as I do below:
xmlns:extension="clr-namespace:Project.Sources.Extensions;assembly=Project"
Also, you're image has to be an EmbeddedResource, do not forget about it. For the path, it's Project.Path.Image.png and not assembly as well ;)
I hope I understood your question and I could help you :)
I'm following this example for an auto-scrolling behavior on a ListBox on WP7 Mango RC targeting 7.1.
In my Xaml:
<ListBox x:Name="StatusMessages"
Height="100"
ItemsSource="{Binding StatusMessages, Mode=TwoWay}"
DisplayMemberPath="Message"
Grid.Row="3">
<i:Interaction.Behaviors>
<behaviors:ListBoxItemAutoScrollBehavior FoundItem="{Binding FoundItem}" />
</i:Interaction.Behaviors>
</ListBox>
The behavior:
public class ListBoxItemAutoScrollBehavior : Behavior<ListBox>
{
public object FoundItem
{
get { return GetValue(FoundItemProperty); }
set { SetValue(FoundItemProperty, value); }
}
public static readonly DependencyProperty FoundItemProperty = DependencyProperty.Register("FoundItem", typeof (object), typeof (ListBoxItemAutoScrollBehavior), new PropertyMetadata(FoundItemChanged));
private static void FoundItemChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
((ListBoxItemAutoScrollBehavior) d).AssociatedObject.ScrollIntoView(e.NewValue);
}
}
I have a breakpoint set at the FoundItemChanged method and would expect to see it hit when I set FoundItem in my ViewModel and fire NotifyProperyChanged. Only, it doesn't work, any ideas why or what I might be doing wrong?
Thanks.
update: breakpoints are hit for OnAttached and OnDetaching in the behavior.
update 2: This works in a regular Silveright 4 application.
update 3: Using version 3.8.5.0 of System.Windows.Interactivity fixed it.
Are you targeting 7.1 / Mango? Binding to DependencyObjects, as opposed to FrameworkElements, is a Silverlight 4 feature and thus not available in 7.0 (which uses SL 3).
There's a workaround that Prism and MVVM Light use to bind to DO's in SL 3. Check out their source for details.
Edit: Your problem is your PropertyMetadata constructor arguments. By not specifying 2 arguments (or, specifically, passing a method rather than a PropertyChangedCallback instance), the compiler might be resolving the default value constructor overload.
In short, change it to:
new PropertyMetadata(null, FoundItemChanged)
Or:
new PropertyMetadata(new PropertyChangedCallback(FoundItemChanged))
Using version 3.8.5.0 of System.Windows.Interactivity fixed this problem.
This post gave me the tip: http://caliburnmicro.codeplex.com/discussions/271092