Binding Observable Collection in XAML in Windows Phone
I am having trouble with declaratively setting the ItemsSource of a ListBox contained within a PivotItem in a simple Windows Phone 7 page. I can successfully set the ItemsSource in code behind.
Here is a snippet of the class that contains the ObservableCollection that I want to bind to:
sealed class Database : INotifyPropertyChanged
{
//Declare Instance
private static readonly Database instance = new Database();
//Private Constructor
private Database() { }
//The entry point into this Database
public static Database Instance
{
get
{
return instance;
}
}
#region Collections corresponding with database tables
public ObservableCollection<Category> Categories { get; set; }
public ObservableCollection<CategoryType> CategoryTypes { get; set; }
And here is a sample of my XAML:
<ListBox x:Name="CategoriesListB开发者_如何转开发ox" Margin="0,0,-12,0" ItemsSource="{Binding Categories}" DisplayMemberPath="Name" />
In my page I have tried setting the data context as follows:
this.DataContext = Database.Instance;
However the binding does not work unless I explicitly set the ItemsSource in code as follows:
CategoriesListBox.ItemsSource = Database.Instance.Categories;
I know that I should be able to do this all declaratively, however I have tried many different ways of setting the ItemsSource declaratively (in addition to what I have detailed above) and none work.
Can someone help me out?
Further info: The output windows at runtime shows the following: System.Windows.Data Error: Cannot get 'Categories' value (type 'System.Collections.ObjectModel.ObservableCollection`1[BTT.PinPointTime.Entities.Category]') from 'BTT.PinPointTime.WinPhone.Database' (type 'BTT.PinPointTime.WinPhone.Database'). BindingExpression: Path='Categories' DataItem='BTT.PinPointTime.WinPhone.Database' (HashCode=99825759); target element is 'System.Windows.Controls.ListBox' (Name='CategoriesListBox'); target property is 'ItemsSource' (type 'System.Collections.IEnumerable').. System.MethodAccessException: Attempt to access the method failed: BTT.PinPointTime.WinPhone.Database.get_Categories() at System.Reflection.RuntimeMethodInfo.InternalInvoke(Object obj, BindingFlags invokeAttr
I found out that the problem was related to the access level of my Database class. When I changed it from "sealed" to "public sealed" the databinding worked.
public sealed class Database : INotifyPropertyChanged
{
//Declare Instance
private static readonly Database instance = new Database();
//Private Constructor
private Database()
{
//Categories = new ObservableCollection<Category>();
}
//more code here....
Hmm I see that you are implementing INotifyPropertyChanged
, but not using it. You should add NotifyPropertyChanged("Categories");
in the get like so:
private ObservableCollection<Category> _categories
public ObservableCollection<Category> Categories {
get{return _categories;}
set
{
if (_categories == value) return;
_categories= value;
NotifyPropertyChanged("Categories");
}
}
when you want to add data to the category collection, use the property and not the member. it worked in my code, hope this helps.
Try instantiating the Categories in your Constructor code.
private Database()
{
Categories = new ObservableCollection<Category>();
}
Now your binding will know the collection properly.
精彩评论