Xamarin ... migration to .NET Standard 2.0 failed - xamarin

I'm trying to migrate my PCL project to the new "net standard" but for now I failed.
Currently I got the following exception :
System.MissingMethodException: 'Method not found: 'Void Xamarin.Forms.Xaml.Internals.SimpleValueTargetProvider..ctor(System.Object[], System.Object, Xamarin.Forms.Internals.INameScope)'.'
It happend directly from the 'InitializeComponent' of a page where I have the following xaml tag:
<Image Source="{ns_uc:ImageResource i_home_on.png}"/>
where the 'ImageResource' is an extension marker, this one works like a charm in my PCL project. Here is a part of the definition :
public class ImageResourceExtension : IMarkupExtension
But this class is not called from my new .NET Standard project !
In the .csproj I have the following references, it should be enough ?
<PackageReference Include="System.ComponentModel" Version="4.3.0" />
<PackageReference Include="Xamarin.Forms" Version="3.4.0.1008975" />
So, if someone have an idea because I have already spend 2 days in this migration, without success :-(
BTW, it seems I'm not alone : https://forums.xamarin.com/discussion/101999/cant-use-imarkupextension-in-a-net-standard-library
Thanks for your help

1.System.ComponentModel is a NuGet package in some NetStandard versions.Try to install it if it doesn't exist.
2.You can use <Image Source="myImage.png"/> directly instead of using IMarkupExtension in .net standard project.
3.The implement of ImageResourceExtension maybe different in PCL project and .net standard 2.0 project. Here is an implement in official demo you can refer:
[ContentProperty("Source")]
class ImageResourceExtension : IMarkupExtension<ImageSource>
{
public string Source { set; get; }
public ImageSource ProvideValue(IServiceProvider serviceProvider)
{
if (String.IsNullOrEmpty(Source))
{
IXmlLineInfoProvider lineInfoProvider = serviceProvider.GetService(typeof(IXmlLineInfoProvider)) as IXmlLineInfoProvider;
IXmlLineInfo lineInfo = (lineInfoProvider != null) ? lineInfoProvider.XmlLineInfo : new XmlLineInfo();
throw new XamlParseException("ImageResourceExtension requires Source property to be set", lineInfo);
}
string assemblyName = GetType().GetTypeInfo().Assembly.GetName().Name;
return ImageSource.FromResource(assemblyName + "." + Source, typeof(ImageResourceExtension).GetTypeInfo().Assembly);
}
object IMarkupExtension.ProvideValue(IServiceProvider serviceProvider)
{
return (this as IMarkupExtension<ImageSource>).ProvideValue(serviceProvider);
}
}
You can refer the demo below to fix your project.
Refer:Demo of ImageResourceExtension
Documents of Markup Extensions

I would follow James Montemagno's steps:
https://montemagno.com/how-to-convert-a-pcl-library-to-net-standard-and-keep-git-history/
I followed this video from the Xamarin show:
https://channel9.msdn.com/Shows/XamarinShow/Snack-Pack-15-Upgrading-to-XamarinForms-to-NET-Standard
I tried it on my own the first go around and failed miserably. The second go around I followed the instructions from the video exactly and everything worked.

Related

Using self created dll in Xamarin.Forms showing white screen on device

I am trying to create and use a DLL in Xamarin.Forms Project. This is given in the Charles Petzold's book 'Creating Mobile Apps using Xamarin.Form'.
It gives the following method to access the library that I have created
"From the PCL project of your application solution, add a reference to the library PCL assembly which is the dynamic-link library generated from the library project"
My library project is this
FILE: HslColorExtension.cs
using System;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
namespace Xamarin.FormsBook.Toolkit
{
public static class Toolkit
{
public static void Init()
{
}
}
public class HslColorExtension : IMarkupExtension
{
public HslColorExtension()
{
}
public double H { set; get; }
public double S { set; get; }
public double L { set; get; }
public double A { set; get; }
public object ProvideValue(IServiceProvider servicePRovider)
{
return Color.FromHsla(H, S, L, A);
}
}
}
THE actual project is CustomExtensionDemo
In that the MainPage.xaml is
<?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:toolkit="clr-namespace:Xamarin.FormsBook.Toolkit;assemby=Xamarin.FormsBook.Toolkit"
x:Class="CustomExtensionDemo.MainPage">
<StackLayout>
<Label Text="UTKARSH">
<Label.BackgroundColor>
<toolkit:HslColorExtension H="0" S="1" L="0.5"/>
</Label.BackgroundColor>
</Label>
</StackLayout>
</ContentPage>
THE METHOD HOW I ADDED THE DLL TO THE APPLICATION
FROM THE LIBRARY IS TOOK THE PATH THAT GENERATED THE DLL
C:\Users\admin\Desktop\Xamarin.FormsBook.Toolkit\Xamarin.FormsBook.Toolkit\obj\Debug
The name of the DLL is
Xamarin.FormsBook.Toolkit.dll
I added the reference to the actual project. browsed the path to
C:\Users\admin\Desktop\Xamarin.FormsBook.Toolkit\Xamarin.FormsBook.Toolkit\obj\Debug
and added the DLL : Xamarin.FormsBook.Toolkit.dll
Everything compiled correctly But I am getting a complete white screen on the Android Phone I am having .
POINTS:
1. I have set MainPage.xaml as the MainPage in the App.xaml.cs.. I have tried to put Label without the property element syntax and that worked.
I have not checked on iOS I think that there it would have the same problem as the problem could be in method of using the DLL in the application.
IDE:VS 2017
THE ERROR THAT IS DISCUSSED IN THE BELOW DISCUSSION
NOW I REQUIRE SOME WAY TO REMOVE THE "Windows Phone Silverlight 8.1" AND IT DOES NOT GIVE OPTION TO REMOVE THAT.
I'm fairly certain your problem is incompatible targets of your PCL.
Instead of adding the reference by browsing for the DLL, add it by selecting the project. This approach will check for compatibility of the DLL. Most likely you will need to change targets, fool around with nuget, etc.
Secondly I would recommend that your first platform for testing be UWP. There seems to be much better diagnostics on UWP. When I tried your code, I got the white screen on Android, but when using UWP as a platform I got an exception that said the HslColorExtension could not be found in the DLL.
If you follow these steps it should work for you:
You mis-spelled assembly as "assemby" in your XAML.
xmlns:toolkit="clr-namespace:Xamarin.FormsBook.Toolkit;assemby=Xamarin.FormsBook.Toolkit"
To make sure we're starting clean, let's just create a fresh Xamarin.FormsBook.Toolkit project and get rid of the one you've been using:
a) Copy out the code that you've already written so you don't lose it.
b) Create a new Xamarin.FormsBook.Toolkit project and only target those platforms that you would feasibly use this toolkit in. For example you would never use this in Silverlight because you're going to be referencing IMarkupExtension which is specific to Xamarin Forms.
c) Add a reference to your Toolkit project from your Xamarin Forms PCL project (looks like you're calling that "CustomExtensionDemo"). Don't reference the .dll but rather the project itself. This will spare you other headaches down the road.
d) Copy your HslColorExtension file (and any other classes you have) back in to the new project.
e) Add the Xamarin.Forms Nuget package to your Xamarin.FormsBook.Toolkit PCL, and a "using Xamarin.Forms" line at the top of your HslColorExtension file so that it recognizes the IMarkupExtension interface.
Add an empty Init function (or call it whatever you want) to your HslColorExtension class and then call it from your App.xaml.cs. This has the effect of "waking the compiler/linker up" to the fact that you have an assembly reference in XAML, since XAML is loaded at runtime. It does seem a bit hokey to have to do this, but you can tuck away that ugliness in your App.xaml.cs and you never have to see it again. If you're curious and want to see what's going on, try running it both with and without the call to Init, and take a look at your Android project's bin/Debug folder. When you call Init you'll see your Xamarin.FormsBook.Toolkit.dll appear in that folder. When you don't call Init it doesn't pull your assembly in. That's the core issue here.
Your resulting markup extension code would look like this:
public class HslColorExtension : IMarkupExtension
{
public static void Init()
{
}
public double H { set; get; }
public double S { set; get; }
public double L { set; get; }
public double A { set; get; }
public object ProvideValue(IServiceProvider serviceProvider)
{
return Color.FromHsla(H, S, L, A);
}
}
And your App.xaml.cs like this:
public partial class App : Application
{
public App()
{
HslColorExtension.Init();
InitializeComponent();
MainPage = new MainPage();
}
...
}
If that doesn't solve it for you, let me know! :-)

Difficulties with using Flashlight/Torch in Xamarin.Forms (Xamarin.Android) Project

Problem
Errors and Exceptions when trying to Turn on flashlight/Torch on an Android device using Xamarin.Forms (Xamarin.Android project) app.
Please see the below code' comments for the errors and exceptions mentioned:
// Get CameraService - This works fine and gets the CameraService
CameraManager CamMgr = (CameraManager) Application.Context.GetSystemService(Context.CameraService);
// Get Cameras - This Returns 0 strings, eg. NULL, it should return id 0 and 1 for respectively back and front camera
string[] CamIdList = CamMgr.GetCameraIdList();
// Turn ON Camera Torch(Flashlight) on camera id 0 - This results in the exception: Unhandled Exception: Java.Lang.NoSuchMethodError: no method with name='setTorchMode' signature='(Ljava/lang/String;Z)V' in class Landroid/hardware/camera2/CameraManager;
CamMgr.SetTorchMode("0", true);
// Turn ON Camera Torch(Flashlight) on camera id 1 - This results in the exception: Unhandled Exception: Java.Lang.NoSuchMethodError: no method with name='setTorchMode' signature='(Ljava/lang/String;Z)V' in class Landroid/hardware/camera2/CameraManager;
CamMgr.SetTorchMode("1", true);
Android Manifest permissions:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:installLocation="auto">
<uses-sdk android:minSdkVersion="15" android:targetSdkVersion="19" />
<uses-permission android:name="android.permission.FLASHLIGHT" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />
<uses-feature android:name="android.hardware.camera.flash" />
<application android:label="Lommelygte.Android"></application>
</manifest>
Platform and Developing environment
I am using Visual Studio Community 2017 15.0.0-RTW+26228.4 version as IDE.
I am using Android namespace (Xamarin assembly): Android.Hardware.Camera2 to use Flashlight functionality.
My Xamarin.Forms Project is using PCL (Portable Class Library) for sharing code.
I am not using Xamarin.Forms Pre release nuget packages or libraries.
I am using Xamarin.Forms (Xamarin.Android project)
I am using Device Samsung Galaxy Note 2 LTE (GT7105) - Android 4.4.2 (Kitkat) - API Level 19 (has Camera flash functionality) to debug application on.
What I have tried to resolve the problem:
Installed Android API 19 SDK
Cleaned Project, Then cleaned Solution, then Rebuild Solution
Checked for new Xamarin.Forms stable release
Tried using decrecated API 21 namespace + class instead for flash: Android.Hardware.Camera.Open();
Researched Xamarin Documentation
Researhed Stackoverflow posts
Researched various blogs and other places
Changed Target Framework to the exact API 19 that my phone supports: 4.4.2 (kitkat)
Researched implementations in Java, to get an overview of how it natively is done.
Looked at the definition of the Android.Hardware.Camera2 namespace and verified that the SetTorchMode method exists there, as displayed here (I am sorry for the majority of the code not being presented correctly in a codeblock, having some trouble with that):
Assembly Mono.Android, Version=0.0.0.0, Culture=neutral, PublicKeyToken=84e04ff9cfb79065
using System;
using Android.OS;
using Android.Runtime;
using Java.Interop;
using Java.Lang;
namespace Android.Hardware.Camera2
{
[Register("android/hardware/camera2/CameraManager", DoNotGenerateAcw = true, ApiSince = 21)]
public sealed class CameraManager : Java.Lang.Object
{
public override JniPeerMembers JniPeerMembers { get; }
protected override IntPtr ThresholdClass { get; }
protected override Type ThresholdType { get; }
[Register("getCameraCharacteristics", "(Ljava/lang/String;)Landroid/hardware/camera2/CameraCharacteristics;", "")]
public CameraCharacteristics GetCameraCharacteristics(string cameraId);
[Register("getCameraIdList", "()[Ljava/lang/String;", "")]
public string[] GetCameraIdList();
[Register("registerAvailabilityCallback", "(Landroid/hardware/camera2/CameraManager$AvailabilityCallback;Landroid/os/Handler;)V", "")]
public void RegisterAvailabilityCallback(AvailabilityCallback callback, Handler handler);
[Register("setTorchMode", "(Ljava/lang/String;Z)V", "", ApiSince = 23)]
public void SetTorchMode(string cameraId, bool enabled);
What I have not done yet
....
Hypothesis
I am suspecting that the Xamarin assembly that handles the Android.Hardware.Camera2 does not interface correctly with all the methods of the java implementation of the namespace, in particular the Class: Camera, Method: setTorchMode.
However I cant find a new stable Xamarin version that might solve the problem.
I also suspect that because the definition says API since 23 that the code won't work at runtime on my device, because it does not support API 23 and the definition seems to require it, so how do I get around this?
This is the exact register for the definition of said method:
[Register("setTorchMode", "(Ljava/lang/String;Z)V", "", ApiSince = 23)]
How can I solve this?
Do you need more information to help me figure out the issue?
Your phone is API 19, CameraManager was added in API 21 and CameraManager.setTorchMode was added in API 23. Thus, those methods can not be called when running on that phone.
You can perform runtime checks to determine which API levels to use:
if (Build.VERSION.SdkInt <= BuildVersionCodes.KitkatWatch)
{
if (PackageManager.HasSystemFeature("FEATURE_CAMERA_FLASH"))
{
camera = Camera.Open(); // `Camera camera` variable is held as the class level
var camParameters = camera.GetParameters();
camParameters.FlashMode = "FLASH_MODE_TORCH";
camera.SetParameters(camParameters);
camera.StartPreview(); // Turn on
//When done with flashlight:
//camera.StopPreview(); // Turn off
//camera.Dispose();
}
else
Log.Debug("SO", "Phone does not contain a flash....");
}
else
{
// Use API 21+ methods...
}
Note: Many phones that have a "torch" mode but are older than API 21, require a SurfaceView to be used so the camera will function properly and thus allow the flash to function. Add a SurfaceView to your UI, get a SurfaceHolder from it and attach the camera to it (camera.SetPreviewDisplay)

The type or namespace name 'Page' could not be found in Xamarin Studio

I'm working on Xamarin Studio and beginner in it. I'm making cross platform app using Forms. ut the basic project gives this error when i build it "Error CS0246: The type or namespace name 'Page' could not be found (are you missing a using directive or an assembly reference?)" Please help me if someone know the answer.here is the code of app.cs:
using System;
using Xamarin.Forms;
namespace CrossPlatformAppForms
{
public class App
{
public static Page GetMainPage () //This is the line where i'm getting the error
{
return new ContentPage {
Content = new Label {
Text = "Hello, Forms !",
VerticalOptions = LayoutOptions.CenterAndExpand,
HorizontalOptions = LayoutOptions.CenterAndExpand,
},
};
}
}
}
One more thing in MyApp.Android i'm getting a warning of incompatible target framework(.Net framework 4.5...)
Its not a duplicate of The type or namespace name 'Xamarin' missing in xamarin studio (the solution to solve the problem in the link is by adding Xarmin.Forms.Addin.dll in the reference), but I'am currently facing this problem in my Xamarin Studio as well, and I think its related to .NET 4.5 framework compatibility.

Entity Framework Designer Extension Not loading

I created a small extension for the EF designer that adds a new property to the property window. I did this using a vsix project (new project -> c# -> extensibility -> vsix project). When I hit F5 the experimental VS instance starts up. I create a new project, add an entity data model and add an entity. However, my break points never get hit and I don't see the property. Any ideas as to what I might be doing wrong?
public class AggregateRootValue
{
internal static XName AggregateRootElementName = XName.Get("AggregateRoot", "http://efex");
private readonly XElement _property;
private readonly PropertyExtensionContext _context;
public AggregateRootValue(XElement parent, PropertyExtensionContext context)
{
_property = parent;
_context = context;
}
[DisplayName("Aggregate Root")]
[Description("Determines if an entity is an Aggregate Root")]
[Category("Extensions")]
[DefaultValue(true)]
public string AggregateRoot
{
get
{
XElement child = _property.Element(AggregateRootElementName);
return (child == null) ? bool.TrueString : child.Value;
}
set
{
using (EntityDesignerChangeScope scope = _context.CreateChangeScope("Set AggregateRoot"))
{
var element = _property.Element(AggregateRootElementName);
if (element == null)
_property.Add(new XElement(AggregateRootElementName, value));
else
element.SetValue(value);
scope.Complete();
}
}
}
}
[Export(typeof(IEntityDesignerExtendedProperty))]
[EntityDesignerExtendedProperty(EntityDesignerSelection.ConceptualModelEntityType)]
public class AggregateRootFactory : IEntityDesignerExtendedProperty
{
public object CreateProperty(XElement element, PropertyExtensionContext context)
{
var edmXName = XName.Get("Key", "http://schemas.microsoft.com/ado/2008/09/edm");
var keys = element.Parent.Element(edmXName).Elements().Select(e => e.Attribute("Name").Value);
if (keys.Contains(element.Attribute("Name").Value))
return new AggregateRootValue(element, context);
return null;
}
}
EDIT: I put the code on Github: https://github.com/devlife/Sandbox
EDIT: After Adding the MEF component to the manifest as suggested, the extension still never loads. Here is a picture of the manifest:
So the answer, as it turns out, is in how I setup my project. I put both classes inside the project which produces the VSIX file. By simply moving those classes into another project and setting that project as the MEF Component in the manifest (and thus copying the assembly) it worked like a charm!
For VS2012, it is only needed to add Solution as MEF component also. Just add whole solution as MEF component also.
Then it works surprisingly fine.
It seems the dll built by your project isn't automatically included in the generated VSIX package, and VS2013 doesn't give you options through the IDE to change this (that I can work out, anyway).
You have to manually open the project file and alter the XML. The property to change is IncludeAssemblyInVSIXContainer.
Seen here: How to include VSIX output in it's package?

How to encapsulate User Setting (Options Page) in Visual Studio 2010 AddIn

I'm currently developping a Visual Studio Extension and I have a question about Options Page. Options Page allows user to save setting about your Extension. Visual Studio handle a lot of work for us.
I created the Options Page.
public class VisualStudioParameter : DialogPage
{
private string _tfsServerUrl = DefaultParameter.TfsServerUrl;
[Category("TFS Parameters")]
[DisplayName(#"Server Name")]
[Description("The URL of your TFS Server")]
public string TfsServerUrl
{
get { return _tfsServerUrl; }
set { _tfsServerUrl = value; }
}
}
First, I created a method in the Visual Studio Package to acces to the Options Page.
Okay so now, from my Package, I can easily acces to the settings.
partial class SpecFlowTfsLinkerExtensionPackage : Package : IParameter
{
....
....
public string GetTfsServerUrl()
{
return ((VisualStudioParameter) GetDialogPage(typeof (VisualStudioParameter))).TfsServerUrl;
}
}
Now, I want to be able, in another library (Another project, included in the VSIX Package), to get easily these values. I don't want to reference the Visual Studio AddIn Package in my library.
I also have Unit Test so I'm going to create an Interface. During Unit Test, I going to Mock the object.
public interface IParameter
{
string GetTfsServerUrl();
}
Do you have any idea about how I can develop a clean solution to get these parameters from another assembly ?
Do you think the better solution is to inject the AddIn dependency in my library ?
If you already developed a Visual Studio Extension, How did you encapsulated the user setting from your core assembly ?
Thanks a lot.
You can try something like that:
// Access DTE infrastructure
EnvDTE.DTE dte = Microsoft.VisualStudio.Shell.Package.GetGlobalService(typeof(EnvDTE.DTE)) as EnvDTE.DTE;
// Access options page
var props = dte.get_Properties(#"Your Extension", "General");
var pathProperty = props.Item("TfsServerUrl");
path = pathProperty.Value as string;

Resources