Answered by:
DataForm does not display content

Question
-
My DataForm is not displaying the content in hte ItemsSource collection. Cna some one give me a hint as what I am doing wrong please? This is my DataForm:
<toolkit:DataForm x:Name="dfCustomer"
ItemsSource="{Binding List}"
AutoGenerateFields="True"
CommandButtonsVisibility="navigation"/>This is my view model:
public class CustomerViewModel: INotifyPropertyChanged
{
private ObservableCollection<Customer> list = new ObservableCollection<Customer>();
private CustomerDomainContext context;public CustomerViewModel()
{
context = new CustomerDomainContext();
context.Load<Customer>(context.GetCustomersQuery(), loadOp =>
{
foreach (var customer in context.Customers)
{
list.Add(customer);
NotifyPropertyChanged("itemAdded");
}
}, null);
}public ObservableCollection<Customer> List
{
get { return this.list; }
}
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(String info)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(info));
}
}
}The code behing Home.xaml is doing the following:
private CustomerViewModel customerViewModel = new CustomerViewModel();
public Home()
{
InitializeComponent();
Loaded += new System.Windows.RoutedEventHandler(Home_Loaded);
}void Home_Loaded(object sender, System.Windows.RoutedEventArgs e)
{
dfCustomer.DataContext = customerViewModel;
}This is not working. I can see that the navigation buttons are not active at startup and once the data has been loaded the buttons become enabled but nothing is displayed in the form. If I click the navigation buttons then the current item is displayed.
Can someone put me in the right direction here please?
Thursday, August 26, 2010 4:32 AM
Answers
-
Hi,
Please use a PagedCollectionView instead of ObservableCollection, on loaded delegate, call PagedCollectionView.MoveCurrentToFirst().
Here is some code:
MainPage.Xaml:
<UserControl x:Class="Forum198118.MainPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="400" xmlns:toolkit="http://schemas.microsoft.com/winfx/2006/xaml/presentation/toolkit"> <Grid x:Name="LayoutRoot" Background="White"> <toolkit:DataForm Height="100" HorizontalAlignment="Left" Margin="142,150,0,0" Name="dataForm1" VerticalAlignment="Top" Width="200" ItemsSource="{Binding List}" AutoGenerateFields="True" CommandButtonsVisibility="navigation" /> </Grid> </UserControl>
MainPage.cs
public partial class MainPage : UserControl,INotifyPropertyChanged { private ObservableCollection<Course> list = new ObservableCollection<Course>(); private DomainService1 client; public MainPage() { InitializeComponent(); client = new DomainService1(); client.Load<Course>(client.GetCoursesQuery(), loadop => { foreach (var course in client.Courses) { list.Add(course); } List.MoveCurrentToFirst(); NotifyPropertyChanged("List"); }, null); Loaded += new RoutedEventHandler(MainPage_Loaded); } public PagedCollectionView List { get { return new PagedCollectionView(list); } } void MainPage_Loaded(object sender, RoutedEventArgs e) { dataForm1.DataContext = this; } public event PropertyChangedEventHandler PropertyChanged; private void NotifyPropertyChanged(string propertyName) { if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); } } }
By the way, you should pass property name to NotifyPropertyChanged method.
Monday, August 30, 2010 2:56 AM
All replies
-
For some reason the Observer - Observable pattern is not working in this case and I do not know if this is a bug, by design or I am doing something weird. To "resolve" my problem I derived a DataForm which implements my version of IObserver
public class ObserverDataForm: DataForm, IObserver
{#region IObserver Members
public void Notify(object anObject)
{
ItemsSource = anObject as ObservableCollection<Customer>;
}#endregion
}Now the CustomerViewModel becomes IObservable by implementing my own version of the interface.
public class CustomerViewModel : INotifyPropertyChanged, IObservable
{
private ObservableCollection<Customer> list = new ObservableCollection<Customer>();
private CustomerDomainContext context;
private Dictionary<IObserver, IObserver> observerContainer = new Dictionary<IObserver, IObserver>();public CustomerViewModel()
{
context = new CustomerDomainContext();
context.Load<Customer>(context.GetCustomersQuery(), loadOp =>
{
foreach (var customer in context.Customers)
{
list.Add(customer);
NotifyPropertyChanged("itemAdded");
NotifyObservers(List);
}
}, null);
}public ObservableCollection<Customer> List
{
get { return this.list; }
}#region Notify Property Changed
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(String info)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(info));
}
}
#endregion#region IObservable Members
public void Register(IObserver anObserver)
{
observerContainer.Add(anObserver, anObserver);
}public void UnRegister(IObserver anObserver)
{
observerContainer.Remove(anObserver);
}#endregion
public void NotifyObservers(object anObject)
{
foreach (IObserver anObserver in observerContainer.Keys)
{
anObserver.Notify(anObject);
}
}
}The code behind now sets the DataContext of this new DataForm and registers with the Observable:
odfCustomer.DataContext = customerViewModel;
customerViewModel.Register(odfCustomer);
Now the data form loads fine, but I am not happy with this because it is too strange... my rule of thumb is: if it is too strange then it is probably wrong.
Can someone comment please?
Friday, August 27, 2010 3:21 AM -
Hi,
Please use a PagedCollectionView instead of ObservableCollection, on loaded delegate, call PagedCollectionView.MoveCurrentToFirst().
Here is some code:
MainPage.Xaml:
<UserControl x:Class="Forum198118.MainPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="400" xmlns:toolkit="http://schemas.microsoft.com/winfx/2006/xaml/presentation/toolkit"> <Grid x:Name="LayoutRoot" Background="White"> <toolkit:DataForm Height="100" HorizontalAlignment="Left" Margin="142,150,0,0" Name="dataForm1" VerticalAlignment="Top" Width="200" ItemsSource="{Binding List}" AutoGenerateFields="True" CommandButtonsVisibility="navigation" /> </Grid> </UserControl>
MainPage.cs
public partial class MainPage : UserControl,INotifyPropertyChanged { private ObservableCollection<Course> list = new ObservableCollection<Course>(); private DomainService1 client; public MainPage() { InitializeComponent(); client = new DomainService1(); client.Load<Course>(client.GetCoursesQuery(), loadop => { foreach (var course in client.Courses) { list.Add(course); } List.MoveCurrentToFirst(); NotifyPropertyChanged("List"); }, null); Loaded += new RoutedEventHandler(MainPage_Loaded); } public PagedCollectionView List { get { return new PagedCollectionView(list); } } void MainPage_Loaded(object sender, RoutedEventArgs e) { dataForm1.DataContext = this; } public event PropertyChangedEventHandler PropertyChanged; private void NotifyPropertyChanged(string propertyName) { if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); } } }
By the way, you should pass property name to NotifyPropertyChanged method.
Monday, August 30, 2010 2:56 AM -
Thank you Frank! Returning the PagedCollectionView instead of the ObservableCollection was the correct solution. Thanks for caching my bug in the property name as well!
Cheers!@
Monday, August 30, 2010 4:40 PM