Fody.Propertychanged preventing Edit and Continue when used with MVVMLight - mvvm-light

I understand that using AOP tooling could/should interfere with edit and continue for a class that is weaved. But I have a case where simply using MVVMLight and Fody.PropertyChanged in the same project prevents edit and continue anywhere if there is a class inheriting from ObservableObject in the project.
To reproduce, I simply create a WPF 4.6.2 project in VS 2017 Update 3 (happens in all the updates), add nuget references to MVVMLight & Fody.PropertyChanged, and then I can't edit and continue even simple code like this:
private void ButtonBase_OnClick(object sender, RoutedEventArgs e)
{
int i = 0;
i++;
i++;
}
Error is:
CS7038 Failed to emit module 'WithFodyPropertyChangedAndMvvmLight'.
If I remove the PropertyChanged tag from the FodyWeavers.xml file, the problem goes away. If I don't use MVVMLight and instead just:
class Class : INotifyPropertyChanged
{
public int Test { get; set; }
public event PropertyChangedEventHandler PropertyChanged;
}
it works fine. So it looks MVVMLight specific.
Anyone seen this? Thanks!

Related

Proper Page.Loaded event in Xamarin.Forms

For the past 2 month I have been searching tirelessly for a way to implement a proper Page.Loaded event when using Xamarin.Forms but I couldn't implement or find a way to do it.
Most people suggest overriding Page.OnAppearing or adding an event handler for Page.Appearing both of which are not the answers or the proper way to achieve the desired effect and don't event behave as a real Page.Loaded event would.
I would like to know the following:
Why doesn't Xamarin.Forms have a built-in Page.Loaded event?
Is there's a work around?
Can I implement it from the native side?
Edit:
What I mean by "proper Page.Loaded" event is:
It must be called ONCE AND ONLY ONCE the page has loaded all of it's controls, laid them out, initialized them and rendered them for the first time.
It must NOT be called when returning from modal pages.
1.Why not load the data/controls in the constructor of the ContentPage? The constructor method is call only once and it is also called before Page.OnAppearing.
Can I implement it from the native side?
Yes, I think you can.
In iOS, override the ViewDidLoad method in custom renderer:
[assembly:ExportRenderer (typeof(ContentPage), typeof(MyPageRenderer))]
namespace App487.iOS
{
public class MyPageRenderer : PageRenderer
{
protected override void OnElementChanged(VisualElementChangedEventArgs e)
{
base.OnElementChanged(e);
}
public override void ViewDidLoad()
{
base.ViewDidLoad();
//call before ViewWillAppear and only called once
}
public override void ViewWillAppear(bool animated)
{
base.ViewWillAppear(animated);
}
}
}
In Android, try to override the OnAttachedToWindow method:
[assembly: ExportRenderer(typeof(ContentPage), typeof(MyPageRenderer))]
namespace App487.Droid
{
public class MyPageRenderer : PageRenderer
{
public MyPageRenderer(Context context) : base(context)
{
}
protected override void OnElementChanged(ElementChangedEventArgs<Page> e)
{
base.OnElementChanged(e);
}
protected override void OnAttachedToWindow()
{
base.OnAttachedToWindow();
}
}
}
Currently Xamarin.Forms doesn't not provide a proper/complete life cycle events to fulfill all specific requirements, but things are improving, the Dev team is currently working on to address this issue, below mentioned issues and recent pull request on the official GitHub Repos (you may follow, get ideas and maybe implement it yourself before they even ship it), they will for sure provide that in the future, although it is not clear when it will be ready.
Specification: Enhancement Add better life cycle events #2210.
Issue: LifeCycle events for controls #556.
Pull request: Life cycle events for controls
GitHub Branch where currently working on.
MAUI repo (Next evolution of Xamarin) Cross-Platform LifeCycle.
Specification Add Loaded/Unloaded to VisualElement.

Xamarin.Forms - getting Control from ImageButtonRenderer

I am trying to create a subclass of ImageButton called TintedImageButton that (surprise) can tint the image. I am following the basic structure of some TintedImage code I have found.
TintedImageButton has three renderers for iOS, Android and UWP.
The Android version of TintedImageButtonRenderer isn't working because it can't access the "Control" property of its superclass, ImageButtonRenderer. The Control should be the native widget.
I have been unable to locate the class documentation for ImageButtonRenderer but decompiling seems to indicate that the Control property has been made private for Android, but not for iOS. Does anyone know why this might be? How can I get the native widget so I can modify it?
The ImageButtonRenderer inherits from AppCompatImageButton, so the class myImageButtonRender itself is a native control which is a subclass of AppCompatImageButton.
[assembly: ExportRenderer(typeof(TintedImageButton), typeof(myImageButtonRender))]
namespace App261.Droid
{
class myImageButtonRender : ImageButtonRenderer
{
public myImageButtonRender(Context context) : base(context)
{
}
protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.ImageButton> e)
{
base.OnElementChanged(e);
this.SetImageResource(Resource.Drawable.sample);
AppCompatImageButton imagV = this as AppCompatImageButton;
}
}
}

How to link button event.click with xamarin.driod from xamarin.form

Am new to xamarin.form having a blockage...
This is what I want to do.
I have a button in welcome.xaml in xamarin.form and I want to perform a click event but I want a method from xamarin.driod to be implemented in the click.event.
Those this makes sense to anyone?
You need to write a custom control.
So you could handle the click event in the Android or IOS.
Read here about how to create a custom controls in xamarin.forms
You could also assign a static class that exist in the shared project from your driod project.
I typically prefer using IOC and Interfaces to implement platform specific logic in the Core project, but simple way to do it may just be to set a static Action on your pages code behind.
public partial class WelcomePage
{
public static Action DroidAction { get; set; }
private void Button_OnClicked(object sender, EventArgs e)
{
if (DroidAction == null)
{
Debug.WriteLine("Action was not set");
}
DroidAction?.Invoke();
}
Your Droids OnCreate could be an option of where to do this.
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
WelcomePage.DroidAction = new Action(() => Debug.WriteLine("I a platform specific action!"));
}

What is the proper way to register view with viewmodels in Prism.DryIoc

I'm using the Prism Template Pack for Visual Studio for Mac to generate a new project (tried both shared and pcl) then updating to 7.0.0.340-ci. Is registration of the views to view models done by convention?
When I try to run this app it throws this exception: Objective-C exception thrown. Name: NSInternalInconsistencyException Reason: Application windows are expected to have a root view controller at the end of application launch.
Here is the code for the main app.
public partial class App : PrismApplication
{
public App(IPlatformInitializer initializer = null) : base(initializer) { }
protected override void OnInitialized()
{
InitializeComponent();
NavigationService.NavigateAsync("MainPage?title=Hello%20from%20Xamarin.Forms");
}
protected override void RegisterTypes(Prism.Ioc.IContainerRegistry containerRegistry)
{
Prism.Mvvm.ViewModelLocationProvider.Register<MainPage,MainPageViewModel>();
}
//protected override void RegisterTypes()
//{
// Container.RegisterTypeForNavigation<MainPage>();
//}
}
I had to comment out the bottom lines and redo the override due to incompatible signatures.
Where did the Container.RegisterTypeForNavigation go or what is it's replacement?
I also tried it without any code in the RegisterTypes method.
In a debug session exploring the NavigationService properties says MainPage is null.
The RegisterTypes method should look like this.
In prism forms 7.x pages used for navigation must be registered via RegisterForNavigation<>() or RegisterForNavigation().
protected override void RegisterTypes(Prism.Ioc.IContainerRegistry containerRegistry)
{
containerRegistry.RegisterForNavigation<MainPage,MainPageViewModel>();
}

Caliburn.Micro for WPF Controls Project

My current situation is that I have a winforms application which I would like to create a new WPF controls library projects to start showing new screens in WPF. I would really like to leverage the Caliburn.Micro framework but im struggling getting it set up. I currently have my bootstrapper as a Singleton so that I can initialize it and also Im setting the useApplication property in the base contructor to false. I'm not sure where to go from here any help would be appreciated. thanks
public class AppBootstrapper : BootstrapperBase
{
private static AppBootstrapper bootsrapper;
public static void InitializeInstance()
{
if (bootsrapper == null)
{
bootsrapper = new AppBootstrapper();
}
}
public AppBootstrapper() : base(false)
{
Initialize();
}
}

Resources