I'm trying to load icons into a ImageCell inside a ListView, but when I build my project the icon doesn't appear on the ImageCell.
Here's my project structure:
Here's my XAML page:
<?xml version="1.0" encoding="utf-8" ?>
<MasterDetailPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MyNotes.StartPage">
<MasterDetailPage.Master Title="Menu">
<ContentPage Title="Menu">
<StackLayout VerticalOptions="FillAndExpand">
<ListView x:Name="listViewMaster" VerticalOptions="FillAndExpand">
<ListView.ItemTemplate>
<DataTemplate>
<ImageCell Text="{Binding Title}" ImageSource="{Binding IconSource}" />
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
</ContentPage>
</MasterDetailPage.Master>
<MasterDetailPage.Detail>
<ContentPage>
</ContentPage>
</MasterDetailPage.Detail>
</MasterDetailPage>
And here's the code behind:
using System.Collections.Generic;
using Xamarin.Forms;
namespace MyNotes
{
public partial class StartPage : MasterDetailPage
{
public StartPage ()
{
InitializeComponent ();
List<MasterPageItem> masterPageItems = new List<MasterPageItem>()
{
new MasterPageItem()
{
Title = "Contacts",
IconSource = ImageSource.FromFile(#"c:\Projetos\MyNotes\MyNotes\MyNotes\Resources\image\contacts.png"),
TargetType = typeof(ContactPage)
},
new MasterPageItem()
{
Title = "Todo List",
IconSource = ImageSource.FromFile(#"Resources\image\todo.png"),
TargetType = typeof(TodoListPage)
},
new MasterPageItem()
{
Title = "Reminder",
IconSource = ImageSource.FromResource("Resources.image.reminder.png"),
TargetType = typeof(ContactPage)
}
};
listViewMaster.ItemsSource = masterPageItems;
}
}
}
What am I doing wrong?
The images go into your "native" projects:
Xamarin.iOS = BundledResource Build Type
Xamarin.Android = AndroidResource Build Type
IconSource = ImageSource.FromFile("SanFran.jpg")
or using the implicit conversion:
IconSource = "SanFran.jpg";
Working with Images
Have you marked the images that you added to the project as embedded reousrces?
embedded resource
Related
If you swipe several times on an already opening field, then after closing the swiped element will return to the position from which the last swipe was.
For example:
I upload project for replay problem: link
XAML 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="TestSwipeView.MainPage">
<CollectionView x:Name="collectionView"
ItemsSource="{Binding TestSequence}">
<CollectionView.ItemTemplate>
<DataTemplate>
<SwipeView>
<SwipeView.LeftItems>
<SwipeItems>
<SwipeItem Text="F"
BackgroundColor="LightGreen"/>
<SwipeItem Text="D"
BackgroundColor="LightPink"/>
</SwipeItems>
</SwipeView.LeftItems>
<Grid BackgroundColor="White"
Padding="10">
<Label Text="{Binding .}"></Label>
</Grid>
</SwipeView>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
</ContentPage>
Xaml.cs code:
namespace TestSwipeView
{
public partial class MainPage : ContentPage
{
public List<String> TestSequence { get; set; }
public MainPage()
{
TestSequence = new List<string>();
for (int i=0; i<10; i++)
{
TestSequence.Add(String.Format("Test {0}",i));
}
InitializeComponent();
this.BindingContext = this;
}
}
}
I tried to implement the package ZXing.Net.Mobile.Forms
this is my xaml:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:zxing="clr-namespace:ZXing.Net.Mobile.Forms;assembly=ZXing.Net.Mobile.Forms"
Title="{Binding Title}">
<ContentPage.Content>
<StackLayout>
<Label x:Name="scanResultText" />
<zxing:ZXingScannerView
OnScanResult="ScanViewOnScanResult"/>
</StackLayout>
</ContentPage.Content>
and this my xaml.cs :
public partial class QRCodePage : ContentPage
{
public QRCodePage()
{
InitializeComponent();
BindingContext = new QRCodeViewModel();
}
public void ScanViewOnScanResult(Result result)
{
Device.BeginInvokeOnMainThread(async () =>
{
scanResultText.Text = result.Text;
});
}
}
On my device i visualize the fragment but it seems not scanning
Try adding the following code (IsScanning="True") to your xaml:
<StackLayout>
<Label x:Name="scanResultText" />
<zxing:ZXingScannerView IsScanning="True"
OnScanResult="ScanViewOnScanResult"/>
</StackLayout>
Here's what I have right now:
I have this template that's simplified for the question:
<?xml version="1.0" encoding="UTF-8"?>
<Frame xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:t="clr-namespace:Japanese.Templates"
xmlns:local="clr-namespace:Japanese;assembly=Japanese"
x:Class="Japanese.Templates.RoundButtonText" x:Name="this">
<Label Text="ABC"
TextColor="{Binding LabelTextColor, Source={x:Reference this}}"
/>
</Frame>
and this C#
using Xamarin.Forms;
namespace Japanese.Templates
{
public partial class RoundButtonText : BaseFrameButtonTemplate
{
public RoundButtonText()
{
InitializeComponent();
// I would like to put the Label TextColor binding here instead of in the XAML
}
}
}
Can someone help me by telling me how I can add the binding for the label TextColor in the C# back end so that it changes in exactly the same way as it currently does when it's written as:
TextColor="{Binding LabelTextColor, Source={x:Reference this}}"
in XAML?
Remove the binding from the XAML and give the Label control an x:Name:
<?xml version="1.0" encoding="UTF-8"?>
<Frame xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:t="clr-namespace:Japanese.Templates"
xmlns:local="clr-namespace:Japanese;assembly=Japanese"
x:Class="Japanese.Templates.RoundButtonText" x:Name="this">
<Label x:Name="label"
Text="ABC" />
</Frame>
Set up the binding and the property to bind to in C# code behind:
using Xamarin.Forms;
namespace Japanese.Templates
{
public partial class RoundButtonText : BaseFrameButtonTemplate
{
Color _labelTextColor;
public Color LabelTextColor {
get {
return _labelTextColor;
}
set {
if (_labelTextColor != value) {
_labelTextColor = value;
OnPropertyChanged("LabelTextColor");
}
}
}
public RoundButtonText()
{
InitializeComponent();
label.BindingContext = this;
label.SetBinding(Label.TextColorProperty, "LabelTextColor");
}
}
}
Now whenever the LabelTextColor property value is changed, the Label's TextColor property should change as well, just like with a XAML binding.
I'm new enough to use Xamarin, in my Xamarin Forms project I created a Master-Detail Page and in the ListView that represents the menu I wanted to put Title and Icon, for icon images I have to insert each icon in all device projects?
And I also have a small problem, when I click on a menu item and navigate to the selected Detail page, the hamburger menu disappears
MainPageMaster.xaml
<?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="XXX"
Title="Master">
<StackLayout>
<ListView x:Name="MenuItemsListView"
SeparatorVisibility="None"
HasUnevenRows="true"
ItemsSource="{Binding MenuItems}">
<ListView.Header>
<Grid BackgroundColor="#03A9F4">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="6"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="6"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="15"/>
<RowDefinition Height="30"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="10"/>
</Grid.RowDefinitions>
<Label
Grid.Column="1"
Grid.Row="1"
Text="B1 Term"
HorizontalTextAlignment="Center"
Style="{DynamicResource SubtitleStyle}"/>
</Grid>
</ListView.Header>
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout VerticalOptions="FillAndExpand"
Orientation="Horizontal"
Padding="20,10,0,10"
Spacing="20">
<Image Source="{Binding Icon}"
WidthRequest="40"
HeightRequest="40"
VerticalOptions="Center" />
<Label Text="{Binding Title}"
FontSize="Medium"
VerticalOptions="Center"
TextColor="Black"/>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
</ContentPage>
File .cs
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class MainPageMaster : ContentPage
{
public ListView ListView;
public MainPageMaster()
{
InitializeComponent();
BindingContext = new MainPageMasterViewModel();
ListView = MenuItemsListView;
}
class MainPageMasterViewModel : INotifyPropertyChanged
{
public ObservableCollection<MainPageMenuItem> MenuItems { get; set; }
public MainPageMasterViewModel()
{
MenuItems = new ObservableCollection<MainPageMenuItem>(new[]
{
new MainPageMenuItem { Id = 0, Icon="ic_menu_home.png",Title = "Home", TargetType = typeof(MainPageDetail) },
new MainPageMenuItem { Id = 1, Title = "Elenco Clienti", TargetType = typeof(ElencoClientiPage) },
new MainPageMenuItem { Id = 2, Title = "Logout", TargetType = typeof(LogOut) }
});
}
#region INotifyPropertyChanged Implementation
public event PropertyChangedEventHandler PropertyChanged;
void OnPropertyChanged([CallerMemberName] string propertyName = "")
{
if (PropertyChanged == null)
return;
PropertyChanged.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
#endregion
}
}
Screen
In this image, my icon isn't visible but I add an image in Android project
Creating the master-detail page:
Add a content page and change the code as follows :
RootPage.xaml
<?xml version="1.0" encoding="utf-8"?>
<MasterDetailPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace: your_NameSpace"
x:Class="your_NameSpace.RootPage">
</MasterDetailPage>
RootPage.xaml.cs
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class RootPage : MasterDetailPage
{
public RootPage()
{
InitializeComponent();
}
}
Creating its Menu Page:
Add another content page and change the code as follows :
MenuPage.xaml (Design of the actual hamburger menu)
<?xml version="1.0" encoding="UTF-8"?>
<ContentPage BackgroundColor="White"
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="your_NameSpace.MenuPage">
<ContentPage.Padding >
<OnPlatform x:TypeArguments="Thickness" iOS=" 0 , 20 , 0 , 0" />
</ContentPage.Padding>
<ContentPage.Content>
<StackLayout BackgroundColor="White" Padding ="10 , 30 , 10, 10">
<Button Text="Login" BackgroundColor="White" TextColor="DarkGray" HorizontalOptions="StartAndExpand" Command="{Binding GoHomeCommand}" />
<BoxView HeightRequest="0.5" HorizontalOptions="FillAndExpand" BackgroundColor="Gray"/>
<Button Text="Search" BackgroundColor="White" TextColor="DarkGray" HorizontalOptions="StartAndExpand" Command="{Binding GoSecondCommand}" />
<BoxView HeightRequest="0.5" HorizontalOptions="FillAndExpand" BackgroundColor="Gray"/>
<Button Text="Browse" TextColor="DarkGray" BackgroundColor="White" HorizontalOptions="StartAndExpand" Command="{Binding GoThirdCommand}"/>
<BoxView HeightRequest="0.5" HorizontalOptions="FillAndExpand" BackgroundColor="Gray"/>
</StackLayout>
</ContentPage.Content>
MenuPage.xaml.cs
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class MenuPage : ContentPage
{
public MenuPage()
{
BindingContext = new MenuPageViewModel();
this.Icon = "yourHamburgerIcon.png"; //only neeeded for ios
InitializeComponent();
}
}
Its model class :
This is where the button click commands of the menu page are bound in
MenuPageViewModel.cs
public class MenuPageViewModel
{
public ICommand GoHomeCommand { get; set; }
public ICommand GoSecondCommand { get; set; }
public ICommand GoThirdCommand { get; set; }
public MenuPageViewModel()
{
GoHomeCommand = new Command(GoHome);
GoSecondCommand = new Command(GoSecond);
GoThirdCommand = new Command(GoThird);
}
void GoHome(object obj)
{
App.NavigationPage.Navigation.PopToRootAsync();
App.MenuIsPresented = false;
}
void GoSecond(object obj)
{
App.NavigationPage.Navigation.PushAsync(new Home()); //the content page you wanna load on this click event
App.MenuIsPresented = false;
}
void GoThird(object obj)
{
App.NavigationPage.Navigation.PushAsync(new ClinicInformation());
App.MenuIsPresented = false;
}
}
Add the following properties in your application class usually, the name for your application class is App.xaml and App.xaml.cs
Add the following to your App.xaml.cs:
public static NavigationPage NavigationPage { get; private set; }
public static RootPage RootPage;
public static bool MenuIsPresented
{
get
{
return RootPage.IsPresented;
}
set
{
RootPage.IsPresented = value;
}
}
Here RootPage is a static instance of your master-detail page,
NavigationPage is your detail page that you change to change your detail page,
IsMenuPresentend is the bool than when true keeps the MenuPage open and when false closes the same.
After doing all this add this function in your application class and call it in its constructor of your App.Xaml.cs
private void CallMain()
{
var menuPage = new MenuPage();
NavigationPage = new NavigationPage(new Home());
RootPage = new RootPage();
RootPage.Master = menuPage;
RootPage.Detail = NavigationPage;
MainPage = RootPage;
}
In your Android project add the following theme:
values/styles.xml
<?xml version="1.0" encoding="utf-8" ?>
<resources>
<style name="MyTheme" parent="MyTheme.Base">
</style>
<style name="DrawerArrowStyle"
parent="#style/Widget.AppCompat.DrawerArrowToggle">
<item name="spinBars">true</item>
<item name="color">#FFFFFF</item>
</style>
<style name="MyTheme.Base" parent="Theme.AppCompat.Light.DarkActionBar">
<item name="windowNoTitle">true</item>
<item name="windowActionBar">false</item>
<item name="colorPrimary">#003399</item>
<item name="colorPrimaryDark">#003399</item>
<item name="colorControlHighlight">#003399</item>
<item name="colorAccent">#012348</item>
<item name="drawerArrowStyle">#style/DrawerArrowStyle</item>
</style>
</resources>
Create a folder named values-v21 and add an XML named styles.xml and add the following code to it :
<?xml version="1.0" encoding="utf-8" ?>
<resources>
<style name="MyTheme" parent="MyTheme.Base">
<item name="android:windowContentTransitions">true</item>
<item name="android:windowAllowEnterTransitionOverlap">true</item>
<item name="android:textAllCaps">false</item>
<item name="android:windowAllowReturnTransitionOverlap">true</item>
<item name="android:windowSharedElementEnterTransition">#android:transition/move</item>
<item name="android:windowSharedElementExitTransition">#android:transition/move</item>
</style>
</resources>
And use the name myTheme as the app theme in all your Android activities.
There you go your hamburger menu is complete in case you have any queries feel free to comment.
Good luck!
Happy Coding.
You can try this as well for detailed information
Hamburger Menu tutorial
To show Humberger menu icon in Android and iOS application you can use Title = "☰" a special character. This going to show menu icon properly.
<MasterDetailPage.Master>
<ContentPage Title = "☰" BackgroundColor="Red">
<StackLayout BackgroundColor = "#B2EC5D" >
< ListView x:Name="navigationDrawerList">
</ListView>
</StackLayout>
</ContentPage>
</MasterDetailPage.Master>
Below is my code that does not work could you spot what is wrong?
I am trying to convert this to prism
https://github.com/xamarin/xamarin-forms-samples/tree/master/Navigation/MasterDetailPage
I keep getting
"System.InvalidOperationException:
PushAsync is not supported globally on Android, please use a NavigationPage."
I am using a navigationpage(I think I do)
Could somebody look at the code .Below is all the code and tell me what Am I doing wrong??
many thanks!
app.cs
public partial class App : PrismApplication
{
public App(IPlatformInitializer initializer = null) : base(initializer) { }
protected override void OnInitialized()
{
InitializeComponent();
NavigationService.NavigateAsync("MainPage/Navigation/ContactsPage");
}
protected override void RegisterTypes()
{
//Container.RegisterTypeForNavigation<NavigationPage>("Navigation");
Container.RegisterTypeForNavigation<MainNavigationPage>("Navigation");
Container.RegisterTypeForNavigation<MainPage,MainPageViewModel>();
Container.RegisterTypeForNavigation<ContactsPage,ContactsPageViewModel>();
Container.RegisterTypeForNavigation<MasterPage,MasterPageViewModel>();
Container.RegisterTypeForNavigation<ReminderPage,ReminderPageViewModel>();
Container.RegisterTypeForNavigation<TodoListPage,TodoListPageViewModel>();
}
}
MainNavigationPage.Xaml
<?xml version="1.0" encoding="utf-8" ?>
<NavigationPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:prism="clr-namespace:Prism.Mvvm;assembly=Prism.Forms"
prism:ViewModelLocator.AutowireViewModel="True"
x:Class="MasterDetailReferenceApp.Views.MainNavigationPage">
</NavigationPage>
MainPage.Xaml
<?xml version="1.0" encoding="utf-8" ?>
<MasterDetailPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:prism="clr-namespace:Prism.Mvvm;assembly=Prism.Forms"
xmlns:views="clr-namespace:MasterDetailReferenceApp.Views;assembly=MasterDetailReferenceApp"
prism:ViewModelLocator.AutowireViewModel="True"
x:Class="MasterDetailReferenceApp.Views.MainPage"
Title="MainPage">
<MasterDetailPage.Master>
<views:MasterPage x:Name="masterPage" />
</MasterDetailPage.Master>
<MasterDetailPage.Detail>
<NavigationPage>
<x:Arguments>
<views:ContactsPage />
</x:Arguments>
</NavigationPage>
</MasterDetailPage.Detail>
MainPage.cs
public partial class MainPage : MasterDetailPage,IMasterDetailPageOptions
{
public MainPage()
{
InitializeComponent();
}
public bool IsPresentedAfterNavigation => Device.Idiom != TargetIdiom.Phone;
}
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:prism="clr-namespace:Prism.Mvvm;assembly=Prism.Forms"
prism:ViewModelLocator.AutowireViewModel="True"
x:Class="MasterDetailReferenceApp.Views.MasterPage"
Icon="hamburger.png"
Title="Personal Organiser">
<ContentPage.Content>
<StackLayout VerticalOptions="FillAndExpand">
<ListView x:Name="listView"
RowHeight="60"
SeparatorVisibility="None"
BackgroundColor="White"
HasUnevenRows="true"
ItemSelected="OnMenuItemSelected">
>
<ListView.ItemTemplate>
<DataTemplate>
<ImageCell Text="{Binding Title}" ImageSource="{Binding IconSource}" />
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
</ContentPage.Content>
</ContentPage>
MasterPage.cs
public partial class MasterPage : ContentPage
{
public ListView ListView => listView;
public MasterPage()
{
InitializeComponent();
var masterPageItems = new List<MasterPageItem>();
masterPageItems.Add(new MasterPageItem
{
Title = "Contacts",
//Uri = "ContactsPage",
Uri = "Navigation/ContactsPage",
IconSource = "contacts.png",
TargetType = typeof(ContactsPage)
});
masterPageItems.Add(new MasterPageItem
{
Title = "TodoList",
Uri = "Navigation/TodoListPage",
//Uri = "TodoListPage",
IconSource = "todo.png",
TargetType = typeof(TodoListPage)
});
masterPageItems.Add(new MasterPageItem
{
Title = "Reminders",
Uri = "Navigation/RemindersPage",
IconSource = "reminders.png",
TargetType = typeof(ReminderPage)
});
listView.ItemsSource = masterPageItems;
}
private void OnMenuItemSelected(object sender, SelectedItemChangedEventArgs e)
{
var item = (MasterPageItem)e.SelectedItem;
((MasterPageViewModel)BindingContext).NavigateCommand.Execute(item.Uri);
}
}
MasterPageItem
public class MasterPageItem
{
public string Title { get; set; }
public string Uri { get; set; }
public string IconSource { get; set; }
}
You need to set some NavigationPage as Detail for MasterDetailPage. Like this:
<MasterDetailPage.Detail>
<NavigationPage BarTextColor="White">
<x:Arguments>
<local:StatisticsPage />
</x:Arguments>
</NavigationPage>
</MasterDetailPage.Detail>
In this example first page in navigation page will be StatisticsPage.
Then, from StatisticsPageViewModel you can do
await _navigationService.NavigateAsync(new Uri(navParam, UriKind.Relative), useModalNavigation: isModal);
where navParam is nameof(SettingsPage). That will switch NavigationPage content to SettingsPage.
If you want to navigate away from MasterDetailPage then do
await NavigationService.NavigateAsync(nameof(OtherNonMasterDetailPage));
from your MasterDetailPageViewModel (not from the NavigationPage content's view model)