I am working with search bar in xamarin forms. I am not able to remove search text in search bar by clicking cross button. I am using custom renderer for remove cancel text in search bar. When I am using that renderer I am not able delete the text, If I remove that renderer it work's fine. what the wrong I have done in renderer file. Here is the sample code in renderer for hide the cancel button beside the search bar.
Renderer Sample code:
protected override void OnElementPropertyChanged(object sender, PropertyChnagedEventArgs e)
{
Control.ShowCancelButton = false;
}
When I try to remove text in search bar by clicking cross image in search bar it's not working in xamarin ios but it's working fine in ios.
Sample code :
<StackLayout Grid.Column = "0" Orientation = "Horizontal">
<Image Source = "backarrow.png" HorizontalOptions = "StartAndExpand" VerticalOptions = "CenterAndExpand" />
<controls:CustomSearchbar x:Name = "CustomSearchbar" BackgroundColor ="Transparent" Text ="{Binding SearchTag}" SearchCommand ="{Binding RestaurantSearchCommand}" GHorizontalOptions = "StartAndExpand" VerticalOptions = "CenterAndExpand" >
Here is the code I am using for search bar. Here 'customsearchbar' class is inherited from searchrenderer.
It works fine for me.
Here's my code for example:
MySearchBar.cs in PCL:
using Xamarin.Forms;
namespace Kevin_XF
{
public class MySearchBar : SearchBar
{
}
}
MySearchBarRenderer.cs in iOS platform:
using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;
using Kevin_XF.iOS;
using Kevin_XF;
using System.ComponentModel;
[assembly: ExportRenderer(typeof(MySearchBar),typeof(MySearchBarRenderer))]
namespace Kevin_XF.iOS
{
public class MySearchBarRenderer: SearchBarRenderer
{
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
{
base.OnElementPropertyChanged(sender, e);
if (Control != null)
{
Control.ShowsCancelButton = false;
}
}
}
}
Xaml code in MainPage.xaml:
<StackLayout>
<local:MySearchBar x:Name = "CustomSearchbar" BackgroundColor ="Transparent" HorizontalOptions = "StartAndExpand" VerticalOptions = "CenterAndExpand" />
</StackLayout>
It works like this:
Related
I'm new to xamarin forms and learning it through video tutorials done using iOS development Mac laptop.I'm using windows & VS2019 for Xamarin forms. When using ListView, TextCell and ContextActions, my mentuItem text="Delete" or text="Call" aren't showing up when i select a name in the android emulator. But the same action of selection a name on the iOS emulator makes two buttons("Delete" & "Call") slides out. I attached my image as well as the tutotial image. Below are the codes from the tutorial.
My xaml file is `
<? xml version = "1.0" encoding = "utf-8" ?>
< ContentPage xmlns = "http://xamarin.com/schemas/2014/forms"
xmlns: x = "http://schemas.microsoft.com/winfx/2009/xaml"
x: Class = "WarMemorial.Excercises.ListViewContextActions" >
< ListView x: Name = "listView" >
< ListView.ItemTemplate >
< DataTemplate >
< TextCell Text = "{Binding Name}"
Detail = "{Binding Status}" >
< TextCell.ContextActions >
< MenuItem Text = "Call" IconImageSource = "phone.png"
Clicked = "Call_Clicked"
CommandParameter = "{Binding .}" ></ MenuItem >
< MenuItem Text = "Delete"
Clicked = "Delete_Clicked" IconImageSource = "trash-can.png"
CommandParameter = "{Binding .}" ></ MenuItem >
</ TextCell.ContextActions >
</ TextCell >
</ DataTemplate >
</ ListView.ItemTemplate >
</ ListView >
</ ContentPage >
XAML.cs
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;
using WarMemorial.Models;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
namespace WarMemorial.Excercises
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class ListViewContextActions : ContentPage
{
private ObservableCollection<Contacts> _contacts;
public ListViewContextActions()
{
InitializeComponent();
_contacts = new ObservableCollection<Contacts> {
new Contacts { Name = "Susana" },
new Contacts { Name = "Sara", Status = "let's tallk" }
};
listView.ItemsSource = _contacts;
}
private void Call_Clicked(object sender, EventArgs e)
{
var contact = (sender as MenuItem).CommandParameter as Contacts;
DisplayAlert("Call", contact.Name, "OK");
}
private void Delete_Clicked(object sender, EventArgs e)
{
var contact = (sender as MenuItem).CommandParameter as Contacts;
_contacts.Remove(contact);
}
}
}
as #Jason said you can't get the same behavior on iOS and Android for ContextActions, on the other hand you might want to use the experimental SwipeView which will give you the same swipe behavior on both platforms.
I am testing using the following example. https://github.com/CrossGeeks/TooltipSample
The sample works fine, it even works with Labels (sample uses buttons, images and boxviews). The issue is in my main App I need to create the tooltips in code behind.
To test how to do it, in the very same solution (from that above example) I created a TestPage and made it my MainPage in App.xaml.cs. The XAML looks like this:
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="ToolTipSample.TestPage">
<ContentPage.Content>
<StackLayout
x:Name="mainLayout"
BackgroundColor="Yellow">
<StackLayout.GestureRecognizers>
<TapGestureRecognizer Tapped="Handle_Tapped"/>
</StackLayout.GestureRecognizers>
</StackLayout>
</ContentPage.Content>
The code-behind looks like this:
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
using ToolTipSample.Effects;
namespace ToolTipSample
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class TestPage : ContentPage
{
public TestPage()
{
InitializeComponent();
var actionLabel = new Label
{
Text = "Show Tooltip",
WidthRequest = 150,
VerticalOptions = LayoutOptions.StartAndExpand,
HorizontalOptions = LayoutOptions.Center,
BackgroundColor = Color.Wheat
};
// Add tooltip to action label
TooltipEffect.SetPosition(actionLabel, TooltipPosition.Bottom);
TooltipEffect.SetBackgroundColor(actionLabel, Color.Silver);
TooltipEffect.SetTextColor(actionLabel, Color.Teal);
TooltipEffect.SetText(actionLabel, "This is the tooltip");
TooltipEffect.SetHasTooltip(actionLabel, true);
actionLabel.Effects.Add(Effect.Resolve($"CrossGeeks.{nameof(TooltipEffect)}"));
mainLayout.Children.Add(actionLabel);
}
void Handle_Tapped(object sender, System.EventArgs e)
{
foreach (var c in mainLayout.Children)
{
if (TooltipEffect.GetHasTooltip(c))
{
TooltipEffect.SetHasTooltip(c, false);
TooltipEffect.SetHasTooltip(c, true);
}
}
}
}
}
All other code unchanged.
When I tap the label, the tooltip appears as expected. But when I tap the background it does not disappear (like those created in XAML in the sample).
One other thing. If I tap twice it disappears.
Can anyone see what I am missing?
Thanks.
According to your description and code, you can delete the following line code to achieve your requirement.
actionLabel.Effects.Add(Effect.Resolve($"CrossGeeks.{nameof(TooltipEffect)}"));
You don't need to add effect for control when page load, because this effect will be added when you click this control by these code:
static void OnHasTooltipChanged(BindableObject bindable, object oldValue, object newValue)
{
var view = bindable as View;
if (view == null)
{
return;
}
bool hasTooltip = (bool)newValue;
if (hasTooltip)
{
view.Effects.Add(new ControlTooltipEffect());
}
else
{
var toRemove = view.Effects.FirstOrDefault(e => e is ControlTooltipEffect);
if (toRemove != null)
{
view.Effects.Remove(toRemove);
}
}
}
I am using a renderer to allow me to set a custom footer in my TableView. The renderer works but I would like to have the capability to set up different footers for the different table sections. For example one footer for table section 0 and another for table section 1, all the way up to table section 5.
Here's the XAML that I am using:
<!-- <local:ExtFooterTableView x:Name="tableView" Intent="Settings" HasUnevenRows="True">-->
<TableView x:Name="tableView" Intent="Settings" HasUnevenRows="True">
<TableSection Title="Cards1">
<ViewCell Height="50">
<Label Text="Hello1" />
</ViewCell>
<ViewCell Height="50">
<Label Text="Hello2" />
</ViewCell>
</TableSection>
<TableSection Title="Cards2">
<TextCell Height="50" Text="Hello"></TextCell>
</TableSection>
</TableSection>
<!-- </local:ExtFooterTableView>-->
</TableView>
and here is the C# class and renderer:
public class ExtFooterTableView : TableView
{
public ExtFooterTableView()
{
}
}
and:
using System;
using Japanese;
using UIKit;
using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;
[assembly: ExportRenderer(typeof(ExtFooterTableView), typeof(Japanese.iOS.ExtFooterTableViewRenderer))]
namespace Japanese.iOS
{
public class ExtFooterTableViewRenderer : TableViewRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<TableView> e)
{
base.OnElementChanged(e);
if (Control == null)
return;
var tableView = Control as UITableView;
var formsTableView = Element as TableView;
tableView.WeakDelegate = new CustomFooterTableViewModelRenderer(formsTableView);
}
private class CustomFooterTableViewModelRenderer : TableViewModelRenderer
{
public CustomFooterTableViewModelRenderer(TableView model) : base(model)
{
}
public override UIView GetViewForFooter(UITableView tableView, nint section)
{
Debug.WriteLine("xx");
if (section == 0)
{
return new UILabel()
{
// Text = TitleForFooter(tableView, section), // or use some other text here
Text = "abc",
TextAlignment = UITextAlignment.Left
// TextAlignment = NSTextAlignment.NSTextAlignmentJustified
};
}
else
{
return new UILabel()
{
// Text = TitleForFooter(tableView, section), // or use some other text here
Text = "def",
TextAlignment = UITextAlignment.Left
// TextAlignment = NSTextAlignment.NSTextAlignmentJustified
};
}
}
}
}
}
The code works but I would like to find out how I can set up a different footer text for different sections in the XAML. Something like this:
From what I see it looks like the code is partly there TitleForFooter(tableView, section) but I am not sure how to use it and how I could set it up. Note that I am not really looking for a view model solution. I would be happy to be simply able to specify the section footer text as part of the TableView XAML.
I'd appreciate if anyone could give me some advice on this.
First of all, in order to be able to specify the section footer text in XAML - simplest option would be to create a bindable property in TableSection. But as TableSection is sealed, we can't derive it to define our custom bindable properties.
So, the next option is to create a attached bindable property.
public class Ex
{
public static readonly BindableProperty FooterTextProperty =
BindableProperty.CreateAttached("FooterText", typeof(string), typeof(Ex), defaultValue: default(string));
public static string GetFooterText(BindableObject view)
{
return (string)view.GetValue(FooterTextProperty);
}
public static void SetFooterText(BindableObject view, string value)
{
view.SetValue(FooterTextProperty, value);
}
}
Next step would be to update renderer to retrieve this value for every section:
private class CustomFooterTableViewModelRenderer : TableViewModelRenderer
{
public CustomFooterTableViewModelRenderer(TableView model) : base(model)
{
}
public override UIView GetViewForFooter(UITableView tableView, nint section)
{
return new UILabel()
{
Text = TitleForFooter(tableView, section), // or use some other text here
Font = UIFont.SystemFontOfSize(14),
ShadowColor = Color.White.ToUIColor(),
ShadowOffset = new CoreGraphics.CGSize(0, 1),
TextColor = Color.DarkGray.ToUIColor(),
BackgroundColor = Color.Transparent.ToUIColor(),
Opaque = false,
TextAlignment = UITextAlignment.Center
};
}
//Retrieves the footer text for corresponding section through the attached property
public override string TitleForFooter(UITableView tableView, nint section)
{
var tblSection = View.Root[(int)section];
return Ex.GetFooterText(tblSection);
}
}
Sample Usage
<local:ExtFooterTableView x:Name="tableView" Intent="Settings" HasUnevenRows="True">
<TableSection Title="Cards1" local:Ex.FooterText="Sample description">
<ViewCell Height="50">
<Label Margin="20,0,20,0" Text="Hello1" />
</ViewCell>
<ViewCell Height="50">
<Label Margin="20,0,20,0" Text="Hello2" />
</ViewCell>
</TableSection>
<TableSection Title="Cards2" local:Ex.FooterText="Disclaimer note">
<TextCell Height="50" Text="Hello"></TextCell>
</TableSection>
</local:ExtFooterTableView>
It is very simple. you need to add the bindable property for pass value from XAML to CustomRenderer in CustomControl like this:
Customer TableView
public class ExtFooterTableView : TableView
{
public ExtFooterTableView()
{
}
}
Xaml control code
<local:ExtFooterTableView x:Name="tableView" Intent="Settings" HasUnevenRows="True">
Renderer class
using System;
using UIKit;
using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;
using yournamespace;
using System.ComponentModel;
[assembly: ExportRenderer(typeof(ExtFooterTableView), typeof(FooterTableViewRenderer))]
namespace yournamespace
{
public class FooterTableViewRenderer : TableViewRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<TableView> e)
{
base.OnElementChanged(e);
}
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
{
base.OnElementPropertyChanged(sender, e);
var view = (ExtFooterTableView)Element;
if (e.PropertyName == ExtFooterTableView.IntentProperty.PropertyName)
{
string intent = view.Intent;
// Do your stuff for intent property
}
if (e.PropertyName == ExtFooterTableView.HasUnevenRowsProperty.PropertyName)
{
bool hasUnevenRows = view.HasUnevenRows;
// Do yout stuff for HasUnevenRow
}
}
}
}
How can I make Label text Underline in WinPhone using Xamarin Forms ?
You have top create a new control in your PCL/shared project inheriting from Label.
public class Exlabel : Label
{
}
In your windows phone project create a Custom Renderer for it as follows and use the TextBlock.TextDecorations Property to set the underline.
The label is rendered as TextBlock in windows.
Sample (untested):
[assembly: ExportRenderer(typeof(Exlabel), typeof(ExlabelRenderer))]
namespace CustomRenderer.WinPhone81
{
public class ExlabelRenderer : LabelRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<Label> e)
{
base.OnElementChanged(e);
if (Control != null)
{
Control.TextDecorations = TextDecorations.UnderLine;
}
}
}
}
If you are using the windows phone check out this sample - How to format texts of TextBlock using xaml in Windows Phone.
For WinRT you can use this - TextBlock underline in WinRT.
In SilverLight WinPhone (the old and not so supported template), you can also use the Margin to achieve what you require, similar to How to make an underlined input text field in Windows Phone?.
Try using following xaml;
<StackLayout Orientation="Vertical">
<Label Text="SomeText"/>
<BoxView HeightRequest="1" HorizontalOptions="FillAndExpand" BackgroundColor="Black"/>
</StackLayout>
this should do it for all 3 platforms. :)
I think you need to create a custom view for this as a Layout/Grid that has a Label and a BoxView with a small heightRequest below the label to act as a line.
Create a label renderer in your WinPhone project:
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Documents;
[assembly: ExportRenderer(typeof(ExtendedLabel), typeof(ExtendedLabelRenderer))]
namespace SampleProject.WinPhone
{
public class ExtendedLabelRenderer: LabelRenderer
{
ExtendedLabel element;
TextBlock control;
protected override void OnElementChanged(ElementChangedEventArgs<Label> e)
{
base.OnElementChanged(e);
if((ExtendedLabel)Element == null || Control == null)
return;
element = (ExtendedLabel)Element;
control = Control;
UnderlineText();
}
void UnderlineText()
{
control.Text = string.Empty;
Underline ul = new Underline();
Run run = new Run();
run.Text = element.Text;
ul.Inlines.Add(run);
control.Inlines.Add(ul);
}
}
}
I have created a button in my xamarin application and have added an icon to it but there is too much of padding between the icon and the text as shown in the screenshot below.
How can I reduce this space between the two?
I have learnt about the custom renders for Xamarin.Android but its not working for me.
Following is the code for my custom renderer
[assembly: ExportRenderer(typeof(Button), typeof(ZeroPaddingRenderer))]
namespace MyApp.Droid
{
class ZeroPaddingRenderer : ButtonRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<Button> e)
{
base.OnElementChanged(e);
Control.SetPadding(0, Control.PaddingTop, 0, Control.PaddingBottom);
}
}
}
Here is the code for button
Button btn_login = new Button
{
VerticalOptions = LayoutOptions.Center,
Text = "Login",
};
btn_login.Image = "login.png";
Any help will be appreciated.