Getting StateLayout with CustomState to show image thumbnail - xamarin

In my Xamarin Forms 5 app, I have a form users will fill out to create a post -- similar to Facebook posts.
The effect I'm trying to create is this:
There's an "Add Image" button that allows user to upload an image. Once the image is uploaded, I want to no longer display the button but display a thumbnail version of the uploaded image.
Here's what my XAML looks like:
<StackLayout
xct:StateLayout.CurrentState="{Binding MainState.None}"
xct:StateLayout.CurrentCustomStateKey="{Binding PostImageState}">
<xct:StateLayout.StateViews>
<xct:StateView StateKey="Custom" CustomStateKey="Image set">
<Image
Grid.Row="0"
Grid.Column="0"
Source="{Binding PostImageUrl}"
WidthRequest="30"
HeightRequest="30"/>
</xct:StateView>
</xct:StateLayout.StateViews>
<Button
Text="Add Image"
Command="{Binding AddImageCommand}"
BackgroundColor="{StaticResource SecondaryBackground}"
WidthRequest="100"
HeightRequest="35"
HorizontalOptions="Start"
Margin="10,0,0,0"/>
</StackLayout>
Here's an abbreviated version of my view model:
public class MyViewModel : BaseViewModel
{
public LayoutState _mainState;
string postImageUrl { get; set; }
string postImageState { get; set; } = "No image";
public MyViewModel()
{
Title = string.Empty;
IsBusy = true;
MainState = LayoutState.None;
AddImageCommand = new AsyncCommand(Add_Image_Tapped);
}
public LayoutState MainState
{
get => _mainState;
set => SetProperty(ref _mainState, value);
}
public string PostImageUrl
{
get => postImageUrl;
set
{
if (postImageUrl == value)
return;
postImageUrl = value;
OnPropertyChanged();
}
}
public string PostImageState
{
get => postImageState;
set
{
if (postImageState == value)
return;
postImageState = value;
OnPropertyChanged();
}
}
async Task Add_Image_Tapped()
{
// Upload image
// Once upload is done
PostImageUrl = uploadedFileUrl;
PostImageState = "Image set";
}
}
I haven't been able to get this to work. Currently, it's not even showing the "Add Image" button. Where am I making a mistake?

There are several problems with your code.
1.Since you use Binding for xct:StateLayout.CurrentState, we should bind it to a variable in ViewModel, here we should use MainState not MainState.None:
xct:StateLayout.CurrentState="{Binding MainState}"
2.Based on your requirement, we can use the value from LayoutState enumeration(for example StateKey="Success"),, we don't need add custom states.
3.If we want to hidden the button once uploading the image, we can bind MainState to property IsVisible of button , but need use Converter StateToBooleanConverter to convert State to bool.
Based on your code ,I created a simple demo, and it works properly on my side.
You can refer to the following code:
MyPage.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"
xmlns:xct="http://xamarin.com/schemas/2020/toolkit"
xmlns:viewmodel="clr-namespace:FormApp0314.ViewModel"
x:Class="FormApp0314.TestPage1">
<ContentPage.BindingContext>
<viewmodel:MyViewModel></viewmodel:MyViewModel>
</ContentPage.BindingContext>
<ContentPage.Resources>
<xct:StateToBooleanConverter x:Key="StateToBooleanConverter" />
</ContentPage.Resources>
<StackLayout
xct:StateLayout.CurrentState="{Binding MainState}">
<xct:StateLayout.StateViews>
<xct:StateView StateKey="Success" CustomStateKey="Image set">
<Image
Grid.Row="0"
Grid.Column="0"
Source="{ Binding PostImageUrl}"
WidthRequest="60"
HeightRequest="60"/>
</xct:StateView>
</xct:StateLayout.StateViews>
<Button
Text="Add Image"
Command="{Binding AddImageCommand}"
IsVisible="{Binding MainState, Converter={StaticResource StateToBooleanConverter}, ConverterParameter={x:Static xct:LayoutState.None}}"
WidthRequest="100"
HeightRequest="35"
HorizontalOptions="Start"
Margin="10,0,0,0" />
</StackLayout>
</ContentPage>
MyViewModel.cs
public class MyViewModel: BaseViewModel
{
public LayoutState _mainState;
string postImageUrl;
string postImageState = "No image";
public ICommand AddImageCommand { get; }
public MyViewModel()
{
MainState = LayoutState.None;
PostImageUrl = "bell.png";
AddImageCommand = CommandFactory.Create(Add_Image_Tapped);
}
async Task Add_Image_Tapped()
{
MainState = LayoutState.Success;
await Task.Delay(3000);
MainState = LayoutState.None;
}
public LayoutState MainState
{
get => _mainState;
set => SetProperty(ref _mainState, value);
}
public string PostImageUrl
{
get => postImageUrl;
set => SetProperty(ref postImageUrl, value);
}
public string PostImageState
{
get => postImageState;
set => SetProperty(ref postImageState, value);
}
}

Related

CollectionView SelectionChange event not working properly in Android (.Net MAUI)

I'm trying to create custom tabs control in .Net MAUI, for that, I had first tried it with ScrollView and BindableStackLayout control but in that, I'm facing a problem.
Reported here Custom tabs with ScrollView bug
So, as an alternative approach or work-around, I have tried to develop the same Tabs control using CollectionView.
This alternative approach is working fine in iOS but not working properly in Android.
There is one problem that is common in both Android and iOS. I have taken BoxView control as an Indicator for the selected tab. That I'm going to show only for the Selected tab but this just shows in the first tab, when I click on other tabs the tabs get changed but it does not get hidden from the first tab and get visible in the other selected tab.
I have used the visual state manager with white color for the selected state because it gives looks like an indicator which I',m trying to create using BoxView. But this also shows Selected item for Android only when that view gets loads for iOS I have to select the tab first then only it shows the selected color there.
Here is what I have done:
MainPage.xaml
<ContentPage.Content>
<Grid RowDefinitions="50, *" RowSpacing="0">
<CollectionView x:Name="TabsView"
Grid.Row="0"
ItemsSource="{Binding Tabs,Mode=TwoWay}"
ItemsUpdatingScrollMode="KeepItemsInView"
ItemSizingStrategy="MeasureAllItems"
SelectedItem="{Binding SelectedTab}"
SelectionChangedCommand="{Binding Path=BindingContext.TabChangedCommand,Source={x:Reference TabsView}}"
SelectionChangedCommandParameter="{Binding SelectedTab}"
SelectionMode="Single">
<CollectionView.ItemsLayout>
<LinearItemsLayout Orientation="Horizontal"/>
</CollectionView.ItemsLayout>
<CollectionView.ItemTemplate>
<DataTemplate>
<Grid RowSpacing="0" RowDefinitions="*, 3">
<Label Grid.Row="0"
Text="{Binding TabTitle}"
TextColor="White"
BackgroundColor="navy"
Padding="20,0"
VerticalTextAlignment="Center"
HorizontalTextAlignment="Center"
FontSize="12" />
<BoxView Grid.Row="1" Color="{Binding BoxColor}"
IsVisible="{Binding IsSelected}"/>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup Name="CommonStates">
<VisualState Name="Normal"/>
<VisualState Name="Selected">
<VisualState.Setters>
<Setter Property="BackgroundColor" Value="White" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Grid>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
<tabs:ParentRecordTabView Grid.Row="1"
IsVisible="{Binding IsParentRecordTabVisible}"
VerticalOptions="FillAndExpand"/>
<tabs:AdditionalInfoTabView Grid.Row="1"
IsVisible="{Binding IsAdditionalInfoTabVisible}"
VerticalOptions="FillAndExpand" />
</Grid>
</ContentPage.Content>
MainPageViewModel.cs
public class MainPageViewModel : BaseViewModel
{
public MainPageViewModel()
{
GetTabs();
}
private bool _isParentRecordTabVisible = true;
private bool _isAdditionalInfoTabVisible;
private ObservableCollection<TabViewModel> _tabs { get; set; }
private TabViewModel _selectedTab { get; set; }
public bool IsParentRecordTabVisible
{
get => _isParentRecordTabVisible;
set { _isParentRecordTabVisible = value; OnPropertyChanged(nameof(IsParentRecordTabVisible)); }
}
public bool IsAdditionalInfoTabVisible
{
get => _isAdditionalInfoTabVisible;
set { _isAdditionalInfoTabVisible = value; OnPropertyChanged(nameof(IsAdditionalInfoTabVisible)); }
}
public ObservableCollection<TabViewModel> Tabs
{
get => _tabs;
set { _tabs = value; OnPropertyChanged(nameof(Tabs)); }
}
public TabViewModel SelectedTab
{
get => _selectedTab;
set
{
_selectedTab = value;
OnPropertyChanged(nameof(SelectedTab));
}
}
public ICommand TabChangedCommand { get { return new Command<TabViewModel>(ChangeTabClick); } }
private void GetTabs()
{
Tabs = new ObservableCollection<TabViewModel>();
Tabs.Add(new TabViewModel { TabId = 1, IsSelected = true, TabTitle = "Parent record" });
Tabs.Add(new TabViewModel { TabId = 2, TabTitle = "Additional Info" });
Tabs.Add(new TabViewModel { TabId = 3, TabTitle = "Contacts" });
Tabs.Add(new TabViewModel { TabId = 4, TabTitle = "Previous inspections" });
Tabs.Add(new TabViewModel { TabId = 5, TabTitle = "Attachments" });
SelectedTab = Tabs.FirstOrDefault();
}
public void ChangeTabClick(TabViewModel tab)
{
Tabs.All((arg) =>
{
if (arg.TabId == tab.TabId)
{
arg.IsSelected = true;
}
else
{
arg.IsSelected = false;
}
return true;
});
SelectedTab = Tabs.Where(t => t.IsSelected == true).FirstOrDefault();
switch (SelectedTab.TabId)
{
case 1:
IsParentRecordTabVisible = true;
IsAdditionalInfoTabVisible = false;
break;
case 2:
IsParentRecordTabVisible = false;
IsAdditionalInfoTabVisible = true;
break;
}
}
}
TabViewModel.cs
public class TabViewModel : BaseViewModel
{
private bool _IsSelected;
public bool IsSelected
{
get { return _IsSelected; }
set
{
_IsSelected = value;
OnPropertyChanged(nameof(IsSelected));
}
}
private int _TabId;
public int TabId
{
get { return _TabId; }
set
{
_TabId = value;
OnPropertyChanged(nameof(TabId));
}
}
private string _TabTitle;
public string TabTitle
{
get { return _TabTitle; }
set
{
_TabTitle = value;
OnPropertyChanged(nameof(TabTitle));
}
}
}
Note: This same approach again works fine in Xamarin.Forms (Visual Studio 2019), this just not working in MAUI, so does anyone notice something like this?
How to Reproduce error: check github
Remove the BoxView default style in your project. Resource> Styles> Styles.xml
<Style TargetType="BoxView">
<Setter Property="Color" Value="{AppThemeBinding Light={StaticResource Gray950}, Dark={StaticResource Gray200}}" />
You could use the IsVisible property to show the BoxView or not instead of binding color with BoxColor. Remove the SelectionChangedCommand, SelectionChangedCommandParameter and VisualStateManager.VisualStateGroups in CollectionView as well.
<BoxView Grid.Row="1"
Color="Yellow"
IsVisible="{Binding IsSelected}"/>
Set the SelectedTab property like below.
public TabViewModel SelectedTab
{
get => _selectedTab;
set
{
_selectedTab = value;
SetSelection();
OnPropertyChanged(nameof(SelectedTab));
}
}
private void SetSelection()
{
foreach (var item in Tabs)
{
item.IsSelected = false;
}
SelectedTab.IsSelected = true;
}

Custom entry null xamarin

I created a custom entry in my Login page, but its getting null
I just created hte CustomEntry class and the CustomEntryRenderer, and put in the xaml file
My Login page .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"
xmlns:custom="clr-namespace:HCTaNaMao.Customs"
x:Class="HCTaNaMao.Views.Login">
<ContentPage.Content>
<StackLayout VerticalOptions="FillAndExpand" Padding="0,100,0,0">
<Image Source="HCbackground.png" VerticalOptions="Center" HeightRequest="200" />
<Label Text="Usuario" HorizontalTextAlignment="Center"/>
<custom:CustomEntry
x:Name=" usernameEntry"
CornerRadius="18"
IsCurvedCornersEnabled="True"
BorderColor="LightBlue"
HorizontalTextAlignment="Start"
FontSize="17"
HeightRequest="40"
Placeholder="Usuário"
PlaceholderColor="LightGray"
TextColor="Black"
FontAttributes="Bold"
WidthRequest="100"/>
<Label Text="Senha" HorizontalTextAlignment="Center"/>
<custom:CustomEntry
x:Name=" passwordEntry"
CornerRadius="18"
IsCurvedCornersEnabled="True"
BorderColor="LightBlue"
HorizontalTextAlignment="Start"
FontSize="17"
HeightRequest="40"
Placeholder="Senha"
PlaceholderColor="LightGray"
TextColor="Black"
FontAttributes="Bold"
WidthRequest="100"
IsPassword="True"/>
<Button Text="Entrar" TextColor="White" Clicked="LoginUser" WidthRequest="110"
HorizontalOptions="Center" BackgroundColor="SteelBlue" BorderRadius="20"/>
<Label x:Name="messageLabel" />
</StackLayout>
</ContentPage.Content>
</ContentPage>
My Login page .xaml.cs
namespace HCTaNaMao.Views
{
public partial class Login : ContentPage
{
public static int seq_cliente;
public Login ()
{
InitializeComponent ();
usernameEntry.ReturnCommand = new Command(() => passwordEntry.Focus());
}
async void LoginUser(object sender, EventArgs e)
{
if (string.IsNullOrEmpty(usernameEntry.Text) || string.IsNullOrEmpty(passwordEntry.Text))
{
if (string.IsNullOrEmpty(usernameEntry.Text))
await DisplayAlert("Usuario", "Digite o Usuario", "OK");
else
await DisplayAlert("Senha", "Digite a Senha", "OK");
return;
}
HCTMWebService service = new HCTMWebService();
seq_cliente = service.Login(usernameEntry.Text.ToUpper());
if (seq_cliente > 0)
await Navigation.PopModalAsync();
else
await DisplayAlert("Erro Login", "Usuario ou Senha errado", "OK");
}
protected override bool OnBackButtonPressed()
{
#if __ANDROID__
Android.OS.Process.KillProcess(Android.OS.Process.MyPid());
#endif
return base.OnBackButtonPressed();
}
}
}
My custom entry
namespace HCTaNaMao.Customs
{
public class CustomEntry : Entry
{
public static readonly BindableProperty BorderColorProperty =
BindableProperty.Create(
nameof(BorderColor),
typeof(Color),
typeof(CustomEntry),
Color.Gray);
// Gets or sets BorderColor value
public Color BorderColor
{
get { return (Color)GetValue(BorderColorProperty); }
set { SetValue(BorderColorProperty, value); }
}
public static readonly BindableProperty BorderWidthProperty =
BindableProperty.Create(
nameof(BorderWidth),
typeof(int),
typeof(CustomEntry),
Device.OnPlatform<int>(1, 2, 2));
// Gets or sets BorderWidth value
public int BorderWidth
{
get { return (int)GetValue(BorderWidthProperty); }
set { SetValue(BorderWidthProperty, value); }
}
public static readonly BindableProperty CornerRadiusProperty =
BindableProperty.Create(
nameof(CornerRadius),
typeof(double),
typeof(CustomEntry),
Device.OnPlatform<double>(6, 7, 7));
// Gets or sets CornerRadius value
public double CornerRadius
{
get { return (double)GetValue(CornerRadiusProperty); }
set { SetValue(CornerRadiusProperty, value); }
}
public static readonly BindableProperty IsCurvedCornersEnabledProperty =
BindableProperty.Create(
nameof(IsCurvedCornersEnabled),
typeof(bool),
typeof(CustomEntry),
true);
// Gets or sets IsCurvedCornersEnabled value
public bool IsCurvedCornersEnabled
{
get { return (bool)GetValue(IsCurvedCornersEnabledProperty); }
set { SetValue(IsCurvedCornersEnabledProperty, value); }
}
}
}
My renderer
[assembly: ExportRenderer(typeof(CustomEntry), typeof(CustomEntryRenderer))]
namespace HCTaNaMao.Droid
{
public class CustomEntryRenderer : EntryRenderer
{
public CustomEntryRenderer(Context context) : base(context)
{
}
protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)
{
base.OnElementChanged(e);
if (e.NewElement != null)
{
var view = (CustomEntry)Element;
if (view.IsCurvedCornersEnabled)
{
// creating gradient drawable for the curved background
var _gradientBackground = new GradientDrawable();
_gradientBackground.SetShape(ShapeType.Rectangle);
_gradientBackground.SetColor(view.BackgroundColor.ToAndroid());
// Thickness of the stroke line
_gradientBackground.SetStroke(view.BorderWidth, view.BorderColor.ToAndroid());
// Radius for the curves
_gradientBackground.SetCornerRadius(
DpToPixels(this.Context,
Convert.ToSingle(view.CornerRadius)));
// set the background of the label
Control.SetBackground(_gradientBackground);
}
// Set padding for the internal text from border
Control.SetPadding(
(int)DpToPixels(this.Context, Convert.ToSingle(12)),
Control.PaddingTop,
(int)DpToPixels(this.Context, Convert.ToSingle(12)),
Control.PaddingBottom);
}
}
public static float DpToPixels(Context context, float valueInDp)
{
DisplayMetrics metrics = context.Resources.DisplayMetrics;
return TypedValue.ApplyDimension(ComplexUnitType.Dip, valueInDp, metrics);
}
}
}
In my Login.xaml.cs, the line
usernameEntry.ReturnCommand = new Command(() => passwordEntry.Focus());
is getting error because the usernameEntry is null
Do I have to instance it?
In your XAML, you have x:Name=" usernameEntry" with a space. You must remove the space.
You need to instantiate your custom entry before adding a command. The correct way to use a custom entry is basically as the following example:
Add StackLayouts or another content layout
<StackLayout VerticalOptions="FillAndExpand" Padding="0,100,0,0">
<Image Source="HCbackground.png" VerticalOptions="Center" HeightRequest="200" />
<Label Text="Usuario" HorizontalTextAlignment="Center"/>
<StackLayout x:Name="stlUserName">
<!-- usernameEntry add here in code behind -->
</StackLayout>
<StackLayout x:Name="stlpasswordEntry">
<!-- passwordEntry add here in code behind -->
</StackLayout>
<Button Text="Entrar" TextColor="White" Clicked="LoginUser" WidthRequest="110"
HorizontalOptions="Center" BackgroundColor="SteelBlue" BorderRadius="20"/>
<Label x:Name="messageLabel" />
</StackLayout>
In code behind instantiate your custom entry
public Login ()
{
InitializeComponent ();
CustomEntryRenderer usernameEntry = new CustomEntryRenderer();
usernameEntry.CornerRadius="18";
usernameEntry.IsCurvedCornersEnabled="True";
usernameEntry.BorderColor="LightBlue";
usernameEntry.HorizontalTextAlignment="Start";
usernameEntry.FontSize="17";
usernameEntry.HeightRequest="40";
usernameEntry.Placeholder="Usuário";
usernameEntry.PlaceholderColor="LightGray";
usernameEntry.TextColor="Black";
usernameEntry.FontAttributes="Bold";
usernameEntry.WidthRequest="100";
usernameEntry.ReturnCommand = new Command(() => passwordEntry.Focus());
// Add entry in stacklayout
stlUserName.Children.Add(usernameEntry);
// do the same for password entry
}
Note:
Some properties of your entry, as CornerRadius, need to be added correctly, the above code just demonstrates that you need to instantiate your entry, add values to your properties, and add it to a stack layout.

Why won't Xamarin Forms Webview binding refresh on iOS?

I'm using the WebView and building my own html. I want to bind the webview to changes elsewhere on the form. Here is my xaml:
<WebView HorizontalOptions="FillAndExpand"
VerticalOptions="FillAndExpand"
Margin="0">
<WebView.Source>
<HtmlWebViewSource x:Name="WebViewSoruce1" Html="{Binding Description}"/>
</WebView.Source>
</WebView>
Here is my model code for the Description:
public string Description
{
get {
return _description;
}
set
{
_description = value;
RaisePropertyChanged();
}
}
This works fine on Android but not for iOS. Any suggestions would be greatly appreciated.
So if anyone else runs into this problem. This is what finally worked for me on both iOS and Android.
I had to bind as a WebViewSource to its Source attribute and not to the HTML. Here is my XAML:
<WebView HorizontalOptions="FillAndExpand"
VerticalOptions="FillAndExpand"
Margin="0" Source="{Binding WebViewSource}"/>
In my view model I have two properites. One to bind the HTML changes, I named it as Description. The other was to bind to the WebViewSource.
Here is the code-behind:
public HtmlWebViewSource WebViewSource
{
get
{
return new HtmlWebViewSource { Html = _description };
}
}
public string Description
{
get {
return _description;
}
set
{
_description = value;
RaisePropertyChanged();
RaisePropertyChanged("WebViewSource");
}
}
This worked for me.

Binding CarouselPage content pages to view model

I am trying to use a CarouselPage in Xamarin Forms.
<?xml version="1.0" encoding="utf-8" ?>
<CarouselPage 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:TestForms.Views;assembly=TestForms"
prism:ViewModelLocator.AutowireViewModel="True"
x:Class="TestForms.Views.Photos" ItemsSource="{Binding Pages}">
<CarouselPage.ItemTemplate>
<DataTemplate>
<ContentPage >
<StackLayout VerticalOptions="StartAndExpand" Padding="50">
<Label Text="ContentPage"></Label>
<Label Text="{Binding Title}"></Label>
<Label Text="{Binding Description}"></Label>
</StackLayout>
</ContentPage>
</DataTemplate>
</CarouselPage.ItemTemplate>
</CarouselPage>
In the view model I have
List<ContentPage> ContentPages = new List<ContentPage>();
foreach (var photo in Photos)
{
var page = new ContentPage();
page.BindingContext = new PhotoDetailViewModel(photo);
ContentPages.Add(page);
}
Pages = new ObservableCollection<ContentPage>(ContentPages);
When I render this, I get a list of pages for all the photos. but I can't seem to bind the title or description in the individual page.
What am I missing here?
You have your CarouselPage wired up correctly
Just need to change your view model slightly.
I'm assuming your Title and Description Properties are in your PhotoDetailViewModel?
if so the binding you are creating in your CarouselPage is not working because it is binded to the List of ContentPage, which wouldn't have the properties "Title" and "Description"
in your CarouselPage your have already set up an ItemsSource binding which should automatically set the BindingContext of your child pages in your CarouselPage. So you dont need to do it manually.
So instead create an ObservableCollection of PhotoDetailViewModel in your ViewModel and bind the ItemsSource of your CarouselPage to that.
So Remove:
List<ContentPage> ContentPages = new List<ContentPage>();
foreach (var photo in Photos)
{
var page = new ContentPage();
page.BindingContext = new PhotoDetailViewModel(photo);
ContentPages.Add(page);
}
Pages = new ObservableCollection<ContentPage>(ContentPages);
And add:
Pages = new ObservableCollection<PhotoDetailViewModel>(Photos.Select(p => new PhotoDetailViewModel(p));
Make sure to change the Property Type of Pages to ObservableCollection<PhotoDetailViewModel>
And that should be all you need to change
As I said you should use ContentView instead of ContentPage. Below is working example
public partial class AnotherCarouselPage : ContentPage
{
public class Zoo
{
public string ImageUrl { get; set; }
public string Name { get; set; }
}
public ObservableCollection<Zoo> Zoos { get; set; }
public AnotherCarouselPage()
{
Zoos = new ObservableCollection<Zoo>
{
new Zoo
{
ImageUrl = "http://content.screencast.com/users/JamesMontemagno/folders/Jing/media/23c1dd13-333a-459e-9e23-c3784e7cb434/2016-06-02_1049.png",
Name = "Woodland Park Zoo"
},
new Zoo
{
ImageUrl = "http://content.screencast.com/users/JamesMontemagno/folders/Jing/media/6b60d27e-c1ec-4fe6-bebe-7386d545bb62/2016-06-02_1051.png",
Name = "Cleveland Zoo"
},
new Zoo
{
ImageUrl = "http://content.screencast.com/users/JamesMontemagno/folders/Jing/media/e8179889-8189-4acb-bac5-812611199a03/2016-06-02_1053.png",
Name = "Phoenix Zoo"
}
};
InitializeComponent();
carousel.ItemsSource = Zoos;
carousel.PositionSelected += Carousel_PositionSelected;
carousel.ItemSelected += Carousel_ItemSelected;
}
private void Carousel_ItemSelected(object sender, SelectedItemChangedEventArgs e)
{
}
private void Carousel_PositionSelected(object sender, SelectedPositionChangedEventArgs e)
{
}
}
page xml
<?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:control="clr-namespace:Xamarin.Forms;assembly=Xamarin.Forms.CarouselView"
x:Class="ButtonRendererDemo.AnotherCarouselPage"
x:Name="devicePage"
BackgroundColor="Gray">
<ContentPage.Content>
<StackLayout VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand">
<control:CarouselView x:Name="carousel" >
<control:CarouselView.ItemTemplate>
<DataTemplate>
<StackLayout>
<Label Text="{Binding Name}"/>
<Image Source="{Binding ImageUrl}"/>
</StackLayout>
</DataTemplate>
</control:CarouselView.ItemTemplate>
</control:CarouselView>
</StackLayout>
</ContentPage.Content>
</ContentPage>

Carousel View not showing

I created a CarouselPage but I need CarouselView so I can add other control onto the page. For some reason, nothing showing up. Don't know what I am missing.
public class Zoo
{
public string ImageUrl { get; set; }
public string Name { get; set; }
}
public ObservableCollection<Zoo> Zoos { get; set; }
public PlayKeySound()
{
Zoos = new ObservableCollection<Zoo>
{
new Zoo
{
ImageUrl = "http://content.screencast.com/users/JamesMontemagno/folders/Jing/media/23c1dd13-333a-459e-9e23-c3784e7cb434/2016-06-02_1049.png",
Name = "Woodland Park Zoo"
},
new Zoo
{
ImageUrl = "http://content.screencast.com/users/JamesMontemagno/folders/Jing/media/6b60d27e-c1ec-4fe6-bebe-7386d545bb62/2016-06-02_1051.png",
Name = "Cleveland Zoo"
},
new Zoo
{
ImageUrl = "http://content.screencast.com/users/JamesMontemagno/folders/Jing/media/e8179889-8189-4acb-bac5-812611199a03/2016-06-02_1053.png",
Name = "Phoenix Zoo"
}
};
InitializeComponent();
carousel.ItemsSource = Zoos;
}
Xaml part:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:control="clr-namespace:Xamarin.Forms;assembly=Xamarin.Forms.CarouselView"
x:Class="keysound.PlayKeySound"
x:Name="devicePage"
BackgroundColor="Gray" >
<ContentPage.Content>
<StackLayout VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand">
<control:CarouselView x:Name="carousel" >
<control:CarouselView.ItemTemplate>
<DataTemplate>
<Label Text="{Binding Name}"/>
</DataTemplate>
</control:CarouselView.ItemTemplate>
</control:CarouselView>
</StackLayout>
</ContentPage.Content>
This is just a testing code to tryout the carousel view.
I was able to run your code and see the data of your collection. I had problems with carousel when I first time installed it. Try two things:
Clean and rebuild the solution. If this doesn't help
Uninstall pre-2, install pre-1. Check if it works. Then update to pre-2.
I know it is strange but that what did it for me.

Resources