Silverlight在MOSS2010上用作前端显示,给用户带来了更好的体验,也让开发者在作前端UI上有了更多的选择,是为前端的开发利器。

这里要记录的开发工作是这样的:需要在首页上显示一个Event的视图,用来显示一周内公司所有的Event,这些event的源头可能来自不同的站点,因此需要先在后台创建一个job,每天先从这些不同的站点下收集event,存放在一个list中,然后再将这个list数据用Silverlight显示出来。

为了以后更方便的访问SharePoint服务器端的对象模型,我们对底层的list数据访问进行了抽象,我们创建了common的类库,在其中创建了几个泛型接口:

interface IListDataCreate<T>
    {
        bool InsertDataIntoList(T t);
    }

  public interface IListDataDelete
    {
        void DeleteListItems(int[] itemIDlist);
    }

 public interface IListDataRetrieve<T>
    {
        T ListDataItemRetrieve();
    }

这些接口代表了对List的查询,增,删等等操作,然后创建抽象类

class BaseItemDataOperation<M, N> : IDisposable, IListDataCreate<M>, IListDataRetrieve<N>, IListDataDelete
    {
        protected SPSite currentSite = null;
        protected SPWeb currentWeb = null;
        protected SPList targetList = null;
        protected string listName = String.Empty;

        public BaseItemDataOperation(string currentSiteURL)
        {
            currentSite = new SPSite(currentSiteURL);
            currentWeb = currentSite.OpenWeb();
        }

        public abstract bool InsertDataIntoList(M m);
        public abstract N ListDataItemRetrieve();
        public abstract void DeleteListItems(int[] itemIds);

        public virtual void Dispose()
        {
            if (null != currentWeb)
            {
                currentWeb.Close();
            }
            if (null != currentSite)
            {
                currentSite.Close();
            }
        }
          
    }

创建实现类,继承上面的父类,实现接口方法

object>>, SPListItemCollection>
    {
        private string camlQuery = String.Empty;
        public string CamlQuery
        {
            get;
            set;
        }

        public string ListName
        {
            get;
            set;
        }

        public SPListItemCollectionCRUD(string currentSiteURL, string listName):base(currentSiteURL)
        {
            this.ListName = listName;
        }

        public SPListItemCollectionCRUD(string currentSiteURL, string camlQuery, string listName):this(currentSiteURL,listName)
        {
            CamlQuery = camlQuery;
        }

        #region //IListDataRetrieve method implement
        /// <summary>
        /// Retrieve data from target list
        /// </summary>
        /// <returns></returns>
        public override SPListItemCollection ListDataItemRetrieve()
        {
            if (String.IsNullOrEmpty(CamlQuery))
            {
                throw new Exception("Please provide caml string.");
            }
            else
            {
                if (String.IsNullOrEmpty(ListName))
                {
                    throw new Exception("Please provide target list name.");
                }
                else
                {
                    targetList = currentWeb.Lists[ListName];
                    SPQuery query = new SPQuery();
                    query.Query = CamlQuery;
                    return targetList.GetItems(query);
                }
            }
        }
        #endregion

        #region //IListDataCreate method implement
        /// <summary>
        /// Add one Item to target list
        /// </summary>
        /// <param name="fieldValuePairs">The source data, set as field value pairs</param>
        /// <returns></returns>
        public override bool InsertDataIntoList(IList<Dictionary<string, object>> itemList)
        {
            if (String.IsNullOrEmpty(ListName))
            {
                throw new Exception("Please provide target list name.");
            }
            else
            {
                try
                {
                    targetList = currentWeb.Lists[ListName];
                    SPListItem newItem = null;
                    for (int i = 0; i < itemList.Count; i++)
                    {
                        newItem = targetList.AddItem();
                        Dictionary<string, object> fieldValuePairs = itemList[i];
                        foreach (KeyValuePair<string, object> item in fieldValuePairs)
                        {
                            newItem[item.Key] = item.Value;
                        }
                        newItem.Update();
                    }
                    return true;
                }
                catch
                {
                    return false;
                }
            }
        }
        #endregion


        #region//IListDataDelete method implement
        /// <summary>
        /// Delete item from list by id list
        /// </summary>
        /// <param name="itemIds"></param>
        public override void DeleteListItems(int[] itemIds)
        {
            targetList = currentWeb.Lists[ListName];
            foreach(int id in itemIds)
            {
                targetList.Items.DeleteItemById(id);
            }
        }
        #endregion

        public void DeleteAllItems()
        {
            targetList = currentWeb.Lists[ListName];
            for (int i = targetList.ItemCount - 1; i >= 0; i--)
            {
                targetList.Items[i].Delete();
            }
        }
        #region //IDispose method
        public override void Dispose()
        {
            if (null != currentWeb)
            {
                currentWeb.Close();
            }
            if (null != currentSite)
            {
                currentSite.Close();
            }
        }
        #endregion
    }

注意在编译这个library时,确保你项目属性的.net framework为3.5,因为你引用的Microsoft.SharePoint .dll .Net Framework 3.5的,而VS2010默认是4.0。

[SharePoint 2010]一个完整的Silverlight显示List数据的例子

这样一个Common的List数据操作类库就完成了,以后可以不断的重用它,并且加入新的方法,现在我们创建一个Console项目作为每天获取Event的Job程序,添加对Common library的引用,并且在main方法中获取来自别的Site的List中的event数据并写入我们创建的用于首页显示的List中:

string[] args)
        {
            string siteURL = "Your target site";
            string knowledgeSite = "Your source site";
            string camlQuery = "";
            string listName = "Your source list";
            string insertTargetListName = "Your target list";

            DateTime firstWeekday = DateTime.Now.AddDays(((double)DateTime.Now.DayOfWeek - 1.0) * -1.0);
            DateTime endWeekDay = DateTime.Now.AddDays((7 - (double) DateTime.Now.DayOfWeek) * 1.0);
            string isoFirstDate = SPUtility.CreateISO8601DateTimeFromSystemDateTime(firstWeekday);
            string isoEndDate = SPUtility.CreateISO8601DateTimeFromSystemDateTime(endWeekDay);
            camlQuery = @"<ViewFields>
                        <FieldRef Name='LinkTitle' />
                        <FieldRef Name='Start_x0020_Time' />
                        <FieldRef Name='End_x0020_Time' />
                        </ViewFields>
                        <OrderBy>
                        <FieldRef Name='Start_x0020_Time'/>
                        </OrderBy>
                        <Where>
                        <And>
                        <Geq>
                        <FieldRef Name= 'Start_x0020_Time' />
                        <Value Type='DateTime'>" + isoFirstDate + @"</Value>
                        </Geq>
                        <Leq>
                        <FieldRef Name= 'End_x0020_Time' />
                        <Value Type='DateTime'>" + isoEndDate + @"</Value>
                        </Leq>
                        </And>
                        </Where>
                        ";
            using (BaseItemDataOperation<IList<Dictionary<string, object>>, SPListItemCollection> listRetrieve = new SPListItemCollectionCRUD(knowledgeSite, camlQuery, listName))
            {
                SPListItemCollection itemCollection = listRetrieve.ListDataItemRetrieve();
                using (BaseItemDataOperation<IList<Dictionary<string, object>>, SPListItemCollection> listCreate = new SPListItemCollectionCRUD(siteURL, insertTargetListName))
                {
                    List<Dictionary<string, object>> dataCollection = new List<Dictionary<string, object>>();
                    
                    foreach (SPListItem item in itemCollection)
                    {
                        Dictionary<string, object> keyValuePairs = new Dictionary<string, object>();
                        keyValuePairs["Title"] = item["Topic"];
                        keyValuePairs["Time Span"] = item["Start Time"].ToString() + " ~ " + item["End Time"].ToString();
                        keyValuePairs["Original Link"] = knowledgeSite + "/Lists/Training%20Schedule/DispForm.aspx?ID=" + item.ID.ToString();
                        dataCollection.Add(keyValuePairs);
                    }
                    (listCreate as SPListItemCollectionCRUD).DeleteAllItems();
                    bool isSuccess = listCreate.InsertDataIntoList(dataCollection);
                }
            }
        }

每天运行这个Job,保证最终List中汇集了当前周的所以Event。在编译运行这个Job前,先确认此project属性中的target platform设为x64,因为moss2010运行在64位的平台上,不作此设置,运行将会出错。

[SharePoint 2010]一个完整的Silverlight显示List数据的例子

现在开始介绍前端Silverlight显示的部分:

首先创建一个Silverlight library 用来完成所有底层访问SharePoint 客户端对象模型的操作,具体代码如下

class BaseClientListProxy <T>
    {
        protected string SiteURL { get; set; }
        public abstract void GetListItemsAsync(string listName, string queryXML, out T listItems);
    }
 public class ClientOMProxy:BaseClientListProxy<ListItemCollection>, IDisposable
    {
        private ClientContext clientContext = null;
        public ListItemCollection listItems = null;
        public ClientOMProxy(string siteURL)
        {
            this.SiteURL = siteURL;
            clientContext = new ClientContext(this.SiteURL);
        }

        public ClientRequestSucceededEventHandler successEventHandler = null;
        public ClientRequestFailedEventHandler failEventHandler = null;

        public override void GetListItemsAsync(string listName, string viewXML, out ListItemCollection listItems)
        {
            clientContext.Load(clientContext.Web);
            List targetList = clientContext.Web.Lists.GetByTitle(listName);
            clientContext.Load(targetList);
            CamlQuery camlQuery = new CamlQuery();
            camlQuery.ViewXml = viewXML;
            listItems = targetList.GetItems(camlQuery);
            clientContext.Load(listItems);
            clientContext.ExecuteQueryAsync(successEventHandler, failEventHandler);
        }

        public void CreateListItemAsync(string listName, Dictionary<string, object> fieldValueDic, ClientRequestSucceededEventHandler onSuccess, ClientRequestFailedEventHandler onFail)
        {
            clientContext.Load(clientContext.Web);
            List targetList = clientContext.Web.Lists.GetByTitle(listName);
            clientContext.Load(targetList);
            ListItemCreationInformation itemCreateInfo = new ListItemCreationInformation();
            ListItem oListItem = targetList.AddItem(itemCreateInfo);
            foreach (KeyValuePair<string, object> pair in fieldValueDic)
            {
                oListItem[pair.Key] = pair.Value;
            }
            oListItem.Update();
            clientContext.Load(oListItem);
            clientContext.ExecuteQueryAsync(onSuccess, onFail);
        }

        public void UpdateListItemAsync(string listName, ListItem item, Dictionary<string, object> fieldValueDic, ClientRequestSucceededEventHandler onSuccess, ClientRequestFailedEventHandler onFail)
        {
            clientContext.Load(clientContext.Web);
            List targetList = clientContext.Web.Lists.GetByTitle(listName);
            clientContext.Load(targetList);
            ListItem oListItem = item;
            foreach (KeyValuePair<string, object> pair in fieldValueDic)
            {
                oListItem[pair.Key] = pair.Value;
            }
            oListItem.Update();
            clientContext.Load(oListItem);
            clientContext.ExecuteQueryAsync(onSuccess, onFail);
        }

        public void Dispose()
        {
            if (null != clientContext)
                clientContext.Dispose();
        }
    }

然后创建Silverlight Application project,在mainpage.xaml文件中添加datagrid,设置显示style和绑定列

1" BorderBrush="#b8babd" CornerRadius="10" Width="280" Height="200">
        <data:DataGrid Name="eventGrid" AutoGenerateColumns="False"  Margin="5,5,5,5" BorderThickness="0" IsReadOnly="True"  CanUserResizeColumns="False" AlternatingRowBackground="White" HorizontalAlignment="Center">
        <data:DataGrid.ColumnHeaderStyle> 
        <Style  
            xmlns:primitives="clr-namespace:System.Windows.Controls.Primitives;assembly=System.Windows.Controls.Data"  
            xmlns:vsm="clr-namespace:System.Windows;assembly=System.Windows" 
            TargetType="primitives:DataGridColumnHeader" >
        <Setter Property="Foreground" Value="White"></Setter>
        <Setter Property="Template"> 
                <Setter.Value> 
                    <ControlTemplate TargetType="primitives:DataGridColumnHeader" >
                        <Grid Name="Root"> 
                            <vsm:VisualStateManager.VisualStateGroups> 
                                <vsm:VisualStateGroup x:Name="SortStates" > 
                                    <vsm:VisualStateGroup.Transitions> 
                                        <vsm:VisualTransition GeneratedDuration="00:00:0.1" /> 
                                    </vsm:VisualStateGroup.Transitions> 
                                    <vsm:VisualState x:Name="Unsorted" /> 
                                    <vsm:VisualState x:Name="SortAscending"> 
                                        <Storyboard> 
                                            <DoubleAnimation Storyboard.TargetName="SortIcon" Storyboard.TargetProperty="Opacity" Duration="0" To="1.0" /> 
                                        </Storyboard> 
                                    </vsm:VisualState> 
                                    <vsm:VisualState x:Name="SortDescending"> 
                                        <Storyboard> 
                                            <DoubleAnimation Storyboard.TargetName="SortIcon" Storyboard.TargetProperty="Opacity" Duration="0" To="1.0" /> 
                                            <DoubleAnimation Storyboard.TargetName="SortIconTransform" Storyboard.TargetProperty="ScaleY" Duration="0" To="-.9" /> 
                                        </Storyboard> 
                                    </vsm:VisualState> 
                                </vsm:VisualStateGroup> 
                            </vsm:VisualStateManager.VisualStateGroups> 
                            <Grid.RowDefinitions> 
                                <RowDefinition Height="*" /> 
                                <RowDefinition Height="*" /> 
                                <RowDefinition Height="Auto" /> 
                            </Grid.RowDefinitions> 
                            <Grid.ColumnDefinitions> 
                                <ColumnDefinition Width="Auto" /> 
                                <ColumnDefinition Width="*" /> 
                                <ColumnDefinition Width="Auto" /> 
                            </Grid.ColumnDefinitions>
                            <Rectangle x:Name="BackgroundRectangle" Stretch="Fill" Grid.ColumnSpan="2" Grid.RowSpan="2">
                                <Rectangle.Fill>
                                    <LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
                                        <GradientStop Color="#2A3A57" Offset="0.0" ></GradientStop>
                                        <GradientStop Color="#6c8cbe" Offset="1.0"></GradientStop>
                                    </LinearGradientBrush>
                                </Rectangle.Fill>
                            </Rectangle>
                            <ContentPresenter Grid.RowSpan="2" Content="{TemplateBinding Content}" Cursor="{TemplateBinding Cursor}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" Margin="{TemplateBinding Padding}" /> 
                            <Rectangle Name="VerticalSeparator" Grid.RowSpan="2" Grid.Column="2" Width="1" VerticalAlignment="Stretch" Fill="{TemplateBinding SeparatorBrush}" Visibility="{TemplateBinding SeparatorVisibility}" /> 
                            <Path Grid.RowSpan="2" Name="SortIcon" RenderTransformOrigin=".5,.5" HorizontalAlignment="Left" VerticalAlignment="Center" Opacity="0" Grid.Column="1" Stretch="Uniform" Width="8" Data="F1 M -5.215,6.099L 5.215,6.099L 0,0L -5.215,6.099 Z "> 
                                <Path.Fill> 
                                    <SolidColorBrush Color="#FF444444" /> 
                                </Path.Fill> 
                                <Path.RenderTransform> 
                                    <TransformGroup> 
                                        <ScaleTransform x:Name="SortIconTransform" ScaleX=".9" ScaleY=".9"  /> 
                                    </TransformGroup> 
                                </Path.RenderTransform> 
                            </Path> 
                        </Grid> 
                    </ControlTemplate> 
                </Setter.Value> 
            </Setter> 
        </Style> 
    </data:DataGrid.ColumnHeaderStyle> 

            <data:DataGrid.Columns>
                <data:DataGridTemplateColumn Width="Auto" CanUserResize="False" Header="">
                            <data:DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                                <Grid>
                                    <Grid.RowDefinitions>
                                        <RowDefinition Height="Auto"></RowDefinition>
                                        <RowDefinition Height="Auto"></RowDefinition>
                                    </Grid.RowDefinitions>
                                    <HyperlinkButton HorizontalContentAlignment="Left" Grid.Row="0" FontWeight="Bold" Foreground="#0072bc" FontSize="10"  VerticalContentAlignment="Center" Content="{Binding Event}"  NavigateUri="{Binding Url}"></HyperlinkButton>
                                    <TextBlock Text="{Binding Time}" VerticalAlignment="Center" Foreground="#0072bc"  Grid.Row="1" FontSize="9" TextWrapping="Wrap" Margin="3,3,3,3"></TextBlock>
                                </Grid>      
                        </DataTemplate>
                    </data:DataGridTemplateColumn.CellTemplate>
                </data:DataGridTemplateColumn>
            </data:DataGrid.Columns>
        </data:DataGrid>
       </Border>

在项目中添加Event实体类,用作Datagrid数据绑定

class EventEntity
    {
        public string Time { get; set; }
        public string Event { get; set; }
        public string Url { get; set; }
    }

在mainpage.xaml.cs中添加显示数据的代码:

null;
        private string targetListName = null;
        private ListItemCollection targetEventItems = null;

        public MainPage(string siteUrl,string listName)
        {
            InitializeComponent();
            this.targetListName = listName;
            string currentPageURL = siteUrl;
            string viewXML = @"<View><ViewFields>
                            <FieldRef Name='LinkTitle' />
                            <FieldRef Name='Time_x0020_Span' />
                            <FieldRef Name='Original_x0020_Link'/></ViewFields></View>";
            clientProxy = new ClientOMProxy(currentPageURL);
            clientProxy.successEventHandler += new ClientRequestSucceededEventHandler(OnRequestSucceeded);
            clientProxy.failEventHandler += new ClientRequestFailedEventHandler(OnRequestFailed);
            clientProxy.GetListItemsAsync(listName, viewXML, out targetEventItems);
        }

        private void OnRequestSucceeded(Object sender, ClientRequestSucceededEventArgs args)
        {
            Dispatcher.BeginInvoke(BindData);
            clientProxy.Dispose();
        }

        private void OnRequestFailed(Object sender, ClientRequestFailedEventArgs args)
        {
            clientProxy.Dispose();
        }

        private string CutDateTime(string timespan)
        {
            string[] dateArray = timespan.Split(new string[]{"~"}, StringSplitOptions.RemoveEmptyEntries);
            string result = String.Empty;
            DateTime startTime = Convert.ToDateTime(dateArray[0]);
            result += startTime.ToString(@"MM\/dd\/yyyy HH:mm");
            result += " ~ ";
            DateTime endTime = Convert.ToDateTime(dateArray[1]);
            result += endTime.ToString(@"MM\/dd\/yyyy HH:mm");
            return result;
        }

        private void BindData()
        {
            EventEntity aecEvent = null;
            IList<EventEntity> eventsList = new List<EventEntity>();
            foreach (ListItem item in targetEventItems)
            {
                aecEvent = new EventEntity();
                aecEvent.Event = item["Title"].ToString();
                aecEvent.Time = CutDateTime(item["Time_x0020_Span"].ToString());
                aecEvent.Url = item["Original_x0020_Link"].ToString() + "&Source=" + HtmlPage.Document.DocumentUri.ToString();
                eventsList.Add(aecEvent);
            }
            this.eventGrid.ItemsSource = eventsList;
        }

 

同时修改App.xaml.cs中Application_Startup的方法,确保从外部获得设置的参数

object sender, StartupEventArgs e)
        {
            string siteUrl = e.InitParams["SiteUrl"];
            siteUrl = System.Windows.Browser.HttpUtility.UrlDecode(siteUrl); 
            string listName = e.InitParams["SourceListName"];
            listName = System.Windows.Browser.HttpUtility.UrlDecode(listName); 
            this.RootVisual = new MainPage(siteUrl, listName);
        }

编译后,上传到SharePoint site上,然后添加silverlight web part,设置xap的url地址,同时设置外部参数,添加参数如下SiteUrl = ”your site”, SourceListName="your list name” 保存后,silverlight就可以正常显示,界面如下

[SharePoint 2010]一个完整的Silverlight显示List数据的例子

实现起来方便又不失美观。

 

欢迎大家讨论指正……

相关文章:

  • 2022-12-23
  • 2021-07-19
  • 2022-12-23
  • 2021-10-07
  • 2021-08-16
  • 2022-12-23
  • 2022-01-10
  • 2021-06-09
猜你喜欢
  • 2022-02-25
  • 2021-06-18
  • 2021-11-09
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
相关资源
相似解决方案