Button image Xamarin.forms - image

The Image Source="icons.png" works fine
but when i insert this code: Button Image="icons.png"
the App won't display in the Xamarin live
This is my code:
<?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="Project.CustomImages">
<StackLayout>
<Button Image="icons.png"/>
<Label Text="TEST"/>
<Image Source="icons.png"/>
</StackLayout>
</ContentPage>
This is the screen shot of Recources/drawable:
Screenshot

Try to place an image instead of button.
You can make use of Tap Gesture Recogniser to take click events.
Try something like this :
<Image Source="icons.jpg">
<Image.GestureRecognizers>
<TapGestureRecognizer
Tapped="OnTapped" />
</Image.GestureRecognizers>
</Image>
The code for the event handler
void OnTapped(object sender, EventArgs args) {
// Do something
DisplayAlert ("Alert", "Image Button Clicked", "OK");
}

Related

How to bind a nested Layout with external ContentView in Xamarin.Forms?

I have a Page with a StackLayout using BindableLayout.ItemsSource, inside each item I have a ListView, for each item in this nested ListView I need to do a Binding to a property on the Page's ViewModel. I'm trying to use the Source+Path approach but the app crashes as soon as I open the page that contains this structure.
MainPage.xaml:
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage
x:Class="BindableLayoutReferenceBug.ListViewPage"
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:BindableLayoutReferenceBug">
<StackLayout BindableLayout.ItemsSource="{Binding Items}">
<BindableLayout.ItemTemplate>
<DataTemplate>
<local:MessageListViewTemplate />
</DataTemplate>
</BindableLayout.ItemTemplate>
</StackLayout>
</ContentPage>
MessageListViewTemplate.xaml:
<?xml version="1.0" encoding="UTF-8" ?>
<ContentView
x:Class="BindableLayoutReferenceBug.MessageListViewTemplate"
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Name="listView">
<ListView ItemsSource="{Binding Options}">
<ListView.ItemTemplate>
<DataTemplate>
<StackLayout>
<Label Text="{Binding .}" />
<Button
BackgroundColor="Blue"
Command="{Binding Source={x:Reference Name=listView}, Path=Parent.BindingContext.ShowMessageCommand}"
CommandParameter="{Binding .}"
Text="Show Message" />
</StackLayout>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</ContentView>
The exception shows that there is a problem finding the reference to the x:Name I used: Can not find the object referenced by listView
This only happens when I have a nested structure as I mentioned (StackLayout with BindableLayout > ListView). I'm not sure if this is not a supported scenario or if it is a bug.
I tried using different Paths for the binding, but since this is a problem parsing the XAML not finding the x:Name referenced, I don't think it even starts evaluating my Path.
Am I doing something wrong or is this a bug in Xamarin.Forms?
Xamarin.Forms version used: 3.6.0.293080
Repro sample: https://github.com/akamud/BindableLayoutReferenceBug
Maybe, x:Name wasn't recognized at runtime even though you have set it to your content view in XAML. You could raise an issue on GitHub.
Here I tried this binding using code behind and it works fine. You could use it as an alternative:
public MessageListViewTemplate()
{
InitializeComponent();
listView.ItemTemplate = new DataTemplate(() =>
{
ViewCell viewCell = new ViewCell();
Label label = new Label();
label.SetBinding(Label.TextProperty, new Binding("."));
Button button = new Button() { Text = "Show Message", BackgroundColor = Color.Blue };
button.SetBinding(Button.CommandProperty, new Binding("Parent.BindingContext.ShowMessageCommand", source: ContentView));
button.SetBinding(Button.CommandParameterProperty, new Binding("."));
viewCell.View = new StackLayout
{
Children =
{
label,
button
}
};
return viewCell;
});
}
XAML:
<ContentView xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="BindableLayoutReferenceBug.MessageListViewTemplate"
x:Name="ContentView">
<StackLayout>
<ListView ItemsSource="{Binding Options}" x:Name="listView" HasUnevenRows="True">
</ListView>
</StackLayout>
</ContentView>
Here, I defined the parent content view as ContentView and named ListView listView.
Please notice that the list view's data template should be a view cell. So I used a view cell to wrap the content here.
It was a bug after all, it is now fixed and the above should work: https://github.com/xamarin/Xamarin.Forms/issues/6192

Issues with displaying a popup

I am using the Rg.Plugins.Popup plugin for displaying a popup on a tap. My issue is how to call a popuppage from a viewmodel class? (I am using MVVM)
I am using the following code in viewmodel for the tap handler:
public async void OnForgotPasswordAsync()
{
await Application.Current.MainPage.Navigation.PushPopupAsync(new ForgotPassword());
}
This is a Command
Here I have the view class for the popuppage
<?xml version="1.0" encoding="UTF-8"?>
<pages:PopupPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="WeHelp.View.ForgotPassword"
xmlns:pages="clr-namespace:Rg.Plugins.Popup.Pages;assembly=Rg.Plugins.Popup">
<StackLayout Margin="12" Padding="24" BackgroundColor="White" HorizontalOptions="CenterAndExpand" VerticalOptions="CenterAndExpand">
<StackLayout>
<Label Text="Please type your Email. Once you click on 'Send', please check your inbox or spam folder" />
<Entry Placeholder="Email" Keyboard="Email"/>
</StackLayout>
<Button Text="Send" Command="{Binding SendPassword}"/>
</StackLayout>
</pages:PopupPage>
So, my problem occurs at the command
await Application.Current.MainPage.Navigation.PushPopupAsync(new ForgotPassword());
I get the error Argument 2: cannot convert from 'WeHelp.View.ForgotPassword' to 'Rg.Plugins.Popup.Pages.PopupPage'
change your xaml to something like this
<pages:PopupPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:pages="clr-namespace:Rg.Plugins.Popup.Pages;assembly=Rg.Plugins.Popup"
xmlns:animations="clr-
namespace:Rg.Plugins.Popup.Animations;assembly=Rg.Plugins.Popup"
x:Class="HealthMobile.PopPages.ForgotPassowordPop">
</pages:PopupPage>
and page.cs to
public partial class ForgotPassowordPop : PopupPage
{
}

How to add entry inside picker popup? Xamarin Forms

I have a picker with more than one hundred data. I want to search a particular item. How can I add a entry inside a picker popup? Is it possible? If not, What are the best alternative to search data inside a picker?
What you want might be able to be done via custom renderer, but I personally don't know how that would be done...
If you want custom functionality in a picker, I highly recommend Rg.Plugins.Popup. This package allows a user to define there own custom popup. I use this for all my Popup pages/controls in the application I develop.
GitHub: Rg.Plugins.Popup
Define a PopupPage with an Entry and ListView and you can provide the kind of functionality you are wanting.
There is no out of the box solution for this. But a picker with searchbar can be implemented with rg.plugins.popup.(https://github.com/rotorgames/Rg.Plugins.Popup).
Create a view with label and down arrow.Provide click for that.In that click event call rg.popup.
The design of popup for referance.
<?xml version="1.0" encoding="utf-8" ?>
<pages:PopupPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="iVerify.Sample"
xmlns:pages="clr-namespace:Rg.Plugins.Popup.Pages;assembly=Rg.Plugins.Popup"
xmlns:animations="clr-namespace:Rg.Plugins.Popup.Animations;assembly=Rg.Plugins.Popup"
BackgroundColor="Transparent" >
<pages:PopupPage.Animation>
<animations:ScaleAnimation
PositionIn="Center"
PositionOut="Center"
ScaleIn="1.2"
ScaleOut="0.8"
DurationIn="400"
DurationOut="300"
EasingIn="SinOut"
EasingOut="SinIn"
HasBackgroundAnimation="False"/>
</pages:PopupPage.Animation>
<StackLayout VerticalOptions="Center" Padding="10" HorizontalOptions="FillAndExpand" Margin="0,20,0,0" >
<StackLayout>
<SearchBar x:Name="Searchbar" />
</StackLayout>
<StackLayout>
<ListView x:Name="ListView" ItemsSource="{Binding}"
ItemSelected="List_Tapped">
ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<ViewCell.View>
// Your controls
</ViewCell.View>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
</StackLayout>
</StackLayout>
</pages:PopupPage>
By using Itemselected property you can get the value of tapped view. Then set it to the label of Mainpage(label that clciked to open the popup).This can be achieved by messeging centre.
Sample screenshot
I did it with Telerik though it didn't launch on Android in main project for me and the dropdown behaves strange on UWP - it is dropping up instead of down for some layout constellations.
Telerik is not free though, so if you have it you can use:
<StackLayout Orientation="Horizontal"
VerticalOptions="FillAndExpand"
HorizontalOptions="FillAndExpand">
<telerikInput:RadAutoCompleteView x:Name="autoCompleteView"
HorizontalOptions="FillAndExpand"
ShowSuggestionView="True"
ShowMoreItems="True"
SuggestMode="Suggest"
Watermark="Search here..." />
<Button Clicked="Button_Clicked"
Text="▼"/>
</StackLayout>
and in code behind
private void Button_Clicked(object sender, System.EventArgs e)
{
autoCompleteView.ShowSuggestions();
}

Show contentview on frame tapgesture

I am developing a cross platform app using xaml forms and have yet to figured out how to call a ContentView ontapGesture. I am able to call ContentView on xaml forms using <local:MailRoomList/> but I cant show a view ontap or on click event.
I have tried to show view on stacklayout using StackLayoutID.Children.Add(new MailRoomList()); but thats not what I want. I want to show full contentview on content page with back button enabled.
Please advise. Thank you
MailRoomList
<?xml version="1.0" encoding="UTF-8"?>
<ContentView xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="xx.xxxx.xx.Views.MailRoomList">
<ContentView.Content>
<StackLayout>
<Label Text="This is my MailRoom List" />
</StackLayout>
</ContentView.Content>
</ContentView>
OnTapGesture
<Frame.GestureRecognizers>
<TapGestureRecognizer Tapped="OnRegisterMail" NumberOfTapsRequired="1"/>
</Frame.GestureRecognizers>
CodeBehind
async void OnRegisterMail(object sender, EventArgs e)
{
await Navigation.PushAsync(new MailRoomList());
}
Edit:
Home Page
<?xml version="1.0" encoding="utf-8" ?>
<xf1:BottomBarPage
xmlns:xf1="clr-namespace:xx.xxxx.xx.BottomBar"
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:xx.xxxx.xx.Views"
x:Class="xx.xxxx.xx.Views.Home">
<ContentPage x:Name="MailRoomPage" Title="MailRoom" Icon="mailroom.png" xf1:BottomBarPageExtensions.TabColor="Orange" xf1:BottomBarPageExtensions.BadgeCount="5">
<local:MailRoom/>
</ContentPage>
<ContentPage Title="Transport" Icon="transport.png" xf1:BottomBarPageExtensions.TabColor="Green" xf1:BottomBarPageExtensions.BadgeCount="10">
<Label VerticalOptions="Center" HorizontalTextAlignment="Center" Text="Transport" FontSize="Large"/>
</ContentPage>
<ContentPage Title="Communication" Icon="communication.png" xf1:BottomBarPageExtensions.TabColor="Blue" xf1:BottomBarPageExtensions.BadgeCount="3">
<Label VerticalOptions="Center" HorizontalTextAlignment="Center" Text="Communication" FontSize="Large"/>
</ContentPage>
<ContentPage Title="HSE" Icon="hse.png" xf1:BottomBarPageExtensions.TabColor="Red" xf1:BottomBarPageExtensions.BadgeCount="2">
<Label VerticalOptions="Center" HorizontalTextAlignment="Center" Text="HSE" FontSize="Large"/>
</ContentPage>
<ContentPage Title="Meeting" Icon="meeting.png" xf1:BottomBarPageExtensions.TabColor="DarkCyan" xf1:BottomBarPageExtensions.BadgeCount="5">
<Label VerticalOptions="Center" HorizontalTextAlignment="Center" Text="Meeting" FontSize="Large"/>
</ContentPage>
From homepage above I am calling my view <local:MailRoom/> which is calling another view MailRoomList. This is where I need your advice on how to call a content view from another content view.
ContentView is a View not a Page. Change your MainRoomList Xaml to 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="xx.xxxx.xx.Views.MailRoomList">
<StackLayout>
<Label Text="This is my MailRoom List" />
</StackLayout>
</ContentPage>
View's dont support navigation, they can only be navigated to if they belong to a Page which are the objects that contain the navigation infrastructure.
IF you want to mantain your MailRoomList as a ContentView, then you need to include her in some other page, and perform the navigation ( inside the tap method ) to that other page

Xamarin Forms TableView selected item handler?

I need to trigger a command when user clicks on the table cell.
I looked at documentation on tablecell, it doesn't talk about any click event handlers.
This is how my XAML looks -
<ContentPage Title="Default">
<TableView>
<TableView.Root>
<TableSection>
<ViewCell>
<StackLayout Padding="10,0,0,0" Orientation="Horizontal">
<Image Source="..." />
<Button Text="Home" Command="{Binding NavigateCommand}" CommandParameter="Home" />
</StackLayout>
</ViewCell>
</TableSection>
</TableView.Root>
</TableView>
</ContentPage>
Right now, command is triggered only when clicked on button, but I want to trigger command when the cell is clicked.
I am new to xamarin, is custom viewcell rendering the only way to achieve this?
If so, any pointers there?
Thanks!
You can use the Tapped gesture recognizer within a ViewCell.
Xaml:
<TableView>
<TableView.Root>
<TableSection>
<ViewCell Tapped="OnViewCellTapped">
~~~~~
</ViewCell>
</TableSection>
</TableView.Root>
</TableView>
Code behind:
protected void OnViewCellTapped(object sender, EventArgs e)
{
System.Diagnostics.Debug.WriteLine("Tapped");
}

Resources