Take the 2-minute tour ×
SharePoint Stack Exchange is a question and answer site for SharePoint enthusiasts. It's 100% free, no registration required.

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?

share|improve this question
    
Can we see the DisplayListData method? –  James Love Jul 8 '11 at 18:01
    
for now it is empty because that was left over from a previous method I attempted <df:DataForm ItemsSource="{Binding Printers}" Height="276" HorizontalAlignment="Left" Margin="12,12,0,0" Name="dataForm1" VerticalAlignment="Top" Width="376" /> is where I bind it to the dataform –  BeardFist Jul 8 '11 at 18:19
    
The DisplayListData method will do the logic once the data has been returned form the server. If it's empty, nothing will happen. –  James Love Jul 8 '11 at 19:54
    
Then how would I tell it to update or otherwise show the data that it is connected to? –  BeardFist Jul 8 '11 at 20:36
    
The DisplayListData method would contain the logic to bind the data in your allCustomers (I think you can call 'GetDataTable' on this object, might need to 'Load' it first, though). –  James Love Jul 8 '11 at 20:44

1 Answer 1

up vote 1 down vote accepted

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.

share|improve this answer
    
Old question and old answer but thank you for the answer anyway. If I remember correctly then I did solve this issue one way or another. I doubt I could figure out what I did in any reasonable amount of time though, I haven't touched the code or the language in 2 years. I'll just give you the benefit of the doubt that this would fix the problem I was having at the time. Thanks again :) –  BeardFist Mar 13 '13 at 5:04

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.