how to modify suavecontrols.materialforms in xamarin forms - xamarin.forms

I want to modify a entry made with the nugget package of this link https://github.com/SuavePirate/SuaveControls.MaterialFormControls
The declaration in xaml looks like this
<suave:MaterialEntry x:Name="Contrasena" IsPassword="True"
Placeholder="Password" Style="{StaticResource Entries}"/>
and I create and effect to remove the underline, I already checked with a normal entry so I know it works. The code with the effect looks like this
<suave:MaterialEntry x:Name="Contrasena" IsPassword="True"
Placeholder="Password" Style="{StaticResource Entries}"/>
<suave:MaterialEntry.Effects>
<local:NoUnderline></local:NoUnderline>
<suave:MaterialEntry.Effects>
</suave:MaterialEntry>
I want to know why don't work, I suppose is because of the namespace where are each one.
This is what I put in contentpage to use materialforms in the xaml
xmlns:suave="clr-namespace:SuaveControls.MaterialForms;Assembly=SuaveControls.MaterialForms"
This is what is in the top of the xaml project
<ContentPage xmlns="xamarin.com/schemas/2014/forms"
xmlns:x="schemas.microsoft.com/winfx/2009/xaml" xmlns:local="clr-
namespace:Proyecto" x:Class="Proyecto.Registro" BackgroundColor="
{StaticResource GrisClaro}" xmlns:suave="clr-namespace:SuaveControls.MaterialForms;assembly=SuaveControls.MaterialForms">
And the local effect is like this in the pcl
public class NoUnderline : RoutingEffect
{
public NoUnderline() : base("EffectsSample.NoUnderline")
{
}
}
And like this in android
public class NoUnderline : PlatformEffect
{
protected override void OnAttached()
{
try
{
if (Control != null)
{
if (Android.OS.Build.VERSION.PreviewSdkInt >= (int)Android.OS.BuildVersionCodes.Lollipop)
Control.BackgroundTintList = Android.Content.Res.ColorStateList.ValueOf(Android.Graphics.Color.White);
else
{
Control.Background.SetColorFilter(Android.Graphics.Color.White, PorterDuff.Mode.SrcAtop);
}
}
}
catch (Exception ex)
{
Console.WriteLine("Cannot set property on attached control. Error: ", ex.Message);
}
}
protected override void OnDetached()
{
}
}

Related

Xamarin Forms to Xamarin.Android

I have some pages in Xamarin.Forms,since I need to build a custom camera,so I used Xamarin.Android.
now I need to go to Xamarin.Android/iOS from page of Xamarin.Forms and and back to Xamarin.Forms again. how can I do it?
pls help
You don't necessarily need to jump between Xamarin.Forms Views/Pages and Project Specific (iOS/Android) Views manually you can do it by using CustomRenderes which are part of Xamarin.Forms.
Basically you would create a Custom Page on Xamarin.Forms then specifying in each platform project how you want that page to look. You would attach this CustomRender to your Custom Page (the one you made in Xamarin.Forms) and the Framework would do the rest for you.
You can read about Custom Renderers here. And you can see a very similar example of what you are looking right in the Xamarin documentation here.
Hope this helps.-
Welcome to SO !
Baesd on a Xamarin Forms project , you can use Custom Renderer to achieve that .
Such as Creating the Custom Control :
public class CameraPreview : View
{
public static readonly BindableProperty CameraProperty = BindableProperty.Create (
propertyName: "Camera",
returnType: typeof(CameraOptions),
declaringType: typeof(CameraPreview),
defaultValue: CameraOptions.Rear);
public CameraOptions Camera {
get { return (CameraOptions)GetValue (CameraProperty); }
set { SetValue (CameraProperty, value); }
}
}
In Xaml :
<ContentPage ...
xmlns:local="clr-namespace:CustomRenderer;assembly=CustomRenderer"
...>
<ContentPage.Content>
<StackLayout>
<Label Text="Camera Preview:" />
<local:CameraPreview Camera="Rear"
HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" />
</StackLayout>
</ContentPage.Content>
</ContentPage>
Now you can create the Custom Renderer on each Platform.
Android :
[assembly: ExportRenderer(typeof(CustomRenderer.CameraPreview), typeof(CameraPreviewRenderer))]
namespace CustomRenderer.Droid
{
public class CameraPreviewRenderer : ViewRenderer<CustomRenderer.CameraPreview, CustomRenderer.Droid.CameraPreview>
{
CameraPreview cameraPreview;
public CameraPreviewRenderer(Context context) : base(context)
{
}
protected override void OnElementChanged(ElementChangedEventArgs<CustomRenderer.CameraPreview> e)
{
base.OnElementChanged(e);
if (e.OldElement != null)
{
// Unsubscribe
cameraPreview.Click -= OnCameraPreviewClicked;
}
if (e.NewElement != null)
{
if (Control == null)
{
cameraPreview = new CameraPreview(Context);
SetNativeControl(cameraPreview);
}
Control.Preview = Camera.Open((int)e.NewElement.Camera);
// Subscribe
cameraPreview.Click += OnCameraPreviewClicked;
}
}
void OnCameraPreviewClicked(object sender, EventArgs e)
{
if (cameraPreview.IsPreviewing)
{
cameraPreview.Preview.StopPreview();
cameraPreview.IsPreviewing = false;
}
else
{
cameraPreview.Preview.StartPreview();
cameraPreview.IsPreviewing = true;
}
}
...
}
}
iOS :
[assembly: ExportRenderer (typeof(CameraPreview), typeof(CameraPreviewRenderer))]
namespace CustomRenderer.iOS
{
public class CameraPreviewRenderer : ViewRenderer<CameraPreview, UICameraPreview>
{
UICameraPreview uiCameraPreview;
protected override void OnElementChanged (ElementChangedEventArgs<CameraPreview> e)
{
base.OnElementChanged (e);
if (e.OldElement != null) {
// Unsubscribe
uiCameraPreview.Tapped -= OnCameraPreviewTapped;
}
if (e.NewElement != null) {
if (Control == null) {
uiCameraPreview = new UICameraPreview (e.NewElement.Camera);
SetNativeControl (uiCameraPreview);
}
// Subscribe
uiCameraPreview.Tapped += OnCameraPreviewTapped;
}
}
void OnCameraPreviewTapped (object sender, EventArgs e)
{
if (uiCameraPreview.IsPreviewing) {
uiCameraPreview.CaptureSession.StopRunning ();
uiCameraPreview.IsPreviewing = false;
} else {
uiCameraPreview.CaptureSession.StartRunning ();
uiCameraPreview.IsPreviewing = true;
}
}
...
}
}
More info can refer to this official sample .

Xamarin forms: Entire row highlighting when tapped FlowListView item?

I have added FlowListView in my project. As mention in the FAQ I am facing the entire row highlighting issue when tapped one item in windows, no such issue in android. I have added the custom renderers like below:
In Main Project:
using DLToolkit.Forms.Controls;
namespace Mynamespace
{
public class CustomFlowListView : FlowListView
{
}
}
In UWP:
using Listpm;
using Listpm.UWP;
using Xamarin.Forms;
using Xamarin.Forms.Platform.UWP;
[assembly: ExportRenderer(typeof(CustomFlowListView), typeof(CustomListViewRenderer))]
namespace Listpm.UWP
{
class CustomListViewRenderer : ListViewRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<ListView> e)
{
base.OnElementChanged(e);
if (List != null)
List.SelectionMode = Windows.UI.Xaml.Controls.ListViewSelectionMode.None;
}
}
}
In xaml added <local:CustomFlowListView> instead of <flv:FlowListView>.
<local:CustomFlowListView
FlowColumnCount="2"
SeparatorVisibility="None"
HasUnevenRows="false"
RowHeight="200"
FlowItemsSource="{Binding AllItems}">
<flv:FlowListView.FlowColumnTemplate>
<DataTemplate>
<StackLayout
HorizontalOptions="FillAndExpand"
VerticalOptions="FillAndExpand">
<Image/>
</StackLayout>
</DataTemplate>
</flv:FlowListView.FlowColumnTemplate>
</local:CustomFlowListView>
Are there any other changes instead of this for solving this issue?
How can I disable entire row highlighting when tapped?
You also need to add List.IsItemClickEnabled = false. And it will not effect FlowItemTapped event.
protected override void
OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.ListView> e)
{
base.OnElementChanged(e);
if (List != null)
List.SelectionMode = Windows.UI.Xaml.Controls.ListViewSelectionMode.None;
List.IsItemClickEnabled = false;
}

"cancel" disapears after submit SearxhBox if the Text is set to null (Xamarin.Forms)

I have a custom control for to show the "cancel" button inside the iOS SearchBars:
[assembly: ExportRenderer(typeof(SearchBar), typeof(AppSearchBarRenderer))]
namespace Elfo.VisionMobile.iOS.Renderers
{
public class AppSearchBarRenderer : SearchBarRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<SearchBar> e)
{
base.OnElementChanged(e);
Control.ShowsCancelButton = true;
}
}
}
And this is my XAML:
<SearchBar Text="{Binding SearchKey, Mode=TwoWay}" SearchCommand="{Binding SearchCommand}"/>
And the search execute method of the command (C#):
private void SearchExecute()
{
// whatever...
SearchKey = null;
}
And when I set the SearchKey to null or string.Empty , the "cancel" button disapears.
Guys, do you know something?
Ok I just fixed it.
I had to use the method OnElementPropertyChanged instead of OnElementChanged.

Caliburn Micro: Screen.TryClose does not work

I am running out of hair in frustration.
I have made a somewhat minimal example where the same viewmodel/view acts as main window and dialog. Hope this does not cause confusion.
class DialogViewModel : Screen
{
private readonly IWindowManager _windowManager;
public DialogViewModel(IWindowManager windowManager)
{
_windowManager = windowManager;
}
public void ShowDialog()
{
_windowManager.ShowDialog(new DialogViewModel(_windowManager));
}
//----------
public DialogViewModel()
{
}
public void Close()
{
TryClose();
//TryClose(true);
//TryClose(false);
}
}
<Window x:Class="Views.DialogView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
xmlns:cal="clr-namespace:Caliburn.Micro;assembly=Caliburn.Micro.Platform"
mc:Ignorable="d"
d:DesignHeight="100" d:DesignWidth="200">
<WrapPanel>
<Button>
Close
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<cal:ActionMessage MethodName="Close" />
</i:EventTrigger>
</i:Interaction.Triggers>
</Button>
<Button>
Show Dialog
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<cal:ActionMessage MethodName="ShowDialog" />
</i:EventTrigger>
</i:Interaction.Triggers>
</Button>
</WrapPanel>
</Window>
public sealed class AppBootstrapper : BootstrapperBase
{
private SimpleContainer _container;
public AppBootstrapper() : base(true)
{
StartRuntime();
}
protected override void OnStartup(object sender, StartupEventArgs e)
{
DisplayRootViewFor<DialogViewModel>();
}
protected override void Configure()
{
_container = new SimpleContainer();
_container.Singleton<IWindowManager, WindowManager>();
_container.Singleton<IEventAggregator, EventAggregator>();
_container.PerRequest<DialogViewModel>();
}
protected override object GetInstance(Type service, string key)
{
var instance = _container.GetInstance(service, key);
if (instance != null)
return instance;
throw new InvalidOperationException("Could not locate any instances.");
}
protected override IEnumerable<object> GetAllInstances(Type service)
{
return _container.GetAllInstances(service);
}
protected override void BuildUp(object instance)
{
_container.BuildUp(instance);
}
}
The call TryClose() does not initiate OnDeactivate.
According to https://caliburnmicro.codeplex.com/wikipage?title=Screens,%20Conductors%20and%20Composition and the several posts here on stackoverflow the above should be enough. But nothing happens when I call TryClose().
Please note that code does run and show the dialogs on my machine. If something is missing, please let me know.
Any ideas why?
Thank you!
StartRuntime should be Initialize(), codeplex code is really really outdated with release of v2. Reference github.com/bluespire/Caliburn.Micro or CaliburnMicro.com. I assume this is a WPF App. Also your Button's don't appear to be correct.
<Button x:Name="ShowDialog" Content="ShowDialog" />
<Button x:Name="Close" Content="Close" />
I am assuming this is a WPF application.

Xamarin.Forms UserControl using XAML and Custom Renderer

There are a few good examples already of how to create a "custom control" by -
Deriving a Class from View or an existing built-in control and then creating a custom renderer for it per platform.
http://blog.xamarin.com/using-custom-controls-in-xamarin.forms-on-android/
http://developer.xamarin.com/guides/cross-platform/xamarin-forms/custom-renderer/
I want to create a "compound custom control OR usercontrol" which contains multiple elements which are defined in XAML (in the shared code), and then customised with a renderer (to say tweak the styling per platform).
Does anyone have an example of doing this please? A simple example with a view that has a bindable label and an entry box should be enough to show the main principles.
Here is what I have so far -
Defined a ContentView to represent our usercontrols layout and contents.
<ContentView xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="News.Forms.VisualNewsContentView">
<ContentView.Content>
<StackLayout>
<Label x:Name="MyLabel" Text="Label"></Label>
<Entry x:Name="MyEntry" Text="Entry"></Entry>
</StackLayout>
</ContentView.Content>
</ContentView>
with codebehind -
public partial class VisualNewsContentView : ContentView
{
public VisualNewsContentView ()
{
InitializeComponent ();
}
// Not sure if I need this to access Entry ...
public Entry GetEntry ()
{
return MyEntry;
}
}
Add an Android Custom Renderer for that ContentView, how do I access and customise natively parts / controls of the ContentView?
[assembly:ExportRenderer (typeof(VisualNewsContentView), typeof(VisualNewsRenderer))]
namespace News.Forms.Android
{
public class VisualNewsRenderer: ViewRenderer
{
public VisualNewsRenderer () { }
protected override void OnModelChanged (VisualElement oldModel, VisualElement newModel)
{
base.OnModelChanged (oldModel, newModel);
if (newModel != null) {
VisualNewsContentView newsContentView = newModel as VisualNewsContentView;
// i.e. How could I get hold of EditText etc so I could natively customise its appearance? When you use a built in renderer like EntryRenderer you can use Control to access native control.
Console.WriteLine (newsContentView.GetLabel ().Text);
EditText ed = (EditText)newsContentView.GetEntry ().???
}
}
}
}
Just can't quite get the pieces together to work, the ContentView seems to render fine on page but cannot work out how to access its Child Native controls in the viewrenderer.
Be nice to also show how you can use Binding for the Label and Entry Text values.
I do not want to have to define a custom renderer for each single label / entry etc of the usercontrol.
Is this what you meant?
Some properties to access the Xamarin.Forms controls:
public partial class VisualNewsContentView : ContentView
{
public VisualNewsContentView()
{
InitializeComponent();
}
public Label Label
{
get
{
return MyLabel;
}
set
{
MyLabel = value;
}
}
public Entry Entry
{
get
{
return MyEntry;
}
set
{
MyEntry = value;
}
}
}
Some magic inside the Renderer to customize the controls on the page:
[assembly:ExportRenderer (typeof(VisualNewsContentView), typeof(VisualNewsRenderer))]
namespace News.Forms.Android
{
public class VisualNewsRenderer: ViewRenderer
{
public VisualNewsRenderer () { }
protected override void OnModelChanged (VisualElement oldModel, VisualElement newModel)
{
base.OnModelChanged (oldModel, newModel);
if (newModel != null) {
VisualNewsContentView newsContentView = newModel as VisualNewsContentView;
newsContentView.Label.Text = "It´s some kind of..";
newsContentView.Entry.Text = "MAGIC!";
newsContentView.Entry.BackgroundColor = Color.Blue;
newsContentView.Entry.RotationX = 180;
newsContentView.Entry.Focus();
}
}
}
}
EDIT:
I don't know if it's possible to map your controls from the XAML-page to native controls. You could add the controls which you want to customize natively # the renderer.
[assembly:ExportRenderer (typeof(VisualNewsContentView), typeof(VisualNewsRenderer))]
namespace News.Forms.Android
{
public class VisualNewsRenderer: NativeRenderer
{
public VisualNewsRenderer () { }
protected override void OnModelChanged (VisualElement oldModel, VisualElement newModel)
{
base.OnModelChanged (oldModel, newModel);
if (newModel != null) {
LinearLayout layout = new LinearLayout (Application.Context);
layout.Orientation = Orientation.Vertical;
TextView tv = new TextView (Application.Context);
tv.Ellipsize = TextUtils.TruncateAt.Middle;
tv.Text = "It´s some kind of..";
EditText et = new EditText (Application.Context);
et.SetTextColor (Graphics.Color.Chocolate);
et.Text = "MAGIC!";
layout.AddView (tv);
layout.AddView (et);
SetNativeControl (layout);
}
}
}
}
But like this you won't be using your ContentView.. I'm sorry, I have nothing better than this..
My solution for customizing compound user control is make a custom control for each control used in compound user control.
For example, which this control:
<ContentView xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="News.Forms.VisualNewsContentView">
<ContentView.Content>
<StackLayout>
<Label x:Name="MyLabel" Text="Label"></Label>
<Entry x:Name="MyEntry" Text="Entry"></Entry>
</StackLayout>
</ContentView.Content>
</ContentView>
I will do something like this:
<ContentView xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:CustomControls="clr-namespace:App.CustomControls;assembly=App" x:Class="News.Forms.VisualNewsContentView">
<ContentView.Content>
<CustomControls:StackLayout>
<CustomControls:Label x:Name="MyLabel" Text="Label"></CustomControls:Label>
<CustomControls:Entry x:Name="MyEntry" Text="Entry"></CustomControls:Entry>
</CustomControls:StackLayout>
</ContentView.Content>
</ContentView>
Example class for CustomControls:StackLayout is:
(in StackLayout.cs)
using Xamarin.Forms;
namespace App.CustomControls
{
public class StackLayout : Xamarin.Forms.StackLayout
{
}
}
(in StackLayoutRenderer.cs for android project)
[assembly: ExportRenderer(typeof(App.CustomControls.StackLayout), typeof(App.Droid.CustomRenderers.StackLayoutRenderer))]
namespace App.Droid.CustomRenderers.MapView
{
public class StackLayoutRenderer : ViewRenderer<StackLayout, Android.Widget.LinearLayout>
{
protected override void OnElementChanged(ElementChangedEventArgs<StackLayout> e)
{
base.OnElementChanged(e);
}
}
}

Resources