Xamarin Forms native customrenderer - xamarin.forms

I have followed James Montemagno's guide on how to make a custom renderer for round images in my Xamarin Forms Shared Project.
https://blog.xamarin.com/elegant-circle-images-in-xamarin-forms/
(being a true copy of the guide it feels redundant to actually add the code itself to my project but please comment if that is not the case)
It is working flawless, however, I need to change the colour of the circle border dynamically with the press of a button when the app is running.
But since the colour of the circle is set natively in each renderer I am uncertain how I could possibly change it from my shared code.

Maybe this snippet can help:
public class CircleImage : Image
{
public static readonly BindableProperty CurvedBackgroundColorProperty =
BindableProperty.Create(
nameof(CurvedBackgroundColor),
typeof(Color),
typeof(CurvedCornersLabel),
Color.Default);
public Color CurvedBackgroundColor
{
get { return (Color)GetValue(CurvedBackgroundColorProperty); }
set { SetValue(CurvedBackgroundColorProperty, value); }
}
}
//Android/iOS
[assembly: ExportRenderer(typeof(CircleImage), typeof(CircleImageRenderer))]
namespace SchedulingTool.iOS.Renderers
{
public class CircleImageRenderer : ImageRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<Image> e)
{
base.OnElementChanged(e);
if (e.NewElement != null)
{
var xfViewReference = (CircleImage)Element;
//Here you can reference xfViewReference.CurvedBackgroundColor to assign what ever is binded.
}
}
}
}
I hope you get the main idea, you can create your own bindable properties and access them on the Native Renderer.
If everything does not go as expected you can always download the NuGet (which has everything you need):
https://github.com/jamesmontemagno/ImageCirclePlugin

Related

IsGestureEnabled is not working in xamarin forms for iOS 16

I'm changing the orientation(Landscape/Portrait) forcefully for one screen.
For that, I used IsGestureEnabled property.
That property is not working on iOS 16 or above versions.
CODE:
protected override void OnDisappearing()
{
SetGestureEnabled(true);
base.OnDisappearing();
}
protected override void OnAppearing()
{
SetGestureEnabled(false);
base.OnAppearing();
}
private void SetGestureEnabled(bool isSet)
{
if (Application.Current.MainPage is MasterDetailPage masterDetailPage)
{
masterDetailPage.IsGestureEnabled = isSet;
}
}
Please help me to resolve this issue.
MasterDetailPage is obsolete. Try using FlyoutPage instead.
FlyoutPage also has IsGestureEnabled property which could disable or enable the swipe gesture. The default value is true. you could use almost the same code in your question
if (Application.Current.MainPage is FlyoutPage flyoutPage)
{
flyoutPage.IsGestureEnabled = true;
}
For more info, you could refer to Xamarin.Forms FlyoutPage

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;
}
}
}

After creating a custom projinvoice can't find created design

I need some help here. I created a custom report invoice design for PSAProjInvoice.
I did duplicate PSAProjInvoice and worked on a already made design.
Created a Controller and PrintMgmtDocTypeHandler class.
Created outputitem extension and redirected it to my ProjInvoiceController
In axapta in ProjFormletterParameters form parameters it shows me name of my custom report but when I go to project invoices and try to make a look at the invoice I just get a error: Unable to find the report design PSAProjInvoiceSZM.ReportPL.
class PSAProjInvoiceSZM
{
[PostHandlerFor(classStr(PSAProjAndContractInvoiceController),
staticMethodStr(PSAProjAndContractInvoiceController, construct))]
public static void ReportNamePostHandler(XppPrePostArgs arguments)
{
PSAProjAndContractInvoiceController controller = arguments.getReturnValue();
controller.parmReportName(ssrsreportstr(PSAprojinvoiceSZM, Report));
}
}
I think that it's a problem with my controller class because I actually have no idea how it should look like. Tried to make one based on salesinvoice tutorial found on microsoft docs but it didn't help me at all.
Tried to make it based on this article:
https://blogs.msdn.microsoft.com/dynamicsaxbi/2017/01/01/how-to-custom-designs-for-business-docs/
My Controller:
class ProjInvoiceControllerSZM extends PSAProjAndContractInvoiceController
{
public static ProjInvoiceControllerSZM construct()
{
return new ProjInvoiceControllerSZM();
}
public static void main(Args _args)
{
SrsReportRunController formLetterController =
ProjInvoiceControllerSZM::construct();
ProjInvoiceControllerSZM controller = formLetterController;
controller.initArgs(_args);
Controller.parmReportName(ssrsReportStr(PSAProjInvoiceSZM, Report));
/* if (classIdGet(_args.caller()) ==
classNum(PurchPurchOrderJournalPrint))
{
formLetterController.renderingCompleted +=
eventhandler(PurchPurchOrderJournalPrint::renderingCompleted);
}*/
formLetterController.startOperation();
}
protected void outputReport()
{
SRSCatalogItemName reportDesign;
reportDesign = ssrsReportStr(PSAProjInvoiceSZM,Report);
this.parmReportName(reportDesign);
this.parmReportContract().parmReportName(reportDesign);
formletterReport.parmReportRun().settingDetail().parmReportFormatName(reportDesign);
super();
}
}

Passing the search term from SearchHandler to ContentPage in Xamarin Forms 4

I'm trying to make use of the new SearchHandler implemented as part of Xamarin Forms 4. I've found it pretty easy so far to get suggestions populated but now I want to raise an event, or follow the suggested method of handling when a search is confirmed.
public class FoodSearchHandler: SearchHandler
{
IFoodDataStore dataStore = new FoodDataStore();
protected override void OnQueryConfirmed()
{
base.OnQueryConfirmed();
// What to do here?
}
protected override void OnQueryChanged(string oldValue, string newValue)
{
base.OnQueryChanged(oldValue, newValue);
if(!string.IsNullOrWhiteSpace(newValue)
{
// Populate suggestions
ItemsSource = dataStore.GetSuggestions(newValue);
}
else
{
ItemsSource = null;
}
}
}
public partial class FoodsPage : ContentPage
{
ObservableCollection<Food> Foods = new ObservableCollection<Food>();
public ItemsPage()
{
InitializeComponent();
// Wire up the search handler
Shell.SetSearchHandler(this, new FoodSearchHandler());
BindingContext = this;
}
}
Unfortunately, althought the alpha docs mention the search handler they don't contain any details on how to use it and the sample apps only demonstrate populating the suggestions.
Does anyone out there have a pointer to offer on how I should be notifying my ContentPage that my SearchHandler confirmed a search?
So, after reading the Shell docs some more, it seems what I want to do in this situation is use of Shell's new Navigation and navigate to a route passing the search text as a query, for example:
protected override void OnQueryConfirmed()
{
base.OnQueryConfirmed();
var shell = Application.Current.MainPage as Shell;
shell.GoToAsync($"app:///fructika/search?query={Query}", true);
}
N.B. It doesn't look like passing data works right now or if it does I'm doing it wrong but I'll raise a separate question about that.

iOS 11 large titles in Xamarin.Forms

How do I enable iOS 11 prefersLargeTitles throughout my Xamarin.Forms app?
I tried creating a custom renderer derived from PageRenderer for NavigationPage, setting:
ViewController.NavigationController.NavigationBar.PrefersLargeTitles = true;
This didn't have any effect, however.
Voila
[assembly: ExportRenderer(typeof(NavigationPage), typeof(NavBarRenderer))]
namespace LargeTitleSample.iOS
{
public class NavBarRenderer : NavigationRenderer
{
protected override void OnElementChanged(Xamarin.Forms.Platform.iOS.VisualElementChangedEventArgs e)
{
base.OnElementChanged(e);
NavigationBar.PrefersLargeTitles = true;
}
}
}
You have to create a custom renderer for the NavigationPage inheriting the NavigationRenderer. Then set the PrefersLargeTitles property on the NavigationBar to true.
It seems that when you add some scrollable control to the page, it will automatically have to 'big to small' effect when scrolling up, at least for a ListView.
Working example repo is here: https://github.com/jfversluis/LargeTitleSample
For XAML:
<NavigationPage Title="..." xmlns:ios="clr-namespace:Xamarin.Forms.PlatformConfiguration.iOSSpecific;assembly=Xamarin.Forms.Core" ios:NavigationPage.PrefersLargeTitles="true">

Resources