locked
Silverlightanwendung kann keine nachgeschlagenen SharePoint-Spalten auslesen!?!? RRS feed

  • Frage

  • Hi,

    ich habe erfolgreich das Tutorial Create a Silverlight 4 Webpart for SharePoint2010 absolviert. Hat auch alles super funktioniert, allerdings  habe ich folgendes Problem:

    Ich möchte aus meiner SharePoint-Liste nun auch "nachgeschlagene Werte" anzeigen lassen. Wenn ich die Spalten in meiner Silverlightanwendung anzeigen lasse, so steht dort immer nur "Microsoft.SharePoint.Client" anstatt der Wert der Spalte.

    Kann mir da jemand weiterhelfen?

    Grüße,

     

    Florian

     

     

    Montag, 8. November 2010 18:23

Antworten

  • Hallo Florian,

    so wie ich das sehe müsstes du für alle Felder den Text "Microsoft.SharePoint.Client.ListItem" erhalten. Meinst du mit "nachgeschlagene Werte" allgemein die Werte die du abrufst oder tatsächlich Nachschlagespalten im SharePoint?

    Dein Code ist so weit fast richtig. Vom SharePoint bekommst du eine ListItemsCollection zurück. Genau da liegt derzeit dein Problem. Durch das einfache Binding an die Listbox wird lediglich die ToString - Methode des Objektes aufgerufen. Ein ListItem kann aber über 200 Spalten enthalten und diese musst du für die Ausgabe Adressieren.

    Entweder du nutzt bei deinem Binding auch noch einen Converter (ListItem zu Text) siehe: http://www.silverlight-community.de/2010/11/textformatierung-trotz-databinding/

    Oder du gehst alle Elemente über ein ForEach durch und suchst dir die benötigten Spalten zusammen.

    Hier ein Beispiel um den Titel anzuzeigen:

    void ContactsLoaded(object sender, Microsoft.SharePoint.Client.ClientRequestSucceededEventArgs args)
    {
      this.Dispatcher.BeginInvoke(() =>
      {
        List<string> titles = new List<string>();
        foreach (Microsoft.SharePoint.Client.ListItem li in contactsListItems) titles.Add(li["Title"].ToString());
        lb.ItemsSource = titles;
      });
    }
    
    

    Selbst wenn du ein DataGrid nutzt kannst du kein direktes Binding verwenden, da die Spalteninformationen nicht direkt im ListItem enthalten sind sondern in untergeordneten Propertys oder über den Enumerator.

     

    Daniel


    silverlight-community.de - deutsche Community mit Tutorials, Blogs und Usergroups
    Freitag, 12. November 2010 13:09
  • Hi.

    Also "unbehandelte Ausnahmen" sollten gar nicht vorkommen ;-) .

    Versuchs mal mit try - catch und einer expliziten Ausgabe der Fehlermeldung. Damit kannst du dann auch besser ergründen wo der Fehler passiert und welches item betroffen ist.

    Ich tippe mal darauf das du nicht in allen Einträgen/Zeilen deiner Liste diesen Wert gesetzt hast. Das musst du vorher natürlich prüfen.

    if (li["Spalte"] != null)
    {
       titles.Add(li["Spalte"].ToString());
    }

    Alternativ kann ich mir vorstellen das die Daten nicht über das OM geladen wurden (sollte bei Nachschlagelisten aber nicht der Fall sein). In diesem Fall müsstest du der Load - Anweisung noch mitgeben welchen Spalten abgerufen werden sollen. Zum Beispiel so:

    ctx.Load(contactsListItems, li=>li.Include(item => item["zu ladende Spalte"]));
    

    Denke dran, wenn es eine Nachschlagespalte ist musst du noch einen Cast auf FieldLookupValue machen um an den Wert zu kommen.

    Daniel


    http://www.silverlight-community.de - deutsche Community mit Tutorials, Blogs und Usergroups
    Montag, 15. November 2010 15:10
  • Hi,

    ich habs ENDLICH (!!!) geschafft :-) Danke Daniel für die Hilfe!!!^^

    also mit einem Converter hat es am besten funktioniert!

    ich habe eine neue Klasse erstellt: 

    using System;
    using System.Net;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Documents;
    using System.Windows.Ink;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Animation;
    using System.Windows.Shapes;
    using System.Windows.Data;
    using Microsoft.SharePoint.Client;
    
    namespace SilverlightSPIntegration
    {
        public class ListItemConverter : IValueConverter
        {
          public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
          {     
            if (value is Microsoft.SharePoint.Client.FieldLookupValue)
            {
              FieldLookupValue _look = (FieldLookupValue)value;
              return _look.LookupValue.ToString();
            }
            return value;
          }
    
          public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
          {
            throw new NotImplementedException();
          }
        }
      }
    
    

    in meiner MainPage.xaml hab ich dann bei meiner entsprechenden Spalte mit dem Lookupwert folgendes ergänzt:

    <TextBlock VerticalAlignment="Top" Margin="0,100,79,0" Text="Betreuer"/>
            <TextBlock Text="{Binding Converter={StaticResource ListItemConverter}, ConverterParameter='Betreuer', Mode=OneWay, Path=FieldValues[Betreuer]}" HorizontalAlignment="Left" Width="517" Margin="104,100,0,0" />
      			
    

    in der App.xaml muss noch das xmlns:local tag ergänzt werden, sowie unter Resources der Converter eingetragen 

    <Application xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
           xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
           xmlns:SampleData="clr-namespace:Expression.Blend.SampleData.SharePointSampleDataSampleDataSource" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" 
           x:Class="SilverlightSPIntegration.App"
           xmlns:local="clr-namespace:SilverlightSPIntegration"
           >
      <Application.Resources>
        <local:ListItemConverter x:Key="ListItemConverter"/>
      	<SampleData:SharePointListItems x:Key="SharePointSampleDataSampleDataSource" d:IsDataSource="True"/>
        </Application.Resources>
    </Application>
    

     

    • Als Antwort markiert M4nTis Samstag, 4. Dezember 2010 11:55
    Samstag, 4. Dezember 2010 11:54

Alle Antworten

  • Wie greifst du denn auf die nachgeschlagenen Felder zu?


    Gruß Daniel

    http://www.silverlight-community.de - Silverlight Community und Usergroups

    Dienstag, 9. November 2010 18:01
  • Mein Code sieht so aus:

    und wie gesagt, normale felder werden ausgegeben, nachgeschlagene werden nur als "Microsoft.SharePoint.Client" dargestellt...

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Net;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Animation;
    using System.Windows.Shapes;
    using Microsoft.SharePoint.Client;
    
    namespace SilverlightSPIntegration
    {
     public partial class MainPage : UserControl
     {
      ClientContext ctx;
      ListItemCollection contactsListItems;
      public MainPage()
      {
       InitializeComponent();
       this.Loaded += MainPage_Loaded;
      }
    
      void MainPage_Loaded(object sender, RoutedEventArgs e)
      {
       LoadList();
      }
    
      
      void LoadList()
      {
       
       ctx = ClientContext.Current;
       if (ctx != null)
       {
        List dokList = ctx.Web.Lists.GetByTitle("Dokumente");
        contactsListItems = dokList.GetItems(CamlQuery.CreateAllItemsQuery());
        ctx.Load(contactsListItems);
        ctx.ExecuteQueryAsync(ContactsLoaded, ContactsLoadedFail);
       }
    
      }
    
      void ContactsLoaded(object sender, ClientRequestSucceededEventArgs args)
      {
       this.Dispatcher.BeginInvoke(() =>
       {
        listBox.ItemsSource = contactsListItems;
       });
      }
      
      void ContactsLoadedFail(object sender, ClientRequestFailedEventArgs args)
      {
       this.Dispatcher.BeginInvoke(() =>
       {
        listBox.ItemsSource = contactsListItems;
       });
      }
    
    
    
     }
    }
    

    Dienstag, 9. November 2010 18:43
  • Hallo Florian,

    so wie ich das sehe müsstes du für alle Felder den Text "Microsoft.SharePoint.Client.ListItem" erhalten. Meinst du mit "nachgeschlagene Werte" allgemein die Werte die du abrufst oder tatsächlich Nachschlagespalten im SharePoint?

    Dein Code ist so weit fast richtig. Vom SharePoint bekommst du eine ListItemsCollection zurück. Genau da liegt derzeit dein Problem. Durch das einfache Binding an die Listbox wird lediglich die ToString - Methode des Objektes aufgerufen. Ein ListItem kann aber über 200 Spalten enthalten und diese musst du für die Ausgabe Adressieren.

    Entweder du nutzt bei deinem Binding auch noch einen Converter (ListItem zu Text) siehe: http://www.silverlight-community.de/2010/11/textformatierung-trotz-databinding/

    Oder du gehst alle Elemente über ein ForEach durch und suchst dir die benötigten Spalten zusammen.

    Hier ein Beispiel um den Titel anzuzeigen:

    void ContactsLoaded(object sender, Microsoft.SharePoint.Client.ClientRequestSucceededEventArgs args)
    {
      this.Dispatcher.BeginInvoke(() =>
      {
        List<string> titles = new List<string>();
        foreach (Microsoft.SharePoint.Client.ListItem li in contactsListItems) titles.Add(li["Title"].ToString());
        lb.ItemsSource = titles;
      });
    }
    
    

    Selbst wenn du ein DataGrid nutzt kannst du kein direktes Binding verwenden, da die Spalteninformationen nicht direkt im ListItem enthalten sind sondern in untergeordneten Propertys oder über den Enumerator.

     

    Daniel


    silverlight-community.de - deutsche Community mit Tutorials, Blogs und Usergroups
    Freitag, 12. November 2010 13:09
  • Hi Daniel,

    danke für deine Antwort! 

    Mit nachgeschlagenen Werten, mein ich die Werte die in "Nachschlagespalten" drin sind. Also quasi die Links zu Einträgen in anderen Listen.

    Ich habe mich jetzt für die foreach-Variante entschieden, bekomm allerdings einen Fehler im Browser angezeigt. 

    Er sagt: "Unhandled Error in Silverlight Application Der Objektverweis wurde nicht auf eine Objektinstanz festgelegt. bei MainPage.<ListLoaded>b__O()

    Kann damit irgendwie nichts anfangen. Könntest Du mir da nochmal helfen? Hier mein Code:

     

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Net;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Animation;
    using System.Windows.Shapes;
    using Microsoft.SharePoint.Client;
    
    namespace SilverlightSPIntegration
    {
      public partial class MainPage : UserControl
      {
        ClientContext ctx;
        ListItemCollection listItems;
        public MainPage()
        {
          InitializeComponent();
          this.Loaded += MainPage_Loaded;
        }
    
        void MainPage_Loaded(object sender, RoutedEventArgs e)
        {
          LoadList();
        }
    
        
        void LoadList()
        {
          
          ctx = ClientContext.Current;
          if (ctx != null)
          {
            List dokList = ctx.Web.Lists.GetByTitle("Dokumente");
            this.listItems = dokList.GetItems(CamlQuery.CreateAllItemsQuery());
            ctx.Load(this.listItems);
            ctx.ExecuteQueryAsync(ListLoaded, ListLoadedFail);
          }
    
        }
    
        void ListLoaded(object sender, ClientRequestSucceededEventArgs args)
        {
          this.Dispatcher.BeginInvoke(() =>
          {
            //String-Liste erstellen, nimmt die Titel der Spalten auf
            List<String> titles = new List<string>();
            //Gehe jedes ListItem in listItems durch
            foreach (Microsoft.SharePoint.Client.ListItem li in this.listItems)
            {
              //Schreibe den Titel der Spalte in die titles-Liste
              titles.Add(li["Title"].ToString());
            }
            //übergib die Titel an die Listbox
            listBox.ItemsSource = titles;
    
            //alt
            //listBox.ItemsSource = listItems;
          });
        }
        
        void ListLoadedFail(object sender, ClientRequestFailedEventArgs args)
        {
          this.Dispatcher.BeginInvoke(() =>
          {
            listBox.ItemsSource = listItems;
          });
        }
    
    
    
      }
    }
    
    

    Montag, 15. November 2010 13:18
  • Hi.

    Also "unbehandelte Ausnahmen" sollten gar nicht vorkommen ;-) .

    Versuchs mal mit try - catch und einer expliziten Ausgabe der Fehlermeldung. Damit kannst du dann auch besser ergründen wo der Fehler passiert und welches item betroffen ist.

    Ich tippe mal darauf das du nicht in allen Einträgen/Zeilen deiner Liste diesen Wert gesetzt hast. Das musst du vorher natürlich prüfen.

    if (li["Spalte"] != null)
    {
       titles.Add(li["Spalte"].ToString());
    }

    Alternativ kann ich mir vorstellen das die Daten nicht über das OM geladen wurden (sollte bei Nachschlagelisten aber nicht der Fall sein). In diesem Fall müsstest du der Load - Anweisung noch mitgeben welchen Spalten abgerufen werden sollen. Zum Beispiel so:

    ctx.Load(contactsListItems, li=>li.Include(item => item["zu ladende Spalte"]));
    

    Denke dran, wenn es eine Nachschlagespalte ist musst du noch einen Cast auf FieldLookupValue machen um an den Wert zu kommen.

    Daniel


    http://www.silverlight-community.de - deutsche Community mit Tutorials, Blogs und Usergroups
    Montag, 15. November 2010 15:10
  • Hi,

    ich habs ENDLICH (!!!) geschafft :-) Danke Daniel für die Hilfe!!!^^

    also mit einem Converter hat es am besten funktioniert!

    ich habe eine neue Klasse erstellt: 

    using System;
    using System.Net;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Documents;
    using System.Windows.Ink;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Animation;
    using System.Windows.Shapes;
    using System.Windows.Data;
    using Microsoft.SharePoint.Client;
    
    namespace SilverlightSPIntegration
    {
        public class ListItemConverter : IValueConverter
        {
          public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
          {     
            if (value is Microsoft.SharePoint.Client.FieldLookupValue)
            {
              FieldLookupValue _look = (FieldLookupValue)value;
              return _look.LookupValue.ToString();
            }
            return value;
          }
    
          public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
          {
            throw new NotImplementedException();
          }
        }
      }
    
    

    in meiner MainPage.xaml hab ich dann bei meiner entsprechenden Spalte mit dem Lookupwert folgendes ergänzt:

    <TextBlock VerticalAlignment="Top" Margin="0,100,79,0" Text="Betreuer"/>
            <TextBlock Text="{Binding Converter={StaticResource ListItemConverter}, ConverterParameter='Betreuer', Mode=OneWay, Path=FieldValues[Betreuer]}" HorizontalAlignment="Left" Width="517" Margin="104,100,0,0" />
      			
    

    in der App.xaml muss noch das xmlns:local tag ergänzt werden, sowie unter Resources der Converter eingetragen 

    <Application xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
           xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
           xmlns:SampleData="clr-namespace:Expression.Blend.SampleData.SharePointSampleDataSampleDataSource" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" 
           x:Class="SilverlightSPIntegration.App"
           xmlns:local="clr-namespace:SilverlightSPIntegration"
           >
      <Application.Resources>
        <local:ListItemConverter x:Key="ListItemConverter"/>
      	<SampleData:SharePointListItems x:Key="SharePointSampleDataSampleDataSource" d:IsDataSource="True"/>
        </Application.Resources>
    </Application>
    

     

    • Als Antwort markiert M4nTis Samstag, 4. Dezember 2010 11:55
    Samstag, 4. Dezember 2010 11:54