How to rename a property in Xamarin Binding Library - c#

I'm trying to build an android binding library for LINE SDK (a SNS service popular in Asia area). I added the jar file from the SDK into my project but it fails to compile because the creators of the SDK just happen to use the same name for a class and its property.
This is part of the C# code that the project generated from the jar file
public partial class AccessToken : global::Java.Lang.Object {
// Metadata.xml XPath field reference: path="/api/package[#name='jp.line.android.sdk.model']/class[#name='AccessToken']/field[#name='accessToken']"
[Register ("accessToken")]
public string AccessToken {
get { /* ... */ }
set { /* ... */ }
}
//...
}
Now simply put, I want to know how I can rename this property "AccessToken". I tried adding some commands in Metadata.xml but it had no effect. Here's a line of what I've written for reference
<attr path="/api/package[#name='jp.line.android.sdk.model']/class[#name='AccessToken']/field[#name='accessToken']" name="propertyName">AccessTokenString</attr>
I'd be grateful if somebody could help me out. I'm totally lost here.

What #SuavePirate suggests will not work completely (at least not now).
If you use name it will also rename the Register attribute parameter as [Register ("AccessTokenString")] instead of [Register ("accessToken")]. So as it states here it will be no longer possible for the Xamarin.Android binding class to access that property because it is not bound to an existent Java member.
To properly change the managed name of a wrapped member, it is necessary to set the managedName attribute, i.e.:
<attr path="/api/package[#name='jp.line.android.sdk.model']/class[#name='AccessToken']/field[#name='accessToken']" name="managedName">AccessTokenString</attr>

I believe the only issue is that "propertyName" should just be "name":
<attr path="/api/package[#name='jp.line.android.sdk.model']/class[#name='AccessToken']/field[#name='accessToken']" name="name">AccessTokenString</attr>

Related

Xamarin Android error: <identifier> expected package #string

In my app I tried reducing the amount of places I needed to update a string name, so I added a string in the Resources/values/Strings.xml file, but when I tried to test my build I got a weird error that I coudnt find a solution on, and have no idea why its doing that.
Someone know anything about this?
heres the xml code:
<resources>
<string name="service_name">ITMNotificationService</string>
</resources>
Using it in a Service attribute:
[Service (Label = "#string/service_name"
, Name = "#string/service_name"
, Icon = "#drawable/ITMIcon"
)]
And the error in the console;
The Name parameter for the ServiceAttribute is defining the Java class name that will be used in the ACW that is generated at compile time.
Thus the literal string of #string/service_name can not be used for a Java class name as that is invalid. Typically this would be the fully-qualified class name that includes your package id, ie.
Name = "com.sushihangover.coolapp.mywickedservice"
You could define this via a C# const string, but not an Android resource-based string value.
Note: You do not need to define the Name and Xamarin will auto-generated one via an MD5 hash routine. You then use typeof instead of the Java class name when calling the StartService method.

Class cannot find another class in the same namespace

I have a C# WebApp that we are doing for a client. I have two classes in the project, defined (in separate files) as such...
A general utility library:
namespace Client.WebApp {
public static class General {
public static MyDbClass GetDB() {
//<creates and returns MyDbClass here>
}
}
}
A PageBase class:
namespace Client.WebApp {
public class PageBase : System.Web.UI.Page {
protected MyDbClass dbo { get; set; }
public PageBase() {
dbo = General.GetDB();
}
}
}
When I try to compile, I get the error from the dbo = General.GetDB(); line:
The name 'General' does not exist in the current context Client.WebApp.
I have double-checked that the namespace is spelled right in both files.
I have tried adding the top-level namespace Client.WebApp as a using directive in the pagebase file.
I have tried fully qualifying the name as in dbo = Client.WebApp.General.GetDB();
Nothing has helped and it insists that my General class does not exist.
Funny thing is that while the build hits this error and stops, the code-editor does not see this error, and the statement does not get red-under-squiggled.
The project is targeting Framework v.4.5.2, and I am working in VS 2015.
It is a strange error, in my VS2015 if I set a file Build Action to anything other than "Compile", I get an error underline on any type for that file.
Anyway the solution here is to verify that the Build Action is set to "Compile", I'm not sure why adding a new file would have set the build action to anything other than "Compile". I've also tested trying to add new files in multiple ways (select a text file template and just name it something.cs), it still sets it as "Compile". You should verify that your VS2015 instance is updated with the latest updates.
I had the same problem: "type or namespace could not be found". It turned out that class was in a file with the "Build Action" property set to "None", meaning the file was not being compiled. I set it to "C# Compiler", that solved it.
This happens to me sometimes. Closing visual studio and opening it again always fixes it for me.
I think I might have figure it out that if we create a file in a folder which suppose to have content files it set that file's build type content automatically. In my Case I create a file under app_code folder and it is a class file but the build type is set to Content which make it unavailable for any other classes i have.
May be it has any other reasons too.
Try to create a new Class in the Project folder and then move it to the folder, you want it to be.

MvvmCross - missing viewmodels parameters with Link all assemblies enabled

Trying to reduce an app size, I enabled 'Link all assemblies' option on my Xamarin.iOS app. Unfortunately, when I launch the app, passing simple view model parameters doesn't work. On the application output I can see the following warning:
mvx:Diagnostic: 1.93 Missing parameter for call to ViewModel - missing parameter isLaunchedForTheFirstTime - assuming null - this may fail for value types! mvx:Error: 1.94 Failed to parse BoolParser parameter isLaunchedForTheFirstTime from string
I have no idea what to add to LinkerPleaseInclude.cs to make it work. Any ideas?
Thanks in advance!
EDIT:
Here's my preserve.xml file which contains all referenced assemblies:
http://pastebin.com/cEmLDxqn
And my view model navigation:
ShowViewModel<FirstViewModel>(new {isLaunchedForTheFirstTime = true})
[ImplementPropertyChanged]
public class FirstViewModel : MvxViewModel
{
//properties
public void Init(bool isLaunchedForTheFirstTime)
{
//handling parameter
}
}
Not all the time the linker is smart enough to detect everything that you need for you project to run, especially if you're using DI or reflection. In these cases, you can configure it to include the assemblies/types or methods that it might've missed.

Invalid Resx file. Could not load type error why?

I'm getting designer error on code:
The Component i'm willing to define a List of properties for:
using System.Collections.Generic;
using System.ComponentModel;
using System.Windows.Forms;
namespace TestProjectForProperty.Test
{
public class MyTreeView : TreeView
{
private List<TypeDescriptorBase> _descriptorsAvailable = new List<TypeDescriptorBase>();
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public List<TypeDescriptorBase> DescriptorsAvailable
{
get { return _descriptorsAvailable; }
set { _descriptorsAvailable = value; }
}
}
}
The Descriptor itself:
using System;
namespace TestProjectForProperty.Test
{
[Serializable]
public class TypeDescriptorBase
{
public string Name { get; set; }
public override string ToString()
{
return Name;
}
}
}
I am getting the following error if i try to use the component for example on a form and add any items on the property sheet or in the component's constructor to the DescriptorsAvailable property
Error 1 Invalid Resx file. Could not load type
System.Collections.Generic.List`1[[TestProjectForProperty.Test.TypeDescriptorBase,
TestProjectForProperty, Version=1.0.0.0, Culture=neutral,
PublicKeyToken=null]], mscorlib, Version=4.0.0.0, Culture=neutral,
PublicKeyToken=b77a5c561934e089 which is used in the .RESX file.
Ensure that the necessary references have been added to your project.
Line 134, position 5. ...\visual studio
2010\Projects\TestProjectForProperty\TestProjectForProperty\Form1.resx 134 5 TestProjectForProperty
In the Resx file there is data field with base64 encoded stuff inside when this error is present.
I have been searching for an answer, but the best i got is to restart everything, it didn't help me, do you guys have any suggestions? I'm using .net 4 client and visual studio 2010
In my experience, this is due to a change of version of a referenced library, or a change of the lib itself, which contains the backing type of a property you have defined in your user control. The solution is to "force" the visual studio designer to re-initialize it's designer code for that type, and not expect to retrieve a "canned" version of it from the .resx file of the control.
1) Delete the offending data section in the .resx file of your control. This will be a section in the xml of the .resx file associated with your user control, which has a node: <data></data> - the name attribute will be set to whatever you've named that object in the properties of whatever you added this type to. The <data>/data> section contains a base64 encoded string that is the encoded form of the name and version of the library the type comes from. This is where the problem ism, because it now contains an encoded version of the library and/or version number you are no longer referencing in order to include the type. Delete the entire <data>/data> section, from opening to closing tag, save the change and close the file. Now the "artifact" is gone.
2) Now find the place in the designer file for your control, where the type is instantiated; this is initialization code generated for you by visual studio, and it is the place that is expecting to load a "canned" definition of the type from the base64 encoded string contained within the .resx file. The line will look something like this:
this.myCtrlFoo.MyPropertyFroo = ((MyNamespaceFoo.MyTypeFoo)(resources.GetObject("myCtrlFoo.MyPropertyFroo")));
...now just replace the resources.GetObjec call with the instantiation of a new instance of the appropriate type like so:
this.myCtrlFoo.MyPropertyFroo = ((MyNamespaceFoo.MyTypeFoo)(new MyNamespaceFoo.MyTypeFoo()));
...now save the change to the file, close it, rebuild, and everything should now build & run OK.
Put the MyTreeView and TypeDescriptorBase classes into another project and reference it from your GUI project will resolve the issues.
I'm not sure why exactly the problem occurs - I guess it has something to do with the way the serializing process is generating the base64 string for the DescriptorsAvailable Property. Maybe somebody else can give us some insight.
I've struggled quite a bit with this; I have three user controls that all expose the same non-designer property, but for some reason, any change to two of the three would instantly cause the next build to fail with this same issue. This is in VS 2015.
I wound up having to add the following two attributes to the property that kept expanding in the resx file, and it hasn't occurred since. It works for me because they're not available in the designer anyway.
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
For me, this error occured when I used a custom class as a property for the user control. When I switched from property to traditional get- and set- methods, the error disappeared. I guess this is because properties are already compiled at design-time, so when you build the whole project, a new version of the custom class is compiled which is separate from the one of the control, and the reference is broken.
For me, with the custom class Inventory, all I had to do was to switch from this property-based approach:
public Inventory Resources {get;set;}
to this method-based approach:
private Inventory resources;
public Inventory getResources() { return resources; }
public void setResources(Inventory newResources) { resources = newResources; }
I hope this helps someone, as I've been spending some hours on figuring it out.
In my case I've got the error : "error MSB3103: Invalid Resx file. The specified module could not be found" executed in a light windows container based on mcr.microsoft.com/powershell instead of mcr.microsoft.com/windows:1909 (was working fine on 1909).
The error was on a ressource icon that was compressed with PNG inside.
It can be checked by opening the ressource on visual studio : Project > Properties > Ressources.resx, select icons, double click on the icon, check the end of the title that is either "..,BMP]" or "...,PNG]").
Updating the icon with an uncompressed format solve the "Invalid Resx file" issue.
I stumbled across this question today whilst looking for the solution to a similar issue.
Unfortunately none of the above worked for me, however my issue turned out to be that I had different versions of the .NET Framework for different projects. For example;
Project A - .NET Framework 4.7.2
Project B - .NET Framework 4
Where Project B was referencing Project A. Solution was simply to change the .NET Framework version of Project B to 4.7.2 (in my case) and hey presto the issue was resolved.
A shame Visual Studio doesn't provide a more helpful error message in this case, but something to look out for!

sharing a static class with a DLL in C# without passing a reference

VS2012 for desktop .net framework 4.5 normal windows forms applications, not WPF
Hello, I tried to search for an answer, but I'm not sure of the correct terminology. I've managed to break my code, and can't understand what I've done wrong. (i didn't think i had changed anything, but ...)
I have a solution which contains 2 projects. The first project is an executable program, and the second is a DLL, which is loaded at run time and used by the first project.
the first project contains a form, and a static class with public static strings in the same namespace. (and some other unconnected classes). specifically:
namespace project1_namespace
{
static class settings
{
public static string some_words = "some words in a string";
}
class dll_callback{
//.. some public methods here
}
dll_callback dllcallback; // instance is initialised in the code (not shown)
Form form;
public partial class frm_splash : Form
{
private void frm_splash_FormClosing(object sender, FormClosingEventArgs e)
{
// this function actually loads the DLL, ensuring its the last step
//... some error checking code removed for brevity
Assembly assembly = Assembly.LoadFrom("c:\dllpath\project2.dll");
Type type_init = assembly.GetType("project2_class");
object init = Activator.CreateInstance(type_init, form, dllcallback);
//... some error checking code removed for brevity
}// end method
}// end form class
}// end namespace
when the form is closing, the method shown above is called which calls the second projects class project2_class constructor.
in project 2, the DLL, there is:
namespace project2_namespace
{
// how did i get this working to reference "settings" class from project 1??
public class project2_class
{
public project2_class(project2_namespace.Form1 form_ref, object callback)
{
settings.some_words = "the words have changed";
//... some more stuff
}
}
}
Now, i was experimenting with some code in an entirely different part of project2, and VS2012 suddenly started refusing to compile stating:
error CS0103: The name 'settings' does not exist in the current context
the standard solution to this appears to be to add a reference to project2, but that would create circular dependencies because project 1 calls 2 as a DLL.
I really honestly don't think i had changed anything relevant to this, but also clearly I have.
looking at it, i cant see how project 2 would have access to a class in project 1 without a reference, but the list of arguments to the project2_class constructor doesn't include one, and I am absolutely positive that it hasn't changed (and I cant change it for backwards compatibility reasons).
would really appreciate help with this, as its been a lot of work to get this working.
as a side note, I've definitely learned my lesson about not using source control. and not making "how this works" comments instead of "what this does" comments.
may dynamic help you? You can not get the setting string at complie time.

Categories

Resources