Data access between .xmal and .cs in xamarin form - c#

I have taken a label in .xmal file.
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="ListDemo.TableView">
<StackLayout>
<Label Text="Above TableView"></Label>
<TableView>
<TableView.Root>
<TableSection Title="Test">
<EntryCell Label="EntryCell"></EntryCell>
<TextCell Text="Test" Detail="Text Detail"></TextCell>
<ViewCell>
<ViewCell.View>
<StackLayout Orientation="Horizontal" >
<BoxView Color="Red"></BoxView>
<StackLayout>
<Label Text="{Binding Receivename}"></Label>
<Label Text="News URL 1"></Label>
</StackLayout>
<BoxView x:Name="boxView" Color="Blue" ></BoxView>
</StackLayout>
</ViewCell.View>
</ViewCell>
</TableSection>
</TableView.Root>
</TableView>
</StackLayout>
I want to set the Label data from .cs file.
namespace ListDemo
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class TableView : ContentPage
{
public TableView()
{
InitializeComponent();
public string Receivename = "Hello";
}
}
}
Please let me know , how can I set the dynamic data of Label . What to write in .cs file .
Thanks in advance.

First, you can only bind to properties. So you would need:
public string Recievename { get; set; }
Second, you are setting this data in the constructor, when it should be within the scope of the actual class.
You can, however, set the value of the property in the constructor. Just not define it there.
Update per request:
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class TableView : ContentPage
{
public string Receivename { get; set; }
public TableView()
{
InitializeComponent();
BindingContext = this; //Need to set data context as well, if not defined in XAML
Receivename = "Hello";
}
}
I also suggest you look more into binding, property notification, etc. This blog on xamarin should give you a hint: https://blog.xamarin.com/introduction-to-data-binding/

Related

MAUI not finding property in VIew Model List

I have a simple view model where one property contains a model, and another property contains a list of models.
I am able to bind the "Test" model's properties without an issue but I'm not able to get the XAML to recognize that "ListModel" contains a list with its own properties. I have looked at several examples for how to set up the view model and initialize the list correctly before binding it to the view, and while the XAML understands that "ListModel" is a property, I can't get it to recognize that it's a list, and thus it will not compile so that I can at least see if it isn't the intellisense that could be failing for whatever reason.
This is the view model in question with the list named "ListModel"
public class TestViewModel
{
public TestModel Test { get; } = new TestModel();
public List<TestListModel> ListModel { get; set; }
public TestViewModel()
{
Initialize();
}
public void Initialize()
{
ListModel = new List<TestListModel>();
ListModel.Add(new TestListModel
{
ListProp1 = "First",
ListProp2 = "Second",
ListProp3 = "Third"
});
}
}
This is the Model that is being put into a list. It seems like the view isn't seeing these properties.
public class TestListModel
{
public string ListProp1 { get; set; }
public string ListProp2 { get; set; }
public string ListProp3 { get; set; }
}
This is my XAML Currently.
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MauiApp1.MainPage"
xmlns:local="clr-namespace:ViewModels"
x:DataType="local:TestViewModel"
>
<ScrollView>
<VerticalStackLayout
Spacing="25"
Padding="30,0"
VerticalOptions="Center">
<!--This works-->
<Entry Text="{Binding Test.Property1}"/>
<Entry Text="{Binding Test.Property2}"/>
<Entry Text="{Binding Test.Property3}"/>
<!--This does not work-->
<ListView
ItemsSource="{Binding ListModel}">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Label Text="{Binding ListProp1}"/>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</VerticalStackLayout>
</ScrollView>
</ContentPage>
For anyone stumbling in on this: Jason in the comments has answered the question. The fix was simply to remove x:DataType from the top of the XAML, though I did not remove the "xmlns:local" from it.
What I had was a View Model that had more than just one model in it, which seemed to upset the intellisense when removing x:DataType. Removing it originally prevented the application from compiling because it couldn't find the properties I had in the XAML. Once I cleaned and rebuilt the solution it compiled and worked without a hitch.
The view and the viewmodel are often connected through data bindings defined in XAML. The BindingContext for the view is usually an instance of the viewmodel.So I think you forget to connect these two elements with BindingContext.
Code behind View:
public partial class MainPage : ContentPage
{
TestViewModel tv = new TestViewModel();
public MainPage()
{
InitializeComponent();
BindingContext = tv;
}
}
Code in Xaml:
<ScrollView>
<VerticalStackLayout
Spacing="25"
Padding="30,0"
VerticalOptions="Center">
<!--This works-->
<Entry Text="{Binding Test.Property1}"/>
<Entry Text="{Binding Test.Property2}"/>
<Entry Text="{Binding Test.Property3}"/>
<!--This works too-->
<ListView
HasUnevenRows="True"
ItemsSource="{Binding ListModel}">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<VerticalStackLayout>
<Label Text="{Binding ListProp1}"/>
<Label Text="{Binding ListProp2}"/>
<Label Text="{Binding ListProp3}"/>
</VerticalStackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</VerticalStackLayout>
</ScrollView>
Outcome:
Reference link.
I was able to fix the error while also keeping the compiled bindings in place by making the ItemSource bind to a List with a private backing field. It seems like the compiler is unable to resolve the list correctly without the private property being there. After i added listModel it compiled. So the issue seems to be that the setter is missing.
private List<TestListModel> listModel;
public List<TestListModel> ListModel { get => listModel; set => listModel = value; }

Why won't my Xamarin.Forms ListView Data Binding reflect in other Views?

My MainPage.xaml page is bound to ClientsViewModel.cs. This page has a ListView bound to an ObservableCollection property.
The NewClient.xaml page and entry fields are also bound to the ClientsViewModel.cs.
When I save a new client using the NewClient.xaml form and navigate back to MainPage.xaml (using the navigation back arrow) I expect to see the newly added client in the MainPage.xaml ListView however I do not see this change.
How come the ListView in MainPage.xaml isn't showing the newly updated record? Where am I going wrong?
It may be worthwhile mentioning that my actual project will be using SQLite, so the ObseravbleCollection will eventually be obtaining records directly from an SQLite database, so any help or advice around this would be greatly appreciated also.
Refer below code, or clone from my GitHub repository https://github.com/minlopalis/XamarinForms-ListView-DataBinding.git
(Model) Client.cs
public class Client
{
public int Id { get; set; }
public string Name { get; set; }
public string Phone { get; set; }
}
(ViewModel) BaseViewModel.cs
public class BaseViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged([CallerMemberName] string propertyName = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
(View Model) ClientViewModel.cs
public class ClientViewModel : BaseViewModel
{
private ObservableCollection<Client> clients;
public ObservableCollection<Client> Clients
{
get { return clients; }
set
{
clients = value;
OnPropertyChanged();
}
}
public Command SaveClientCommand { get; }
public ClientViewModel()
{
this.Clients = new ObservableCollection<Client>();
SaveClientCommand = new Command(()=> {
Client client = new Client()
{
Name = Name,
Phone = Phone
};
Clients.Add(client);
OnPropertyChanged(nameof(Clients));
});
}
private int id;
public int Id
{
get { return id; }
set
{
id = value;
OnPropertyChanged();
}
}
private string name;
public string Name
{
get { return name; }
set
{
name = value;
OnPropertyChanged();
}
}
private string phone;
public string Phone
{
get { return phone; }
set
{
phone = value;
OnPropertyChanged();
}
}
}
(View) MainPage.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:viewModels="clr-namespace:DataBinding.ViewModels"
x:Class="DataBinding.MainPage">
<ContentPage.BindingContext>
<viewModels:ClientViewModel/>
</ContentPage.BindingContext>
<StackLayout>
<Label Text="Client List"></Label>
<ListView ItemsSource="{Binding Clients}">
<ListView.ItemTemplate>
<DataTemplate>
<StackLayout>
<Label Text="{Binding Name}"/>
<Label Text="{Binding Phone}"/>
</StackLayout>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<Button Text="Add Client"
Clicked="AddClientButton_Clicked"/>
</StackLayout>
</ContentPage>
(View) NewClient.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:viewModels="clr-namespace:DataBinding.ViewModels"
x:Class="DataBinding.Views.NewClient">
<ContentPage.BindingContext>
<viewModels:ClientViewModel/>
</ContentPage.BindingContext>
<ContentPage.Content>
<StackLayout>
<Label Text="Add New Client" />
<Label Text="Name"/>
<Entry Text="{Binding Name}"/>
<Label Text="Phone"/>
<Entry Text="{Binding Phone}"/>
<Button Text="Save"
Command="{Binding SaveClientCommand}"/>
<!-- Added ListView -->
<ListView ItemsSource="{Binding Clients}">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout>
<Label Text="{Binding Name}"/>
<Label Text="{Binding Phone}"/>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
</ContentPage.Content>
</ContentPage>
I've downloaded your code from the repo and I think there is one big flaw in it causing this. You're setting your BindingContext in XAML on both pages. If you set a breakpoint in the constructor of the ClientViewModel, you will notice it gets called twice: once when the app boots, once when you click "Add Client".
This means you are looking at two separate instances of this class so your Client is in the wrong instance. You want to make sure that you are looking at the same view model.
Even more so, you might even want to make the separation of concerns even better by creating an extra, i.e.: CreateClientViewModel which is only responsible for creating the client and returning that object to the ClientViewModel which then in its turn adds that to the collection.
Hope this helps!
According to your description, you want to pass data when navigate between pages, I suggest you can use MessagingCenter.
MainPage:
<StackLayout>
<Label Text="Client List" />
<ListView ItemsSource="{Binding Clients}">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout>
<Label Text="{Binding Name}" />
<Label Text="{Binding Phone}" />
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<Button Command="{Binding SaveClientCommand}" Text="Add Client" />
</StackLayout>
public partial class Page9 : ContentPage
{
private ClientViewModel _clientmodel;
public ClientViewModel clientmodel
{
get { return _clientmodel; }
set
{
_clientmodel = value;
}
}
public Page9()
{
InitializeComponent();
this.BindingContext = new ClientViewModel(this.Navigation);
}
}
public class ClientViewModel
{
public ObservableCollection<Client> Clients { get; set; }
public Command SaveClientCommand { get; }
private INavigation _navigation;
public ClientViewModel(INavigation navitation)
{
Clients = new ObservableCollection<Client>();
Clients.Add(new Client() { Name = "client1", Phone = "123" });
_navigation = navitation;
SaveClientCommand = new Command(async() => {
await _navigation.PushAsync(new NewClient());
});
MessagingCenter.Subscribe<string, string[]>("test", "Add", (sender, values) =>
{
Client client = new Client() { Name=values[0],Phone=values[1]};
Clients.Add(client);
});
}
}
NewClient.xaml:
public partial class NewClient : ContentPage
{
public NewClient()
{
InitializeComponent();
}
private void Button_Clicked(object sender, EventArgs e)
{
string name = entry1.Text;
string phone = entry2.Text;
string[] values = { name,phone};
MessagingCenter.Send<string, string[]>("test", "Add", values);
Navigation.PopAsync();
}
}
By the way, you don't need to call PropertyChanged for ObservableCollection, because ObservableCollection Class Represents a dynamic data collection that provides notifications when items get added, removed, or when the whole list is refreshed.
Thanks for everyone's help, I have solved my issue.
There were two problems with my code.
1. Two ViewModel Instances
As pointed out by Gerald Versluis I had two instances of my ViewModel. I fixed this issue by creating an instance of my view model in Application.Resources in my App.xaml page.
<?xml version="1.0" encoding="utf-8" ?>
<Application xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="DataBinding.App"
xmlns:ClientViewModel="clr-namespace:DataBinding.ViewModels">
<Application.Resources>
<ClientViewModel:ClientViewModel x:Key="ClientViewModel" />
</Application.Resources>
</Application>
And binding each page to the Static Resource (as below)
<?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:ViewModels="clr-namespace:DataBinding.ViewModels"
x:Class="DataBinding.Views.NewClient">
<ContentPage.BindingContext>
<StaticResource Key="ClientViewModel"/>
</ContentPage.BindingContext>
<ContentPage.Content>
<StackLayout>
<Label Text="Add New Client" />
<Label Text="Name"/>
<Entry Text="{Binding Name}"/>
<Label Text="Phone"/>
<Entry Text="{Binding Phone}"/>
<Button Text="Save"
Command="{Binding SaveClientCommand}"/>
<!-- Added ListView -->
<ListView ItemsSource="{Binding ClientList}">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout>
<Label Text="{Binding Name}"/>
<Label Text="{Binding Phone}"/>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
</ContentPage.Content>
</ContentPage>
Thanks Gerald Versluis for your help. Check out his YouTube channel here.
2. Missing ViewCell
My MainPage.xaml was missing a ViewCell in the ListView. This was a simple typing oversight but was throwing a "'Specified cast is not valid" error. Big thanks to Alexander Fauland for his reply to this thread which helped me solve my missing ViewCell problem.

Xamarin.Forms ImageCell not displaying image version 4.7.0.xx

I already tried, string to ImageSource in my model but still I did not get image to display in ImageCell.
If I try this line of code <Image Source="https://img.icons8.com/carbon-copy/2x/user.png"></Image>, image displays fine.
Model
public class Contact
{
public string Name { get; set; }
public string Status { get; set; }
public ImageSource ImageUri { get; set; }
}
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:d="http://xamarin.com/schemas/2014/forms/design"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
x:Class="App1.ListPage">
<ContentPage.Content>
<StackLayout>
<ListView x:Name="listView" SeparatorVisibility="Default" SeparatorColor="Blue">
<ListView.ItemTemplate>
<DataTemplate>
<!--<TextCell Text="{Binding Name}" Detail="{Binding Status}" TextColor="Accent" DetailColor="Beige"></TextCell>-->
<!--<TextCell Text="{Binding Name}" Detail="{Binding Status}"></TextCell>-->
`<ImageCell Text="{Binding Name}" Detail="{Binding Status}" ImageSource="{Binding ImageUri}`"></ImageCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<!--<Image Source="https://img.icons8.com/carbon-copy/2x/user.png"></Image>-->
</StackLayout>
</ContentPage.Content>
</ContentPage>
XAML.cs
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class ListPage : ContentPage
{
public ListPage()
{
InitializeComponent();
listView.ItemsSource = new List<Contact>
{
new Contact{ Name="Monkey D. Luffy", ImageUri=ImageSource.FromUri(new Uri("https://img.icons8.com/carbon-copy/2x/user.png"))},
new Contact{ Name="Monkey D. Dragon",
ImageUri=ImageSource.FromUri(new Uri("https://img.icons8.com/carbon-copy/2x/user.png"))},
new Contact{ Name="Portgas D. Ace",
ImageUri=ImageSource.FromUri(new Uri("https://img.icons8.com/carbon-copy/2x/user.png")), Status="Hello World!"}
};
}
}
just did two tests on my playground.
I kicked off with a blank Xamarin.Forms project (only one MainPage there) in VS2019, then
updated the XF nuget package to 4.7.0.1142.
pasted your code.
remove two extra ` characters in your xaml code snippet.
It's working.
Then, I tried the string property in the model class like this:
public string ImageUri { get; set; }
And also set string value in xaml.cs class like this:
new Contact{ Name="", ImageUri="https://xxx.png"}
It's also working.
Not sure about the issue, but your code is fine anyway.
Try to use this nuget https://github.com/luberda-molinet/FFImageLoading for images. Is the best !!

Detecting tap on label, inside ViewCell, inside ListView

I'm trying to handle something similar (from UI perspective), to:
in order to invoke two different business logics for:
tapping at ViewCell element itself (inside ListView) - in example navigate to different page
tapping at Label element (Clickable Label), which is inside given ViewCell element - in example delete given object or smth else
I would like to have whole "tapping" logic inside page ViewModel.
Based on Xamarin forum proposes, I'm able to invoke some logic of "tapping" my delete action from cell, however directly inside my data model - which in my PoV is not good solution, as I would like to manipulate my List collection (so the most preferable way, would be to have this logic at page ViewModel).
What I have right now:
My page View XAML code looks like:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="App.Views.TestView">
<ContentPage.Content>
<StackLayout HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand">
<ListView HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" ItemsSource="{Binding MyItemsCollection}" SelectedItem="{Binding SelectedItem}">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout Orientation="Horizontal">
<!-- Name Label -->
<Label Text="{Binding Name}" VerticalOptions="CenterAndExpand" HorizontalOptions="StartAndExpand" />
<!-- Delete "Icon" -->
<Label Text="Clickable Label" VerticalOptions="CenterAndExpand" HorizontalOptions="EndAndExpand">
<Label.GestureRecognizers>
<TapGestureRecognizer Command="{Binding OnClickableLabel}" CommandParameter="{Binding .}" />
</Label.GestureRecognizers>
</Label>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
</ContentPage.Content>
</ContentPage>
My page View C# code looks like (not specific code there, except binding **BindingContext* to page ViewModel):
public partial class TestView : ContentPage
{
public TestView()
{
InitializeComponent();
BindingContext = ServiceLocator.Current.GetInstance<TestViewModel>();
}
}
My page ViewModel C# code looks like:
public class TestViewModel : ViewModelBase
{
public TestViewModel()
{
MyItemsCollection = GetMyItemsCollection();
}
private List<MyItem> GetMyItemsCollection()
{
return new List<MyItem>
{
new MyItem
{
ID = 1L,
Name = "Item 1 Name"
},
new MyItem
{
ID = 2L,
Name = "Item 2 Name"
},
new MyItem
{
ID = 3L,
Name = "Item 3 Name"
}
};
}
private List<MyItem> _myItemsCollection { get; set; }
public List<MyItem> MyItemsCollection
{
get
{
return _myItemsCollection;
}
set
{
_myItemsCollection = value;
RaisePropertyChanged();
}
}
private MyItem _SelectedItem { get; set; }
public MyItem SelectedItem
{
get
{
return _SelectedItem;
}
set
{
if (_SelectedItem != value)
{
_SelectedItem = value;
RaisePropertyChanged();
Debug.WriteLine("SelectedItem: " + _SelectedItem.Name);
}
}
}
private RelayCommand<object> _OnClickableLabel;
public RelayCommand<object> OnClickableLabel
{
get { return _OnClickableLabel ?? (_OnClickableLabel = new RelayCommand<object>((currentObject) => Test(currentObject))); }
}
private void Test(object currentObject)
{
Debug.WriteLine("This should work... but it's not working :(");
}
}
My data model code looks like:
public class MyItem
{
public long ID { get; set; }
public string Name { get; set; }
private RelayCommand<object> _OnClickableLabel;
public RelayCommand<object> OnClickableLabel
{
get { return _OnClickableLabel ?? (_OnClickableLabel = new RelayCommand<object>((currentObject) => Test(currentObject))); }
}
private void Test(object currentObject)
{
Debug.WriteLine("This works... but it's not good idea, to have it here...");
}
}
Any idea what needs to be changed, in order to invoke OnClickableLabel directly inside my page ViewModel ?
I know, that it's something wrong at:
<TapGestureRecognizer Command="{Binding OnClickableLabel}" CommandParameter="{Binding .}" />
but don't know what :/.
Help! Thanks a lot.
Ok, I found solution, by extending XAML code:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="App.Views.TestView" x:Name="Page">
<ContentPage.Content>
<StackLayout HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand">
<ListView HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" ItemsSource="{Binding MyItemsCollection}" SelectedItem="{Binding SelectedItem}">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout Orientation="Horizontal">
<!-- Name Label -->
<Label Text="{Binding Name}" VerticalOptions="CenterAndExpand" HorizontalOptions="StartAndExpand" />
<!-- Delete "Icon" -->
<Label Text="Clickable Label" VerticalOptions="CenterAndExpand" HorizontalOptions="EndAndExpand">
<Label.GestureRecognizers>
<TapGestureRecognizer Command="{Binding Path=BindingContext.OnClickableLabel, Source={x:Reference Page}}" CommandParameter="{Binding .}" />
</Label.GestureRecognizers>
</Label>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
</ContentPage.Content>
</ContentPage>
After that, I got OnClickableLabel command invoked inside my page ViewModel, as expected :).
If someone know "better" solution (better from XAML code point of view), I would like to see it ;).
Thanks a lot everyone!
continuing with what #Namek said i would suggest to get the object of list view item first and then call the command or viewmodel method.
for more you can refer my blog post about interactive Listview at https://adityadeshpandeadi.wordpress.com/2018/07/15/the-more-interactive-listview/
feel free to drop by. :)

Xamarin: Populating ListView in xcml using a List<T>

I'm having issues getting the data binding to work in xaml with ListView. The ListView displays all cells as expected but doesn't display the value for any of the bound variables.
I have my sample data constructed like this:
public class DataItem
{
public int Number { get; set; }
public string Message { get; set; }
public DataItem (int i)
{
this.Number = i + 1;
this.Message = string.Format ("Data Item Hello {0}", i + 1);
}
}
The ListView in xaml is defined this way:
<ListView x:Name="uiList">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout Orientation="Vertical" BackgroundColor="Silver">
<Label TextColor="Green" Text="Pre Xamarin" />
<Label BackgroundColor="Aqua" TextColor="Red" Text="{Binding Path=Message}" />
<Label TextColor="Green" Text="Hello Xamarin" />
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
I have created 200 sample objects and assigned to uiList.ItemsSource. This results in the ListView showing 200 items as expected but it doesn't show the value of the Message property in the DataItem.
I've also tried using {Binding Message} (without Path=) but the result didn't change. I'm sure there is something obvious I'm missing but can't figure it out.
--- UPDATE ---
I have a reliable repro now. Create a new project and add the ListView and population as provided above.
Go to the solution properties for the iOS project, select the iOS Build page and change 'Link behavior' to 'Link All' and change the 'Supported architecture' to 'x86_64'. Now Clean, Build and Run and the binding will not work.
Hey I just tried your code and it worked for me out of the box. I just added my logic to populate a list of DataItem and set it as ItemsSource of the listview. Here I is my code and the result.
<?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="TestForms.TestListView" xmlns:ffimageloading="clr-namespace:FFImageLoading.Forms;assembly=FFImageLoading.Forms">
<ContentPage.Content>
<ListView x:Name="uiList">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout Orientation="Vertical" BackgroundColor="Silver">
<Label TextColor="Green" Text="Pre Xamarin" />
<Label BackgroundColor="Aqua" TextColor="Red" Text="{Binding Message}" />
<Label TextColor="Green" Text="Hello Xamarin" />
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</ContentPage.Content>
public partial class TestListView : ContentPage
{
public TestListView ()
{
InitializeComponent ();
ObservableCollection<DataItem> employeeList = new ObservableCollection<DataItem>();
for(int i=0;i<100;i++)
employeeList.Add(new DataItem(i));
uiList.ItemsSource = employeeList;
//Mr. Mono will be added to the ListView because it uses an ObservableCollection
}
}
public class DataItem
{
public int Number { get; set; }
public string Message { get; set; }
public DataItem (int i)
{
this.Number = i + 1;
this.Message = string.Format ("Data Item Hello {0}", i + 1);
}
}

Categories

Resources