How to programmatically associate a style to a button in Xamarin? - xamarin

In my Xamarin app, I create a button (Xamarin.Forms.Button) programmatically. I need this button to show a different background image under normal vs hovered state. I have created a style resource similar to what is described at How to indicate currently selected control in Xamarin?. However, I cannot figure out how to apply this style to the button.
The Button class exposes a property called Image that is of FileImageSource type. The closest API I found to load my style resource is ImageSource.FromResource static method. However, this method seems to return StreamImageSource instance which is not what we need.
Class Button does not seem to provide any Style property.
Can you please suggest how I can programmatically associate a style to the button? Regards.

To achieve this request you need custom renderers.
To be able to apply your style f.e.: "myButtonStyle.xml" you have to create a custom renderer for your target platform:
Android:
[assembly: ExportRenderer (typeof (YourExtendedButtonClass), typeof (MyCustomButtonRenderer))]
namespace YourApp.Droid
{
public class MyCustomButtonRenderer : ButtonRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<Button> e)
{
base.OnElementChanged(e);
var myButton = this.Control as Android.Widget.Button;
myButton?.SetBackgroundResource(Resource.Drawable.myButtonStyle);
}
}
}

Related

How can I create a Custom Renderer for a ContentView in Xamarin.Forms MacOS?

We're using Xamarin.Forms with MacOS, and have a custom view MyCustomView : Xamarin.Forms.ContentView, and I'm trying to create a custom view renderer for our view, but it's interfering with the rendered view.
Does anyone know how to create a view renderer in my platform project?
This is the code I've tried so far, looking at similar places:
[assembly: Xamarin.Forms.ExportRenderer(typeof(MyCustomView), typeof(MyCustomViewRenderer))]
namespace Mac.Renderers
{
public class MyCustomViewRenderer : ViewRenderer<Xamarin.Forms.ContentView, AppKit.NSView>
{
public MyCustomViewRenderer()
{
// My implementation
}
}
}
Event when the implementation is left blank, having this custom renderer is affecting the display of the ContentView, so I think this code must not be right - is there a way to do this?
You could fix your issue by changing your class to inherit from VisualElementRenderer<T> instead.
[assembly: Xamarin.Forms.ExportRenderer(typeof(MyCustomView), typeof(MyCustomViewRenderer))]
namespace Mac.Renderers
{
public class MyCustomViewRenderer : VisualElementRenderer<ContentView>
{
public MyCustomViewRenderer()
{
// My implementation
}
}
}
Page has a default Renderer "PageRenderer", do not understand why ContentView does not. It would be nice if there was a ContentViewRenderer.
Hope this helps.-

Xamarin forms - Picker Renderer set 'spinner' font size

How do you change the font of the 'spinner' portion of the picker? I can change the display font doing the following
public class MyPickerRenderer : PickerRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<Picker> e)
{
base.OnElementChanged(e);
if (Control != null)
{
**Control.Font = UIFont.SystemFontOfSize(8);**
}
}
}
Unfortunately this is not possible at least it's not subclassing the PickerRenderer defined in Xamarin.Forms for iOS.
The UIPickerView control that is displayed is marked as private for the renderer implementation, hence it will not be accesible from the subclass.
You could anyway do your own implementation of the Renderer and for this you could follow the implementation made by Xamarin.Forms (here you can see it) and do the modifications you need.
You will also need to subclass the UIPickerView class and override the ViewFor and there set the font size you want for the items..
Hope this helps.-

xamarin forms ButtonRenderer onclick override

In XAMARIN FORMS ButtonRenderer only provide two methods which i can override: OnElementChanged and OnElementPropertyChanged. Which method do I want to override to handle button clicks?
You have a reference to the button in your Renderer (search for the proeprty Control). Just add the click-event/listener/command for this Control (but be carefull, it may be that the Control is NULL, depending on your renderer implementation).
Quick code sample for ios (depends on your renderer):
protected override void OnElementChanged(ElementChangedEventArgs<MyButtonRenderer> e)
{
var mybutton = Control as UIButton;
mybutton.TouchUpInside += (s, args) => { /* your logic */};
}
For android you can find a sample on this page.

XamarinForms AppCompat OnOptionsItemSelected

I have recently updated xamarin forms to 1.5.1-pre1 so that I can use the beautiful AppCompat themes. It works and looks very nice.
I do have one problem, in my old FormsApplicationActivity I used to override the OnOptionsItemSelected method to intercept when the user was clicking on the back arrow icon and do some viewmodel cleanup. Apparently this method is not being called after using the FormsAppCompatActivity.
How can I intercept the "soft" back button press (toolbar icon not hard back button) ?
I also tried to override the Xamarin.Forms.Platform.Android.AppCompat.NavigationPageRenderer but i can't seem to override it :(
Does anyone have a clue how I can intercept this?
You can add the following to your custom renderer. You can either user current activity plugin or cast your context to activity.
var toolbar = CrossCurrentActivity.Current?.Activity?.FindViewById<Toolbar>(Resource.Id.toolbar);
toolbar.NavigationClick += ToolbarNavigationClick;
Have a look at the last two lines of the OnCreate() After adding them OnOptionsItemSelected was called as expected).
https://raw.githubusercontent.com/UdaraAlwis/Xamarin-Playground/master/XFNavBarBackBtnClickOverride/XFNavBarBackBtnClickOverride/XFNavBarBackBtnClickOverride.Droid/MainActivity.cs
Toolbar toolbar = this.FindViewById<Toolbar>(Resource.Id.toolbar);
SetSupportActionBar(toolbar);
In Xamarin.Forms there's a better way to intercept the NavigationBar back button pressed and the hardware back button pressed, which is creating your own NavigationRenderer and overriding the method OnPopViewAsync:
[assembly: ExportRenderer(typeof(NavigationPage), typeof(CustomNavigationRenderer))]
namespace YourApp.Droid
{
public class CustomNavigationRenderer : NavigationPageRenderer
{
public CustomNavigationRenderer(Context context) : base(context)
{
}
protected override async Task<bool> OnPopViewAsync(Page page, bool animated)
{
// Write your code here
}
}
}
Hope this helps

how to add custom view to palette in android studio?

i made custom view which extend textView with this constractors :
// Default constructor override
public AutoResizeTextView(Context context) {
this(context, null);
}
// Default constructor when inflating from XML file
public AutoResizeTextView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
how to i add it to my palette in android studio ?
i saw button that allows to to chose custom view but after i click on it nothing happen :
after i click on the class that i want the window is closed and nothing happen ...
I found this official guide to add custom views in the palette.

Resources