Xamarin Forms listview databinding - c#

I am currently following this guide:
http://www.morganskinner.com/2015/01/xamarin-forms-contacts-search.html
I am willing to make a contacts page in my app, like the one showed in the pictures there, still something is not working out as it should for me:
I wrote/copied the XAML:
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<SearchBar x:Name="search" Placeholder="Search"/>
<ListView x:Name="ProvaView" Grid.Row="1" ItemsSource="{Binding FilteredContacts}" IsGroupingEnabled="true" GroupDisplayBinding="{Binding Key}" GroupShortNameBinding="{Binding Key}">
<ListView.ItemTemplate>
<DataTemplate>
<TextCell Text="{Binding Name}" TextColor="Black" Detail="{Binding PhoneNumber}" DetailColor="Gray">
</TextCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
and now I am trying to "display something", not dinamically loaded (yet), from a list of data.
I declared a class like this:
public class Contact
{
public string Name { get; set; }
public string PhoneNumber { get; set; }
}
}
and now the code behind the xaml is this:
public partial class ContactsPage : MasterDetailPage
{
public List<Contact> FilteredContacts = new List<Contact>
{
new Contact
{
Name = "Guido",
PhoneNumber = "3292773477"
},
new Contact
{
Name = "Luca",
PhoneNumber = "3472737445"
},
new Contact
{
Name = "Luca",
PhoneNumber = "3472737445"
}
};
public ContactsPage()
{
InitializeComponent();
ProvaView.ItemsSource = FilteredContacts;
}
}
When I launch the app, all I get anyway is an empty listview, with 3 fields but nothing in it.
Where am I doing wrong?
Also, straight from the page where I am working off, I can't understand the meaning of these Fields associated to the listview:
GroupDisplayBinding="{Binding Key}"
GroupShortNameBinding="{Binding Key}"
and as much as I could look around on the web, I coudln't find any reference to both of them.

Most likely the problem is with the way you declared FilteredContacts, it should be a property, and not a field. The reflection mechanism used in binding only searches for properties, fields are not included.

Related

Showing a single value from api call TextBlock (MVVM)

I have been stuck on this for a few hours now. I am using the IGDB api for the application I'm building. So, I'm trying to get the ListBox I have to show the Game Title, cover and Developer. I've managed to get all of them to show up in the list with no issues but the main issue comes in when I just want to show a single developer within the list, the list is showing all companies involved plus the developer because the API returns an array of Involved Companies and within those Involved Companies the developer body returns a Boolean value to say which one is the developer. I can see it in my head, if developer is true then show the developer and remove the other involved companies. Here is an image of what is showing up when I run my query:
Query Image
I have outlined it in red. From that list all I would need is Bungie since they're the developers. So in my view I have a ListBox and a ListView nested within it:
BrowseGamesView
<ListBox ItemsSource="{Binding Games}"
Width="390"
Height="500"
Grid.Row="4">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Border Grid.Column="0"
Grid.Row="0"
Grid.RowSpan="2"
Margin="0 0 10 0">
<Image Source="{Binding cover.image_id, Converter={StaticResource stringToImage}}"
Stretch="Fill"
Height="70"
Width="60"/>
</Border>
<TextBlock Text="{Binding name}"
FontWeight="Bold"
Grid.Column="1"
Grid.Row="0"/>
<ListView Grid.Column="1"
Grid.Row="1"
ItemsSource="{Binding involved_companies}">
<ListView.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding company.name}"/>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Within my ViewModel I have a method for making the query and also holds the ObservableCollection (Games).
BrowseGamesViewModel
public ObservableCollection<Game> Games { get; set; }
public async void MakeQuery()
{
var games = await IGDBHelper.GetGames(Query);
Games.Clear();
foreach(var game in games)
{
Games.Add(game);
}
}
In my Helper class I get the games
IGDBHelper
public static async Task<List<Game>> GetGames(string query)
{
List<Game> games = new List<Game>();
string myJson = "search \"{0}\"; fields name, cover.url, cover.image_id, involved_companies.developer, involved_companies.company.name; limit 500;";
using (HttpClient client = new HttpClient())
{
client.DefaultRequestHeaders.Add("user-key", "key hidden");
var response = await client.PostAsync(BASE_URL_GAMES, new StringContent(string.Format(myJson, query), Encoding.UTF8, "application/json"));
var responseString = await response.Content.ReadAsStringAsync();
games = JsonConvert.DeserializeObject<List<Game>>(responseString);
}
return games;
}
And all of models are concrete classes for the Json
public class Game
{
public int id { get; set; }
public Cover cover { get; set; }
public List<InvolvedCompany> involved_companies { get; set; }
public string name { get; set; }
}
public class InvolvedCompany
{
public int id { get; set; }
public Company company { get; set; }
public bool developer { get; set; }
}
public class Company
{
public int id { get; set; }
public string name { get; set; }
}
public class Cover
{
public int id { get; set; }
public string image_id { get; set; }
public string url { get; set; }
}
So, to reiterate, I need to somehow just show the developers name by removing the rest of the involved companies from the list. I have tried several things from converters to trying it in the converter class and each time I get exceptions for null.
I would add a new readonly property to the Game class:
public List<InvolvedCompany> DeveloperCompanies
{
get
{
return involved_companies.Where(c => c.developer == true).ToList();
}
}
And then you can bind this new property to your ListView:
<ListView Grid.Column="1"
Grid.Row="1"
ItemsSource="{Binding DeveloperCompanies}">
<ListView.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding company.name}"/>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
This way you would be showing only the developer companies but you would keep the information about all the involved companies as well, if you need to use them for another purpose.
I also suggest you to use PascalCase for the public members of a class. So, for example involved_companies would become InvolvedCompanies.
First, I would suggest to name your properties in PascalCase.
Now for your problem, I suggest to filter the companies by developer property and assign a new list of involving companies to the game before adding it to the list.
foreach(var game in games)
{
game.involved_companies = game.involved_companies.Where(e => e.developer == true).Tolist();
Games.Add(game);
}
Not tested but I believe this should work.

Best approach to add an item to a databound Listbox using MVVM pattern?

I'm facing a problem in my WPF project at the moment. At this moment I have a Viewmodel which has a Manager (to communicate with the repo).
internal class TicketViewModel
{
private TicketManager mgr;
public IEnumerable<Ticket> List { get; set; }
public TicketViewModel()
{
mgr = new TicketManager();
List = mgr.GetTickets();
}
}
I've managed to bind this list to the Listbox in my MainWindow. The next step is that I need to add an extra ticket to the list and also pass this through the manager. The problem is I need two parameters from some Controls in the MainWindow. From MVVM perspective I need to use bound Commands on e.g. a Button to communicate with the viewmodel as my viewmodel can't/may not access controls from the window. Is using parameterized Commands the way to go here?
The next problem is that the Listbox won't update I guess. This is the code:
<ListBox x:Name="listboxTix" BorderThickness="0" ItemsSource="{Binding List}">
<ListBox.ItemTemplate>
<DataTemplate>
<Border BorderBrush="Bisque" Background="Beige" BorderThickness="2">
<StackPanel Width="250">
<TextBlock Text="{Binding TicketNumber}" />
<TextBlock Text="{Binding Text}" />
<TextBlock Text="{Binding State}" />
</StackPanel>
</Border>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
I found that using a CompareableCollection is the way to go here, but then I still have to read all the Tickets again after adding a new Ticket.
Thanks in advance,
Hicy
okay here is the code.
Lets say you have three textboxes on MainWindow(since you have three Textblocks.) so Your MainWindow.xaml looks like
<Window.DataContext>
<local:MyViewModel/>--set's your viewModel
</Window.DataContext>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="250*"/>
<RowDefinition Height="90"/>
<RowDefinition Height="30"/>
</Grid.RowDefinitions>
<ListBox Grid.Row="0" x:Name="listboxTix" BorderThickness="0" ItemsSource="{Binding List}">
<ListBox.ItemTemplate>
<DataTemplate>
<Border BorderBrush="Bisque" Background="Beige" BorderThickness="2">
<StackPanel Width="250">
<TextBlock Text="{Binding TicketNumber}" />
<TextBlock Text="{Binding Text}" />
<TextBlock Text="{Binding State}" />
</StackPanel>
</Border>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<TextBox x:Name="TicketNumber" Grid.Row="1" TextWrapping="Wrap" Text="{Binding Path=Text}" VerticalAlignment="Top" Width="120"/>
<TextBox x:Name="Text" Grid.Row="1" TextWrapping="Wrap" Text="{Binding Path=State}" />
<TextBox x:Name="State" Grid.Row="1" TextWrapping="Wrap" Text="{Binding Path=TicketNumber}" />
<Button Content="Button" Command="{Binding Path=MainCommand}" Grid.Row="2"/>
</Grid>
and I am assuming that you have some class called class Ticket which contain these three members
Class Ticket
{
public int TicketNumber { get; set; }
public string Text { get; set; }
public string State { get; set; }
}
Now in class TicketManager we fill it with some dummy data
class TicketManager
{
ObservableCollection<Ticket> tl = new ObservableCollection<Ticket>();
internal ObservableCollection<Ticket> GetTickets()
{
tl.Add(new Ticket() { State = "State1", Text = "Text1", TicketNumber = 1 });
tl.Add(new Ticket() { State = "State2", Text = "Text2", TicketNumber = 2 });
tl.Add(new Ticket() { State = "State3", Text = "Text3", TicketNumber = 3 });
return tl;
}
}
and in your Mainwindow ViewModel lets call it MyViewModel.cs we add
class MyViewModel:INotifyPropertyChanged
{
private TicketManager mgr;
public ObservableCollection<Ticket> List { get; set; }
private string text;
private string state;
private int ticketNumber;
private readonly DelegateCommand<object> MyButtonCommand;
public Class1()
{
mgr = new TicketManager();
List = mgr.GetTickets();
MyButtonCommand = new DelegateCommand<object>((s) => { AddListToGrid(text, state, ticketNumber); }, (s) => { return !string.IsNullOrEmpty(text) && !string.IsNullOrEmpty(state); });
}
private void AddListToGrid(string text, string state, int ticketNumber)
{
List.Add(new Ticket() {Text=text,State=state,TicketNumber=ticketNumber });
}
public DelegateCommand<object> MainCommand
{
get
{
return MyButtonCommand;
}
}
public string Text
{
get
{
return text;
}
set
{
text = value;
OnPropertyChanged("Text");
MyButtonCommand.RaiseCanExecuteChanged();
}
}
public string State
{
get
{
return state;
}
set
{
state = value;
OnPropertyChanged("State");
MyButtonCommand.RaiseCanExecuteChanged();
}
}
public int TicketNumber
{
get
{
return ticketNumber;
}
set
{
ticketNumber = value;
OnPropertyChanged("TicketNumber");
MyButtonCommand.RaiseCanExecuteChanged();
}
}
private void OnPropertyChanged(string p)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(p));
}
public event PropertyChangedEventHandler PropertyChanged;
}
You can Modify the code in anyway you want
This ViewModel implements fewthings which are very important from MVVM point of view
1) INotifyPropertyChanged
2) WPF Delegate Command
P.S:The code is tested and it runs as expected
Don't get hung up on MVVM it is simply a separation of data from a view, and models are shared between the two with a majority of the business logic (on a shared component) should be performed on the VM; it is not a religion just a three tiered data system. IMHO
If your button needs to do an operation, have it make a call, most likely in the code behind, to a method on the VM which handles the business logic, updates the list with the new item and notifies the manager.
I would bind the list in question to an ObservableCollection which can notify upon insert/delete of an item.

How do you bind to a complex object in usercontrol.resources for Windows Phone 8.1 (C#)

I have searched the web for the last few days but can't seem to find something that I would have thought was quite a simple task. I would like to add a resource in my XAML page of my windows phone application which will reference a complex object but I can't find the correct method. Is this possible? Object is made up something similar to:
Public class ComplexClass
{
Public string name { get; set; }
Public int ID { get; set; }
Public observablecollection<SimpleClass> simpleObjects { get; set; }
Public addSimpleObject(SimpleClass newSimpleObject)
{
if (simpleObjects == null)
simpleObjects = new ObservableCollection<SimpleClass>();
simpleObjects.Add(newSimpleObject);
}
}
Public Class SimpleClass
{
Public String Name { get; set; }
Public String Disc { get; set; }
}
You could use MVVM do achieve this. There are already heaps of tutorials available that you can access to show you how to follow this design pattern, so I won't go into that.
Instead I'll just show you a simple way of getting the data to your view.
In the constructor of your UserControl (or Page or whatever), set up the DataContext to an instance of your ComplexClass:
ComplexClass complexClass;
public MyUserControl1()
{
complexClass = new ComplexClass();
complexClass.AddSimpleObject(new SimpleClass { Name = "Bob" });
this.DataContext = complexClass;
this.InitializeComponent();
}
Then in your XAML you can bind to it like this:
<StackPanel>
<!-- Binding to properties on ComplexClass -->
<TextBlock Text="{Binding Name}" />
<TextBlock Text="{Binding ID}" />
<ListView ItemsSource="{Binding SimpleObjects}">
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel>
<!-- Binding to properties on SimpleClass -->
<TextBlock Text="{Binding Name}" />
<TextBlock Text="{Binding Disc}" />
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackPanel>
Without knowing specifics of your code, it's hard for me to suggest a method that is most suitable for you. I'd read up on MVVM and view models.

Dynamic pages using Pivot control

Being new to the Windows 7/8 phone development arena... I am enjoying working with the windows phone tremendously... however there has been a learning curve and so much to get to know.
With that said, what I am trying to do is create a page that that is dynamically bound to a data structure that will display n number of pivot pages, and each pivot page will have different XAML to display the content.
I looked over this code project article (http://www.codeproject.com/Articles/113152/Applying-Data-Templates-Dynamically-by-Type-in-WP7) and it uses a list box to control the display... but what I am interested in is doing the same thing, but with a pivot page.
I learn best by example... here are the classes for binding the data to the controls, that I would LIKE TO USE ...
public class ParkingLot : List<Car>
{
public ParkingLot() { }
// this will be the pivot page title
public string Lot { get; set; }
// the list of cars will be displayed on the page
}
public class Car
{
public Car() { }
// this will be the data that is displayed in the pivot page for each car
public string Width { get; set; }
public string Length { get; set; }
}
public class Library : List<Book>
{
public Library() { }
// this will be the pivot page title
public string Location { get; set; }
// the list of books will be displayed on the page
}
public class Book
{
public Book() { }
// this is the data that will be displayed for each book
public string ISBN { get; set; }
public string Title { get; set; }
}
I don't know if it would be better to post all the code here... or just to have you all look at the article on Code project, I will post up the code that I modified from the article... in hopes that somebody can help me figure this out:
xaml :
<phone:PhoneApplicationPage x:Class="dynDataTemplateTest.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:loc="clr-namespace:dynDataTemplateTest.View"
xmlns:controls="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
SupportedOrientations="Portrait"
Orientation="Portrait"
mc:Ignorable="d"
d:DesignWidth="480"
d:DesignHeight="768"
shell:SystemTray.IsVisible="True"
DataContext="{Binding Main, Source={StaticResource Locator}}">
<!--LayoutRoot contains the root grid where all other page content is placed-->
<Grid x:Name="LayoutRoot"
Background="Transparent">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<!--TitlePanel contains the name of the application and page title-->
<StackPanel x:Name="TitlePanel"
Grid.Row="0"
Margin="24,24,0,12">
<TextBlock x:Name="ApplicationTitle"
Text="{Binding ApplicationTitle}"
Style="{StaticResource PhoneTextNormalStyle}" />
<TextBlock x:Name="PageTitle"
Text="{Binding PageName}"
Margin="-3,-8,0,0"
Style="{StaticResource PhoneTextTitle1Style}" />
</StackPanel>
<!--ContentPanel - place additional content here-->
<Grid x:Name="ContentGrid"
Grid.Row="1">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<loc:DynamicContentControl Content="{Binding SelectedItem}"
HorizontalContentAlignment="Stretch"
VerticalContentAlignment="Stretch" />
<controls:Pivot ItemsSource="{Binding Path=Items}" SelectedItem="{Binding Path=SelectedItem}" >
<controls:Pivot.HeaderTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=DisplayName}" FontSize="30" FontWeight="Bold" Margin="5"/>
</DataTemplate>
</controls:Pivot.HeaderTemplate>
<controls:Pivot.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center"></StackPanel>
</ItemsPanelTemplate>
</controls:Pivot.ItemsPanel>
</controls:Pivot>
</Grid>
</Grid>
Here is the DataTemplateSelector class
public static class DataTemplateSelector
{
public static DataTemplate GetTemplate(ViewModelBase param)
{
Type t = param.GetType();
return App.Current.Resources[t.Name] as DataTemplate;
}
}
Here is the dynamic Content control:
public class DynamicContentControl:ContentControl
{
protected override void OnContentChanged(object oldContent, object newContent)
{
base.OnContentChanged(oldContent, newContent);
this.ContentTemplate = mSator.Model.DataTemplateSelector.GetTemplate(newContent as ViewModelBase);
}
}
Here is the first view xaml:
<Grid x:Name="LayoutRoot" Background="{StaticResource PhoneChromeBrush}">
<TextBlock Margin="20" Foreground="Green" FontSize="32"
FontWeight="Bold" Text="{Binding Path=FirstProperty}"
></TextBlock>
</Grid>
( the second view xaml can be the first view, just change the color )
Here is the FirstViewModel class (from the article)
public class FirstViewModel : SelectableViewModel
{
public FirstViewModel()
{
DisplayName = "First";
FirstProperty = "this is the first property";
}
private string firstProp;
public string FirstProperty
{
get { return firstProp; }
set
{
if (firstProp != value)
{
firstProp = value;
RaisePropertyChanged("FirstProperty");
}
}
}
}
Here is the SelectableView Model class
public class SelectableViewModel : ViewModelBase
{
public SelectableViewModel()
{
}
string dispName;
public string DisplayName
{
get { return dispName; }
set
{
if (dispName != value)
{
dispName = value;
RaisePropertyChanged("DisplayName");
}
}
}
}
Here is the main view model class:
public class MainViewModel : ViewModelBase
{
public string ApplicationTitle
{
get
{
return "Dynamic Data Templates";
}
}
public string PageName
{
get
{
return "Main page";
}
}
private List<SelectableViewModel> viewModels;
public MainViewModel()
{
viewModels = new List<SelectableViewModel>();
viewModels.Add(new FirstViewModel());
viewModels.Add(new SecondViewModel());
SelectedItem = viewModels[0];
}
public List<SelectableViewModel> Items
{
get
{
return viewModels;
}
}
SelectableViewModel selItem;
public SelectableViewModel SelectedItem
{
get { return selItem; }
set
{
if (selItem != value)
{
selItem = value;
RaisePropertyChanged("SelectedItem");
}
}
}
}
Thanks again for helping !
As you say you're still learning, let me explain why having n number of Pivot items is a bad idea:
You will likely run into performance issues due to the amount of content on a single page. With a list the items can be virtualized. The Pivot control does not support virtualization of dynamically added PivotItems.
It's hard for people to navigate to a desired item when there are lots of PivotItems as there isn't a way to quickly get to the one that is wanted. Say you had 30 items in the pivot but wanted to get to the 15th one. That would require a lot of swiping and if doing it quickly it would be easy to go past the one that was wanted.
The Pivot Control is intended to be used for one of two purposes:
To show different views of a set of data. i.e. The email app shows different views of a mailbox in each PivotItem, filtered for "all", "unread", "flagged" and "urgent".
To show different pieces of related data. i.e. When viewing an individual contact/person you see different related actions and information grouped into the different PivotItems: "profiles", "what's new", "photos" and "history".
It is not the intention that the Pivot control should be used as a container for vast quantities of content, such as n collections of template lists.
It is suggested that the maximum number of items in a pivot should be 7 to avoid issues with performance and usability.
All in all, not using the Pivot control in one of the ways it was intended can cause performance issues for you as a developer and usability issues for the people using the app.
Both of which are scenarios to be avoided.
Sorry this isn't a direct answer to your question but hopefully it will help you develop a better app (or apps). ;)

can't' bind to ViewModel

I have a problem that resists the past few hours, here is the ViewModel code: (PS: I can not share the url stream but do not worry its march because I tested it with BreakPoint)
private ObservableCollection<CustomerPublic> customers;
List<CustomerPublic> liste = new List<CustomerPublic>();
public ObservableCollection<CustomerPublic> Customers
{
get
{ return customers; }
set
{
if (customers != value)
{
customers = value;
RaisePropertyChanged("Customers");
}
}
}
private int id;
public int ID
{
get
{
return id;
}
set
{
id = value;
RaisePropertyChanged("ID");
}
}
public Detail_AgenceViewModel(int id)
{
this.ID = id;
PopulateCollection();
}
public Detail_AgenceViewModel()
{
}
private void PopulateCollection()
{
ParseFeedRequest();
}
private void ParseFeedRequest()
{
RestClient client = new RestClient();
client.BaseUrl = "....";
RestRequest request = new RestRequest();
.......
client.ExecuteAsync(request, ParseFeedCallBack);
}
public void ParseFeedCallBack(IRestResponse response)
{
if (response.StatusCode == HttpStatusCode.OK)
{
ParseXMLFeed(response.Content);
}
}
private void ParseXMLFeed(string feed)
{
if (feed == null)
return;
XElement xmlItems = XElement.Parse(feed);
liste = (from response in xmlItems.Descendants("result")
let lib = response.Element("lib")
let adresse = response.Element("adresse")
select new CustomerPublic
{
lib = lib == null ? null : lib.Value,
adresse = adresse == null ? null : adresse.Value,
}).ToList();
Customers = new ObservableCollection<CustomerPublic>(liste);
}
the View:
<phone:PhoneApplicationPage.DataContext>
<vm:Detail_AgenceViewModel/>
</phone:PhoneApplicationPage.DataContext>
<Grid x:Name="LayoutRoot"
Background="Transparent">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<!--TitlePanel contains the name of the application and page title-->
<StackPanel x:Name="TitlePanel"
Grid.Row="0"
Margin="12,17,0,28">
<TextBlock x:Name="ApplicationTitle"
Text="MY APPLICATION"
Style="{StaticResource PhoneTextNormalStyle}" />
<TextBlock x:Name="PageTitle"
Text="page name"
Margin="9,-7,0,0"
Style="{StaticResource PhoneTextTitle1Style}" />
</StackPanel>
<!--ContentPanel - place additional content here-->
<StackPanel x:Name="ContentPanel" Grid.Row="2" Margin="12,0,12,0" Orientation="Vertical">
<!--TextBox Text="{Binding Count, Mode=TwoWay}" x:Name="tbCount" />
<TextBlock Text="{Binding Count}" /-->
<ListBox x:Name="Agences" ItemsSource="{Binding Customers}" >
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Vertical">
<TextBlock Text="{Binding lib}" />
<TextBlock Text="{Binding adresse}" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</StackPanel>
</Grid>
The problem is that its all going well Customers even she is loaded but nothing appears! someone has an idea?
You are setting Customers to a new instance of an observable collection!
When you change the observable collection to a new instance, you must use INotifyPropertyChanged to tell the view that the collection has changed to a new instance - although changes to the items IN the collection are notified, changes to the collection ITSELF are not.
When you do this:
Customers = new ObservableCollection<CustomerPublic>(liste);
The view is still bound to the OLD collection. You should do:
Customers.Clear();
foreach(var item in liste)
Customers.Add(item);
OR make sure that the Customers property calls the NotifyPropertyChanged function.
Have a check of this video or article for more info:
http://www.codeproject.com/Articles/371217/Apex-Part-1-Create-Your-First-MVVM-Application
http://www.youtube.com/watch?v=m4cx9w5fiwk&feature=youtu.be
Good luck and please do let me know if this helps!!
I'm having similar problems ;
public void FillList(List<StockItem> siList)
{
listBox.ItemsSource = siList;
}
Where sIList is a filled list of X items, with correctly named properties.
Program builds & runs fine, but the listbox isnt shown. (this problem started when transitioning into MVVM)
I've got it.
Check your datacontext - I bet it is null. I've had this exact same issue in WP7. In the constructor of your PhoneApplicationPage do:
DataContext = new Detail_AgenceViewModel();
and initialise it there. In WP7 when I create the datacontext in XAML it's null. Does this help?

Categories

Resources