Xamarin Forms from Windows Phone 8.1(RT) - xaml exceptions - xaml

I created app with Xamarin Forms for Windows Phone 8.1(RT). I updated XF to last version 2.3.4.231. My app in run to:
-windows phone 8.1 device
-windows phone 8.1 emulator
-mobile emulator 10.0.14393(x86)
It work is ok.
But when I running app to Windows 10 device(arm) I have many exception. I try different start pages and get mane exceptions(from xaml):
-Cannot assign property \"ColumnDefinitions\": Property does not exists, or is not assignable, or mismatching type between value and property"
-StaticResource not found for key ...
-An item with the same key has already been added
All these errors are related to xaml.
I do not use XamlCompilationOptions.Compile.
Last working version XF for my app 2.3.2.127
This small example:
I changed start page. I have exception:
-StaticResource not found for key StandardPadding
This is part of my page:
<StackLayout Padding="{StaticResource StandardPadding}">
My resource in App.xaml:
<Application.Resources>
<ResourceDictionary>
<Thickness x:Key="StandardPadding">16</Thickness>
</ResourceDictionary>
</Application.Resources>

I solved this problem. The error was in my xaml code. Xamarin Forms 2.3 not supported Windows OnPlatform in xaml. So I used this extension:
public class XOnPlatform<T> : OnPlatform<T>
{
public T Windows { get; set; }
public static implicit operator T(XOnPlatform<T> onPlatform)
{
if (Device.OS == TargetPlatform.Windows)
{
return onPlatform.Windows;
}
return (OnPlatform<T>)onPlatform;
}
}
I used this class in my xaml code. But in XF 2.3.4 Device.OS is obsolete. I removed XOnPlatform from my xaml code. I use OnPlatform in my xaml code.This is work. Bingo :)

Related

Unable to add MediaPlayerElement in XAML

I'm trying to use the Windows.Media.Playback MediaPlayer. I am attempting to follow the information here Play audio and video with MediaPlayer. I am able to hear the audio of a video by calling it from C#.
public MainPage()
{
InitializeComponent();
var mediaPlayer = new MediaPlayer();
mediaPlayer.Source = MediaSource.CreateFromUri(new Uri("https://sec.ch9.ms/ch9/5d93/a1eab4bf-3288-4faf-81c4-294402a85d93/XamarinShow_mid.mp4"));
mediaPlayer.Play();
}
However, when I attempt to add a MediaPlayerElement in XAML I get an 'MediaPlayerElement' cannot be added to a collection or dictionary of type 'IList'1'. error
<?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:controls="clr-namespace:Windows.UI.Xaml.Controls;assembly=Windows.Foundation.UniversalApiContract"
x:Class="XamarinTest.MainPage">
<StackLayout>
<controls:MediaPlayerElement x:Name="_mediaPlayerElement" AreTransportControlsEnabled="False" HorizontalAlignment="Stretch" Grid.Row="0"/>
</StackLayout>
</ContentPage>
If I remove the StackLayout and have the MediaPlayerElement directly in the Content I get a 'Content' does not support values of type 'MediaPlayerElement'.
I saw this question so I assume I'm missing some kind of DLL or reference but I am unable to locate what reference would be needed.
You are trying to apply UWP controls to a cross platform Xamarin Forms project
Windows.Media.Playback is only for Windows, and would not work on Android or iOS. There are techniques you can use to include platform specific controls in a Xamarin project, or you can use a cross-platform control like MediaElement

Xamarin.Forms Xaml background Image

I just started a Xamarin.Forms application and I want to add a background image to my XAML.
I added the attribute but it does not appear when I run it!!
Here is the images.
APP
public class App : Application
{
public App()
{
// The root page of your application
MainPage = new Page();
}
XAML:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="App1.Page"
BackgroundImage="bg.png">
SO, how do I fix it?
Add your bg.png file in each of your native projects, since you are currently using a Android emulator start with your Xamarin.Android project:
Android - Place images in the Resources/drawable directory with Build Action: AndroidResource
ref: https://developer.xamarin.com/guides/xamarin-forms/working-with/images/
Example: In your Xamarin.Android project, add bg.png as shown:
Check the Build Action of that image and ensure that it is assigned AndroidResource. Rebuild and re-test.
In Xamarin.forms
The images should be placed in the following folders
iOS, Android - Resources folder
Windows/UWP, Windows Phone - Assets folder
Then the build action(rt click img->properties) of the images should be changed as follows
iOS - BundleResource Windows Phone - Content
Android - AndroidResource Windows/UWP - Content
If Still the image is not displayed, try changing the Copy to Output Directory to Copy if newer in image Properties
If you want to add background image in XAML file for the entire page in Xamarin project, then use the BackgroundImage property and add your image to the Android project under Resources -> drawable folder and for iOS Resources folder.
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:PhoneDailerDemo"
x:Class="PhoneDailerDemo.MainPage"
BackgroundImage="image3.jpg">
<Label Text="Welcome to Xamarin Forms!"
VerticalOptions="Center"
HorizontalOptions="Center" />
<StackLayout Padding="100">
//..........
</StackLayout>
</ContentPage>
Reducing the size of the image worked for me.
Another way (source) you can achieve this, is by setting the image's build action (in file properties) as Embedded Resource.
Then, using a converter markup-extension you will be able to use it directly in XAML and won't have to copy or link the files in each platform specific project.
Here's the converter you should add to you portable project:
[ContentProperty(nameof(Source))]
public class ImageResourceExtension : IMarkupExtension
{
static readonly Assembly CurrentAssembly =
typeof(ImageResourceExtension).GetType().Assembly;
public const string Assets = nameof(Assets);
public string Source { get; set; }
public object ProvideValue(IServiceProvider serviceProvider)
{
if (string.IsNullOrWhiteSpace(Source))
return null;
// Do your translation lookup here, using whatever method you require
var source = $"{CurrentAssembly.GetName().Name}.{Assets}.{Source}";
var imageSource = ImageSource.FromResource(source, CurrentAssembly);
return imageSource;
}
}
Then in your 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:WorkingWithImages;assembly=WorkingWithImages"
x:Class="WorkingWithImages.EmbeddedImagesXaml">
<Image Source="{local:ImageResource Background.jpg}"}
</ContentPage>
Image files can be added to each application project and referenced from Xamarin.Forms shared code. To use a single image across all apps, the same filename must be used on every platform, and it should be a valid Android resource name (ie. only lowercase letters, numerals, the underscore, and the period are allowed).
iOS - Place images in the Resources folder with Build Action: BundleResource . Retina versions of the image should also be supplied - two and three times the resolution with a #2x or #3x suffixes on the filename before the file extension (eg. myimage#2x.png).
Android - Place images in the Resources/drawable directory with Build Action: AndroidResource. High- and low-DPI versions of an image can also be supplied (in appropriately named Resources subdirectories such as drawable-ldpi , drawable-hdpi , and drawable-xhdpi ).
Windows Phone - Place images in the application's root directory with Build Action: Content .
Windows/UWP - Place images in the application's root directory with Build Action: Content .
You can read more at Working with Images
Loading and displaying images in Xamarin.Forms

UWP + MvvmLight - ViewModelLocator defined as App.xaml resource is returning Access Denied error in Design Mode

I'm building UWP app with MVVMLight and I have problem with my ViewModelLocator in Design Mode.
I created ViewModelLocator:
public class ViewModelLocator
{
public MainPageViewModel Main =>ServiceLocator.Current.GetInstance<MainPageViewModel>();
static ViewModelLocator()
{
ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
SimpleIoc.Default.Register<MainPageViewModel>();
if (ViewModelBase.IsInDesignModeStatic)
{
SimpleIoc.Default.Register<IMainPageDataService, DesignMainPageDataService>();
}
else
{
SimpleIoc.Default.Register<IMainPageDataService, MainPageDataService>();
}
}
}
And then I declared it as App resource:
<Application.Resources>
<ResourceDictionary>
<viewModels:ViewModelLocator x:Key="Locator"></viewModels:ViewModelLocator>
</ResourceDictionary>
</Application.Resources>
It should work now and I should have possibility to define MainPageViewModel as MainPage DataContext but Intellisense is underlining
<viewModels:ViewModelLocator x:Key="Locator"></viewModels:ViewModelLocator>
with error
Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED))
I noticed that when I'm not using ViewModelBase.IsInDesignModeStatic property it works properly and I can see design data at MainPage.
Something like this works:
public class ViewModelLocator
{
public MainPageViewModel Main =>ServiceLocator.Current.GetInstance<MainPageViewModel>();
static ViewModelLocator()
{
ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
SimpleIoc.Default.Register<MainPageViewModel>();
SimpleIoc.Default.Register<IMainPageDataService, DesignMainPageDataService>();
}
}
Have you any ideas to resolve this weird problem?
Well... it was something wrong with my environment. I checked it on another machine and it works flawless.
I ran into this same issue and finally fixed it by using the native UWP Windows.ApplicationModel.DesignMode.DesignModeEnabled and now all is working well.
Additionally, I am in the process of switching to Prism, unclear if this is a VS/Blend issue, or an MVVMLight issue, but slowing finding more items I find easier to use and more robust about Prism 6, such as its Validation for example.

Download with Webview Windows 8

I'm really stuck with an issue. I would like to download a PDF/ZIP formatted file from webview but I can't find any solution/tutorial on the internet, I tried to look webview property class.
i have a webview:
WebView x:Name="webviewIntranet" Grid.Row="1" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />
and my method:
public IntranetPage()
{
webviewIntranet.Navigate(new Uri("http://www.testme.com"));
this.InitializeComponent();
}
I'm able to show the webpage content but nothing happens when a try to download/click to download some files.
First of all some reading about what's new in WebView control
http://blogs.windows.com/windows/b/appbuilder/archive/2013/07/17/what-s-new-in-webview-in-windows-8-1.aspx
as you can see, WebView hanldes different browser events:
It doesn't support showing nothing else than webpages, but WebView.UnviewableContentIdentified event is fired for them
http://msdn.microsoft.com/en-us/library/windows/apps/windows.ui.xaml.controls.webview.unviewablecontentidentified.aspx
Then you can use file association to throw it to the OS (or do what you need with the file throught the uri... i hope)
void webView1_UnviewableContentIdentified(WebView sender,
WebViewUnviewableContentIdentifiedEventArgs args)
{
Windows.Foundation.IAsyncOperation<bool> b =
Windows.System.Launcher.LaunchUriAsync(args.Uri);
}
WebView can't download file. Microsoft has tried not to be WebView, a replacement of IE browser. See the answer from MSDN forum.
I think you can do this, but there's quite a bit of manual intervention. Using something like the BackgroundDownloader you can download a file that you have the URI for. Is you want to also intercept web view navigation, then there's a few workarounds for that; for example: here

Dependency Injection in XAML (WPF)

I am creating a new WPF project and we use Microsoft Unity as DI.
I am having a user control which is calling a 3rd party service.
So now how to inject dependency from the main window XAML for the usercontrol.
You can use the service locator pattern. I use it with Unity as a DI.
internal class ServiceLocator
{
[...]
public MainViewModel Main { get { return container.Resolve<MainViewModel>(); } }
}
You can intantiate your class the way you want (DI or not, the class initializes the DI etc...).
In your App.xaml
<Application.Resources>
<vm:ServiceLocator x:Key="Locator"/>
</Application.Resources>
And now, you can set your datacontext
DataContext="{Binding Main, Source={StaticResource Locator}}"
Edit:
I found another way of doing it (among other):
Take a look at this article. In the command, you can resolve your viewmodel as you like.