Xamarin Forms.Xaml.XamlParseException - c#

I am creating a xamarin behaviour to validate an email id, therefore I created the behaviour file and tried to localise it in XAML file but I get the below error
Xamarin.Forms.Xaml.XamlParseException: Position 12:10. Type
local:EmailBhvr not found in xmlns
clr-namespace:Validation.Helpers;assembly=Validation.Helpers
Namespace: Validation
Behaviour Code File: EmailBhvr
Here is my XAML code:
<? 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:Validation;assembly=Validation"
x:Class="Validation.WelcomePage">
<StackLayout>
<Label Text = "Hello Xamarin" />
< Entry Placeholder="Enter your full name" x:Name="myName">
<Entry.Behaviors>
<local:EmailBhvr />
</Entry.Behaviors>
</Entry>
<Entry Placeholder = "Enter your email" x:Name="myEmail" />
<Entry Placeholder = "Enter password" x:Name="myPassword" IsPassword="True" />
<Entry Placeholder = "Confirm password" x:Name="myConfirmPassword" IsPassword="True" />
<Button Text = "Save" x:Name="SaveRegistration"/>
</StackLayout>
</ContentPage>

This could be related to a known linking issue - where Xamarin compiler ends up linking out classes (from external assemblies) that have references only in XAML.
Looks like EmailBhvr might be getting linked out by the compiler. There are couple of links that talk about this:
Extending Control plugins > Getting Started
Force assembly linking
There are a lot of options to resolve this:
Add a static Init method in each class as mentioned here in "Getting started" section here
// this ensures the class does not get
// linked out in the application we add this assembly to.
public static void Init() { }
Or, preserve code using preserve attributes on Android, and iOS
public class Example
{
[Android.Runtime.Preserve]
public Example ()
{
}
}
Or, use Custom linking.
Or, update project configuration to not link. Android, and iOS. Not a recommended option though.

I feel your XAML is clean. Looks error free. I think the problem is with the EmailBhvrclass in Validation. I suggest you to verify it. Make sure that the assembly name in XAML is also correct. XamlParseException can also occur with the incorrect assembly name..

I think you made some mistake while writing tags/property names in your EmailBhvr file.
Because of that you are getting parsing exception.

For the import to work, the class EmailBhvr must
be named "EmailBhvr"
reside in an assembly with an assembly name "Validation".
reside in the namespace "Validation" (check your class file)
Be especially careful with 2.:
If you use a shared Project the assembly name will be that of the platform project (e.g. it could be Validation.Droid / Validation.iOS). That can be fixed be giving both the same Assembly name (in project properties). For example "Validation.Platform" and change the xaml namespace import accordingly

Please Make sure that the assembly name in XAML is correct. it should be like this xmlns:local="clr-namespace:ProjectNamspace.Validation;assembly=ProjectNamspace.Validation"

Related

.NET MAUI InitialiseComponent doesn't exist [duplicate]

I've attempted to start playing with .Net MAUI and I've setup my development environment following the steps as described in:
https://learn.microsoft.com/en-us/dotnet/maui/get-started/first-app?pivots=windows
https://learn.microsoft.com/en-us/windows/apps/project-reunion/set-up-your-development-environment#required-workloads-and-components
https://learn.microsoft.com/en-us/xamarin/android/get-started/installation/android-emulator/device-manager?tabs=windows&pivots=windows
I've also run the 'maui-check' CLI tool and everything checks out, but when I create a new .NET MAUI App with Visual Studio 2019 v16.11.0 Preview 2.0 (running on Windows 10 Home 20H2), I get the 'The name 'InitializeComponent' does not exist in the current context' build errors. It also doesn't find the references to any controls on the form e.g. 'The name 'CounterLabel' does not exist in the current context'
I've tried almost everything in this post The name 'InitializeComponent' does not exist in the current context which contains suggestions like adding and removing files, making changes and changing them back... basically everything except throwing a penny in a wishing well.
I found that a common mistake is a namespace mismatch, but here is what I have showing that the namespaces are correct:
App.xaml:
<Application xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:MauiApp1"
x:Class="MauiApp1.App">
...
</Application>
App.xaml.cs
using Microsoft.Maui;
using Microsoft.Maui.Controls;
using Microsoft.Maui.Controls.PlatformConfiguration.WindowsSpecific;
using System;
using Application = Microsoft.Maui.Controls.Application;
namespace MauiApp1
{
public partial class App : Application
{
public App()
{
InitializeComponent(); <-- This is throwing the build error...
}
protected override IWindow CreateWindow(IActivationState activationState)
{
this.On<Microsoft.Maui.Controls.PlatformConfiguration.Windows>()
.SetImageDirectory("Assets");
return new Microsoft.Maui.Controls.Window(new MainPage());
}
}
}
MainPage.xaml:
ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MauiApp1.MainPage"
BackgroundColor="{DynamicResource PageBackgroundColor}">
...
</ContentPage>
MainPage.xaml.cs
using System;
using Microsoft.Maui.Controls;
namespace MauiApp1
{
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent(); <-- This is throwing the build error...
}
int count = 0;
private void OnCounterClicked(object sender, EventArgs e)
{
count++;
CounterLabel.Text = $"Current count: {count}"; <-- This is throwing the build error...
}
}
}
Any help will be greatly appreciated!
---=== UPDATE ===---
The path to the project I created is c:\develop\c#...... as soon as I copy the project to a folder that doesn't contain 'c#' it works. This clearly causes some parsing in the background to fail.
I faced the same issue and looks like when I created a ContentPage in VS its still pointing to Xamarin Forms. After changing namespace to MAUI, I updated the Build Action(RightClick on Xaml Page>>Properties>>BuildAction) of XAML Page to MauiXaml and it worked for me.
Close VS2022
Open VS2022
Open project with menu VS2022(File - Open - Project...)
What caused it for me was that I had renamed the xaml and xaml.cs file something else but I hadn't updated it in the ContentPage node in the xaml under x:Class
The same error popped in for me being an absolute beginner and missing the ending '>' in the XAML file. So, It could also be XAML errors, which leads to this error.
The path to the project I created is c:\develop\c#...... as soon as I copy the project to a folder that doesn't contain 'c#' it works. This clearly causes some parsing in the background to fail.
A very simple answer but has happened to me a few times.
Make sure you are using the preview version of VS 2022. It is very easy to accidently open up any other version of VS, which will cause the error to occur.
I have found a workaround for this problem. I am a newbie to c# and especially to .net Maui therefore, my apologies if I misinterpreted things differently.
First things first The error is about the context that the InitializeComponent() resides in. Context is nothing but the nuget package dependency that the file is looking for.
To change the context
Open the .cs file and at the top of the editor click the navigation bar as shown in the
Image
Change the context to Windows specific dependency from the list.
And also the other workaround would be to change the build action of the xaml file to MauiXaml as others mentioned
I'm using VS 2022 Preview 17.4.0 Preview 1.0, I don't know why but when you create a new Content Page it creates with the wrong namespace. take a look in the C# file and fix the namespace. It worked for me.
I am using preview version of 17.5 VS2022, I add to do below changes to run the app after adding new page.
*.Xmal Build Action -> BundleResource
*.Xmal.cs Build Action -> Compile

"The name does not exist in the namespace error" in XAML

I know this is a recurring error but I can't seem to get around it.
Intellisense does recognize the name of my custom control and suggests to add the proper using: directives, but not only XAML designer doesn't find the name of the control but I can't get through compilation either.
The custom control is a public class defined as
namespace MyApp.CustomControls
{
public class CustomTextBox : TexBox
{
...
}
}
And in my MainPage.xaml
<Page ...
xmlns:customControls="using:MyApp.CustomControls">
...
<customControls:CustomTextBox/>
...
</Page>
This does not render in design nor compile.
This answer and the ones below are not working for me.
The error message:
Error XDG0008 The name "CustomTextBox" does not exist in the namespace "using:MyApp.CustomControls".
Your code should works well after you build the project, and it works well in my side using your above code. Try to clean your solution or delete the bin and obj folders in your project then rebuild your app again. Also try to restart your Visual Studio. If it still happens, you can provide a reproducible sample to help me look into this issue.
I've seen quite a lot solutions saying that you should rebuild the project, restart Visual Studio or restart the machine.
What worked for me was specifying the assembly in the namespace reference, that is:
xmlns:the_namespace="clr-namespace:the_namespace" - produces the above error.
xmlns:the_namespace="clr-namespace:the_namespace;assembly=the_assembly" - works well.
I got a version of this error in my embedded UserControl when I tried to use the Name property in my XAML instead of using x:Name. In other words, when my XAML code looked like this:
myUserControls="using:MyUserControls"
<myUserControls:GraphCanvas Name="GraphCanvas" />
I got an error that 'The name "GraphCanvas" does not exist in the namespace "using:MyUserControls"'. When I changed one line of code to this:
<myUserControls:GraphCanvas x:Name="GraphCanvas" />
Everything built just fine.
I'm dropping this solution here because it took me about a day and a half to figure out this problem and this was the only stackoverflow page I found when I searched the error string. Hopefully I will save someone else the hassle I went through.

uwp app has dynamic variables, which causes the app to crash in release mode

in my uwp app I am using dynamic variables at many places, because the data is coming from the server backend api, so we want to keep it dynamic. it runs fine in Debug mode but I wanted to upload to store so I tried it on Release mode and it fails with following exception
system.reflection.missingmetadataexception
obviously this exception occurs, in one of my pages called "LoginPage.xaml.cs" at the first line where I am trying to use the dynamic data. following is the line which causes the exception.
ViewModel.backgroundURL = AppConfig.Login.background;
AppConfig here is a static object in a constants class. and its type is dynamic, I am succesfully get it from server API, but exception only occurs when I try to consume it in my app as you can see in the code line above.
after some research I found that using the following line in Default.rd.xml can solve this error I put the following line there.
<Namespace Name="bluebook.ViewModels" Seralize="All" />
as you can see I am putting this line in my directives tag as shown below.
<Directives xmlns="http://schemas.microsoft.com/netfx/2013/01/metadata">
<Application>
<!--
An Assembly element with Name="*Application*" applies to all assemblies in
the application package. The asterisks are not wildcards.
-->
<Assembly Name="*Application*" Dynamic="Required All" />
<!-- Add your application specific runtime directives here. -->
<Namespace Name="bluebook.ViewModels" Serialize="All" />
</Application>
</Directives>
I am trying to do the directives on ViewModels because the fields I am assigning to are in the ViewModel class. I also tried to do it on Views name space which has all the view classes like LoginPage and others, but in both cases the exception is still occuring, exactly at the same line.
Update 1
Exception Details
System.Reflection.MissingMetadataException: 'Reflection_InsufficientMetadata_NoHelpAvailable: EETypeRva:0x000a8990.
StackTrace : null
Source : null
Is "Serialize" misspelled in your directive file?
Try adding <Type Name="Microsoft.CSharp.RuntimeBinder.CSharpGetMemberBinder" Dynamic="Required All"/> to your Default.rd.xml.
(This answer may be relevant to you - answered by someone who works on .Net Native - Building with .NET Native tool chain causes error with missing property in dynamic object )

View doesn't find ViewModel in different Assembly

I am starting a new project and oriented my projectstructure on the structure recommended in this question.
Now I am seeing strange behaviour. When I am setting the datacontext in the View-XAML, it isn't found at runtime (getting a XamlParseException). When I set it in the constructor in the codebehind-file, everything is working just fine.
Is this official (documented) behaviour when using different assemblies, or am I doing something wrong?
The code:
Not Working:
MainView.xaml:
<UserControl x:Class="ViewsRoot.Views.MainView"
xmlns:baseControls="clr-namespace:BaseControls;assembly=BaseControls"
xmlns:viewModels="clr-namespace:ViewModelsRoot;assembly=ViewModelsRoot">
<UserControl.DataContext>
<viewModels:ShellViewModel />
</UserControl.DataContext>
MainView.xaml.cs
public MainView()
{
InitializeComponent();
// No DataContext set in codebehind-file
}
Working:
MainView.xaml:
<UserControl x:Class="ViewsRoot.Views.MainView"
xmlns:baseControls="clr-namespace:BaseControls;assembly=BaseControls"
xmlns:viewModels="clr-namespace:ViewModelsRoot;assembly=ViewModelsRoot">
<!--<UserControl.DataContext>
<viewModels:ShellViewModel />
</UserControl.DataContext> -->
MainView.xaml.cs:
public MainView()
{
InitializeComponent();
DataContext = new ViewModelsRoot.ShellViewModel();
}
Update:
The Exception-Text is:
{"The file or assembly \" ViewModelsRoot, PublicKeyToken = null \ "or one of its dependencies was not found. The system can not find the file specified."}
And the only inner Exception I can see is a System.IO.FileNotFoundException.
Update 2:
Thanks for the comments, but I haven't forgotten a namespace. I shortened it here for showing the code, but I double- and triplechecked (again). The DataContexts namespace is also filled in by intellisense. The whole <viewModels:ShellViewModel /> is written by intelli-sense. So it is found at designtime... ...so any more ideas?
Update 3:
The xaml is "correctly" parsed as I am able to bind the DataContext to a class in the same assembly.
I have reproduced this error using a three project solution, with the specified dependencies between them:
StartupProject → ViewsRoot
ViewsRoot → ViewModelsRoot
ViewModelsRoot
"StartupProject" has "exe" output type, while the other two have "dll".
In my case, I solved the problem by adding "ViewModelsRoot" to the References list of "StartupProject". It is not a coding problem, but rather a runtime problem, because "ViewModelsRoot.dll" is not copied to "StartupProject" output folder.
When you specify the DataContext in code-behind, Visual Studio notices the need for that "dll" and adds it to the output after compilation. This doesn't happen when setting the DataContext from XAML. It is tricky because "ViewModelsRoot" code is used from XAML with Reflection. Adding it to References list forces Visual Studio to copy the "dll" in both cases.
You can also copy "ViewModelsRoot.dll" to the output folder directly, but it will not be updated when you change the code.
I've often found this error when the project target framework was set to "Client Profile" (this was set by default on VS2010, IIRC), if this is the case, try changing it to 3.5 or 4.0.

Making WPF navigation dynamic - using an XML file?

I'm working on the navigation part of a desktop application, and have a bit of a problem. The request is that the navigation should be dynamic, so that you can, for instance, switch orders of the views without having to recompile (and ideally also adding a view without recompiling).
Currently I'm using an XML to define which windows to display, which header it should have and how the footer should look like. Here's how the XML looks now:
<?xml version="1.0" encoding="utf-8" ?>
<ArrayOfViewState xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<ViewState ViewName="WelcomeView" Header="Welcome to the Application" FooterButton1="Quit" FooterButton2="Back" FooterButton3="Next" />
<ViewState ViewName="LicenseView" Header="Licence Agreement" FooterButton1="Quit" FooterButton2="Back" FooterButton3="Next" />
<ViewState ViewName="LoginView" Header="Log in" FooterButton1="Quit" FooterButton2="Back" FooterButton3="Next" />
<ViewState ViewName="InstallationView" Header="Installing..." FooterButton1="Cancel" FooterButton2="None" FooterButton3="Next" />
<ViewState ViewName="UpdateView" Header="Updating..." FooterButton1="Cancel" FooterButton2="None" FooterButton3="Next" />
<ViewState ViewName="FinishedView" Header="Finished!" FooterButton1="None" FooterButton2="None" FooterButton3="Finish" />
</ArrayOfViewState>
And when I match this in the code it looks like this (viewState.View is of type UserControl):
...
case "WelcomeView":
viewState.View = new WelcomeView();
...
As you can see I use the ViewName property in the XML to match and create my views (they also have a ViewModel, but that is taken care through XAML and the MVVM Light ViewModel Locator).
This solution technically allows the navigation to be changed somewhat without recompiling (for example you can shuffle the order any way you like), but there must be a better way to handle this than matching a string property. I've tried looking into serializing the User Control so that I could just load it along with the other properties, but so far I've had no luck. Any ideas on how to go about and improve/change this?
Thanks!
Indeed, there is a better way. :-)
Have a look at the Microsoft Extensibility Framework (MEF). It works very well with WPF and MVVM.
It allows you to easiliy compose application parts on-the-fly during runtine.
In short, you mark a class you want to be loaded somewhere else with an Attribute [Export]:
[Export(typeof(ViewContainer))]
public class ViewContainer
{
public string ViewName = "WelcomeView";
public string Header="Welcome to the Application"
// Do more stuff here
}
And in the class or assembly that should use the exported class you can load it with the [Import] Attribute:
public class ClassInOtherAssembly
{
[ImportMany]
internal ObservableCollection<ViewContainer> m_MyViews { get; set; }
// Do other stuff here
}
Depending on the architecture that you implement it might even be sufficient to use a 1-liner (!) to assemble all imported classes (this uses a different approach than the following referenced tutorial):
CompositionInitializer.SatisfyImports(this);
And that's it!
(Do not take these examples as is, I just wanted to get to the point. I recommend using
Properties instead of the strings and interfaces instead of the class export. You'll find plenty of more elegant snippets on the net. :-) )
Here you can find a tutorial to get you started:
Getting started with Managed Extensibility Framework (MEF)
Why not use reflection?
You could use Activator.CreateInstance and pass in your View's string:
string asmName = "YourAssembly";
string typeName = "YourViewName";
object obj = Activator.CreateInstance(asmName, typeName).Unwrap() as UserControl;

Categories

Resources