Question

As a continuation of my last question, I can get the data correctly now just I am having a problem getting it to display. I want it to be in a DataForm control but I seem to be unable to connect it correctly. here is my code:

namespace SP2010
{
    public partial class MainPage : UserControl
    {

        ClientContext context;
        Web spWeb;
        List customerList;
        ListItemCollection allCustomers;
    public MainPage()
    {
            this.Loaded += new RoutedEventHandler(MainPage_Loaded);
            InitializeComponent();
    }

    void MainPage_Loaded(object sender, RoutedEventArgs e)
    {
        this.DataContext = this;
        context = new ClientContext(ApplicationContext.Current.Url);
        spWeb = context.Web;
        context.Load(spWeb);
        customerList = spWeb.Lists.GetByTitle("testlist");
        context.Load(customerList);
        CamlQuery camlQuery = new CamlQuery();
        camlQuery.ViewXml =
            @"<View>
            <Query></Query>
           <RowLimit>1000</RowLimit>
         </View>";
        allCustomers = customerList.GetItems(camlQuery);
        context.Load(allCustomers);
        context.ExecuteQueryAsync(new ClientRequestSucceededEventHandler(OnRequestSucceeded), new ClientRequestFailedEventHandler(OnRequestFailed));

    }
    private void OnRequestSucceeded(Object sender, ClientRequestSucceededEventArgs args)
    {
        Dispatcher.BeginInvoke(DisplayListData);
    }
    private void OnRequestFailed(Object sender, ClientRequestFailedEventArgs args)
    {
        MessageBox.Show(args.ErrorDetails + "   " + args.Message);
    }
    public ObservableCollection<SPCustomers> Printers
    {
        get
        {
            if (printers == null)
            {
                printers = new ObservableCollection<SPCustomers>();
                foreach (ListItem item in allCustomers)
                {
                    printers.Add(new SPCustomers
                    {
                        IPAddress = item["Title"].ToString(),
                        Make = item["make"].ToString(),
                        Model = item["model"].ToString(),
                        xCord = item["x"].ToString(),
                        yCord = item["y"].ToString()
                    });
                }
            }
            return (printers);
         }
    }
    private ObservableCollection<SPCustomers> printers;

does anyone know what I am doing wrong?

Was it helpful?

Solution

Sorry - real old post.. I kind of stumbled upon it...

  • In your MainPage_Loaded-Method you set the DataContext. Ater that your UI will bind to Printers.
  • This will cause the Printers_get to be executed - which in turn will iterate over allCustomers. allCustomers is either null or empty because context.ExecuteQueryAsync(...) will most definitively not have run at this point.
  • Then - some time later - you call context.ExecuteQueryAsync(...) which fills allCustomers - but you never tell your UI that it is time to refresh the Printes...

Real quick (but IMHO the wrong way) would be to move your this.DataContext = this into OnRequestSucceeded.

I would:

  • make MainPage implement INotifyPropertyChanged
  • in OnRequestSucceeded raise the PropertyChanged-event with Printers as the argument and by doing so tell the UI that it is time to update the Printers binding.
  • this will refresh the binding and re-execute Printers_get - which will do nothing new, because printers is no longer null - so I'd do something about that, too...

To stay close to your code a working example ("probably working" - I have not tested it..) would most probably look like this:

namespace SP2010
{
    public partial class MainPage : UserControl
    {

        ClientContext context;
        Web spWeb;
        List customerList;
        ListItemCollection allCustomers;
    public MainPage()
    {
            this.Loaded += new RoutedEventHandler(MainPage_Loaded);
            InitializeComponent();
            this.Printers = new ObservableCollection<SPCustomers> ();
            this.DataContext = this;
    }

    void MainPage_Loaded(object sender, RoutedEventArgs e)
    {
        context = new ClientContext(ApplicationContext.Current.Url);
        spWeb = context.Web;
        context.Load(spWeb);
        customerList = spWeb.Lists.GetByTitle("testlist");
        context.Load(customerList);
        CamlQuery camlQuery = new CamlQuery();
        camlQuery.ViewXml =
            @"<View>
            <Query></Query>
           <RowLimit>1000</RowLimit>
         </View>";
        allCustomers = customerList.GetItems(camlQuery);
        context.Load(allCustomers);
        context.ExecuteQueryAsync(new ClientRequestSucceededEventHandler(OnRequestSucceeded), new ClientRequestFailedEventHandler(OnRequestFailed));

    }
    private void OnRequestSucceeded(Object sender, ClientRequestSucceededEventArgs args)
    {
        //Dispatcher.BeginInvoke(DisplayListData);
        // Fill Printers:

        foreach (ListItem item in allCustomers)
        {
            Printers.Add(new SPCustomers
            {
                IPAddress = item["Title"].ToString(),
                Make = item["make"].ToString(),
                Model = item["model"].ToString(),
                xCord = item["x"].ToString(),
                yCord = item["y"].ToString()
            });
        }
    }
    private void OnRequestFailed(Object sender, ClientRequestFailedEventArgs args)
    {
        MessageBox.Show(args.ErrorDetails + "   " + args.Message);
    }

    public ObservableCollection<SPCustomers> Printers
    {
        get; private set;
    }

Notice that this still doesn't implement INotifyPropertyChanged, but Printers gets initialized in the contstructor and before setting the DataContext. This way the Binding to Printers will be o.k. and as you already utilized an ObservableCollection all changes to the collection will trigger an update of the UI.

Then I am filling the Printers collection in OnRequestSucceeded (without creating a new ObservableCollection). This way you should be able to see the printers as expected.

Licensed under: CC-BY-SA with attribution
Not affiliated with sharepoint.stackexchange
scroll top