December 13

Create Silverlight Graphs to use SharePoint 2010 Data

When finished, you will have a Silverlight Pie chat that will be using a SharePoint Tasks list and group by Status like this:

PieChart

Prepare SharePoint to use Silverlight:
Need to put the following two files in the root of your SharePoint Web Application:

ClientAccessPolicy.xml

<?xml version="1.0" encoding="utf-8"?>
<access-policy>
	<cross-domain-access>
		<policy>
			<allow-from http-request-headers="*">
				<domain uri="*"/>
			</allow-from>
			<grant-to>
				<resource path="/" include-subpaths="true"/>
			</grant-to>
		</policy>
	</cross-domain-access>
</access-policy>

CrossDomain.xml

<?xml version="1.0"?>
<cross-domain-policy>
	<allow-http-request-headers-from domain="*" headers="*"/>
</cross-domain-policy>

Create Silverlight in Visual Studio 2010:

  1. Open Visual Studio 2010 Select New Project…
  2. At top select .NET Framework 3.5 and Silverlight
  3. In Visual C# section Select Silverlight-> Silverlight Application
  4. Type in name of project. We will create a Pie chart first, so we will use Silverlight.PieCharts and press
  5. In New Silverlight Application Window, make sure Host the Silverlight application in new Web site is checked.
  6. Add SharePoint Silverlight client object model references
    1. In Solution Explorer, right-click the Silverlight.PieCharts node, and then click Add References.
    2. Click Browse tab.
    3. Navigate to the following folder: C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\TEMPLATE\LAYOUTS\ClientBin.
    4. Select Microsoft.SharePoint.ClientSilverlight.dll and Microsoft.SharePoint.Client.Silverlight.Runtime.dll
    5. Click OK
  7. Add Silverlight Charting object model references
    1. In Solution Explorer, right-click the Silverlight.PieCharts node, and then click Add References.
    2. Click .NET tab.
    3. Select System.Windows.Controls.DataVisualization.Toolkit
    4. Click OK
  8. Add References & Parameters passing to Silverlight
    1. Right-Click on App.xml
    2. Select View Code
    3. Add following using statements to top of page
      using Microsoft.SharePoint.Client;
      using System.Threading;
      
    4. Find Application_Startup
    5. Change from:
      private void Application_Startup(object sender, StartupEventArgs e)
      {
         this.RootVisual = new MainPage();
      }
      

      to:

      private void Application_Startup(object sender, StartupEventArgs e)
      {
          ApplicationContext.Init(e.InitParams, SynchronizationContext.Current);
          this.RootVisual = new MainPage(e.InitParams);
      }
      

    6. Right-Click on MainPage.xml
    7. Select View Code
    8. Add following using statements to top of page
      using Microsoft.SharePoint.Client;
      
    9. Find MainPage
    10. Change from:
      public MainPage()
      {
          InitializeComponent();
      }
      

      to:

      //Parameters
      private string _webFullURL = @"http://s22102:83//"; //url to your sharepoint site
      private string _Title = "Pie Chart";
      private string _ListName = "Tasks"; //name of list on SharePoint Site
      //internal
      private ListItemCollection _listTasks;
      
      public MainPage(IDictionary<string, string> Parameters)
      {
      	InitializeComponent();
      
      	#region Parameters
      	if (Parameters.ContainsKey("WebURL"))
      	{
      		_webFullURL = Parameters["WebURL"].Replace("%20", " ").Replace("%28", "(").Replace("%29", ")");
      	}
      
      	if (Parameters.ContainsKey("Title"))
      	{
      		_Title = Parameters["Title"].Replace("%20", " ").Replace("%28", "(").Replace("%29", ")");
      	}
      	pieChart.Title = _Title;
      
      	if (Parameters.ContainsKey("ListName"))
      	{
      		_ListName = Parameters["ListName"].Replace("%20", " ").Replace("%28", "(").Replace("%29", ")");
      	}
      	#endregion
      	
      	 GetData();
      }
      
  9. Add Pie Chart container
    1. Open MainPage.asml
    2. Add reference to chart control
      1. in UserControl above d:DesignHeight= add following:
        xmlns:chartingToolkit="clr-namespace:System.Windows.Controls.DataVisualization.Charting;assembly=System.Windows.Controls.DataVisualization.Toolkit"
        
      2. Add following inside grid section
        <chartingToolkit:Chart x:Name="pieChart" Width="350" Height="250" Title="PieChart" BorderThickness="0" Background="White" VerticalAlignment="Top" HorizontalAlignment="Center">
        	<chartingToolkit:Chart.Series>
        		<chartingToolkit:PieSeries ItemsSource="{Binding}" 
        		DependentValuePath="Value"  
        		IndependentValuePath="Key"
        		AnimationSequence="FirstToLast"   
        		Title="Status" 
        		IsSelectionEnabled="True"
        	/>
        	</chartingToolkit:Chart.Series>
        </chartingToolkit:Chart>
        
  10. Add data to chart
    1. Add following two classes above MainPage class in MainPage.asml.cs:
      public class SLGridData
      {
      	public string Key { get; set; }
      	public int Value { get; set; }
      }
      
      public class SPTasks
      {
      	public string Title { get; set; }
      	public DateTime StartDate { get; set; }
      	public DateTime DueDate { get; set; }
      	public string AssignedTo { get; set; }
      	public string Status { get; set; }
      	public double PercentComplete { get; set; }
      	public string Priority { get; set; }
      }
      
    2. Now add folowing data functions after public MainPage(IDictionary<string, string> Parameters):
      GetData():
      private void GetData()
      {
      	ClientContext spContext = null;
      	if (ApplicationContext.Current.Url != null)
      	{
      		spContext = new ClientContext(ApplicationContext.Current.Url);
      	}
      	if (spContext == null)
      	{
      		spContext = new ClientContext(_webFullURL);
      		spContext.Load(spContext.Web);
      	}
      	List ProjectBooks = spContext.Web.Lists.GetByTitle(_ListName);
      	spContext.Load(ProjectBooks);
      
      	CamlQuery query = new Microsoft.SharePoint.Client.CamlQuery();
      	string camlQueryXml =
      		"<View>" +
      			"<Query>" +
      			"</Query>" +
      					"<Where>" +
      					"</Where>" +
      			"<ViewFields>" +
      				"<FieldRef Name='Title' />" +
      				"<FieldRef Name='StartDate' />" +
      				"<FieldRef Name='DueDate' />" +
      				"<FieldRef Name='AssignedTo' />" +
      				"<FieldRef Name='Status' />" +
      				"<FieldRef Name='PercentComplete' />" +
      				"<FieldRef Name='Priority' />" +
      			"</ViewFields>" +
      		"</View>";
      
      	query.ViewXml = camlQueryXml;
      	_listTasks = ProjectBooks.GetItems(query);
      	spContext.Load(_listTasks);
      	spContext.ExecuteQueryAsync(new ClientRequestSucceededEventHandler(OnRequestSucceeded), new ClientRequestFailedEventHandler(OnSiteLoadFailure));
      }
      

      OnRequestSucceeded():

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

      OnSiteLoadFailure()

      private void OnSiteLoadFailure(Object sender, ClientRequestFailedEventArgs args)
      {
      	string msg = args.Exception.ToString();
      }
      

      BindData():

      private void BindData()
      {
      	List<SPTasks> tasks = new List<SPTasks>();
      
      	foreach (ListItem li in _listTasks)
      	{
      		tasks.Add(new SPTasks()
      		{
      			Title = Convert.ToString(li["Title"]),
      			StartDate = li["StartDate"] != null ? Convert.ToDateTime(li["StartDate"]) : DateTime.MinValue,
      			DueDate = li["DueDate"] != null ? Convert.ToDateTime(li["DueDate"]) : DateTime.MinValue,
      			AssignedTo = li["AssignedTo"] != null ? Convert.ToString(li["AssignedTo"]) : string.Empty,
      			Status = li["Status"] != null ? Convert.ToString(li["Status"]) : string.Empty,
      			PercentComplete = li["PercentComplete"] != null ? Convert.ToDouble(li["PercentComplete"]) : 0.0,
      			Priority = li["Priority"] != null ? Convert.ToString(li["Priority"]) : string.Empty
      		});
      	}
      
      
      	//Total by Status
      	var grouped = tasks.GroupBy(p => new { p.Status })
      				  .Select(p => new SLGridData()
      				  {
      					  Key = p.First().Status + " (" + p.Count() + ")",
      					  Value = p.Count(),
      				  });
      	List<SLGridData> listData = grouped.ToList();
      	//Bind to chart
      	BindChart(listData);
      	//Set Title
      	pieChart.LegendTitle = _Title;
      }
      

      BindChart()

      private void BindChart(List<SLGridData> gridData)
      {
      	List<KeyValuePair<string, int>> valueList = new List<KeyValuePair<string, int>>();
      
      	foreach (SLGridData pb in gridData)
      	{
      		valueList.Add(new KeyValuePair<string, int>(pb.Key, pb.Value));
      	}
      
      	// Setting data for pie chart
      	pieChart.DataContext = valueList;
      
      	//Get Series
      }
      
    3. Press F5 to run
  11. Adding to SharePoint via Webpart
    1. Copy Silverlight.PieCharts\Silverlight.PieCharts\Bin\Debug\Silverlight.PieCharts.xap to C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\TEMPLATE\LAYOUTS\ClientBin
    2. Create a Visual WebPart project in the same solution called Silverlight.WebPart
    3. Copy contents (items between tags) of Silverlight.PieCharts.Web -> Silverlight.PieChartsTestPage.aspx into VisualWebPart1UserControl.ascx desinger page
    4. Change object section to this
      <object data="data:application/x-silverlight-2," type="application/x-silverlight-2" width="100%" height="100%">
      	<param name="source" value="_layouts/ClientBin/Silverlight.PieCharts.xap"/>
      	<param name="onError" value="onSilverlightError" />
      	<param name="background" value="white" />
      	<param name="minRuntimeVersion" value="5.0.61118.0" />
      	<param name="autoUpgrade" value="true" />
      	<param name="initParams" value="WebURL=<%=WebUrl %>,ListName=<%=ListName %>,Title=Total Projects By Status"/>
      	<a href="http://go.microsoft.com/fwlink/?LinkID=149156&v=5.0.61118.0" style="text-decoration:none">
      	  <img src="http://go.microsoft.com/fwlink/?LinkId=161376" alt="Get Microsoft Silverlight" style="border-style:none"/>
      	</a>
      </object>
      
    5. Edit VisualWebPart1UserControl.ascx page
    6. Add following public objects before Page_Load
      public string ListName = "Tasks";
      public string WebUrl = "http://s22102:83/";
      

      NOTE: You can create webpart parameters to this webpart and allow users to change the WebUrl and ListName

    7. Build and deploy to SharePoint
    8. Add your webpart to a page and see your chart!!


    References:

September 11

SharePoint 2010 batch files to install DLLs into the GAC

Instead of manually coping over DLLs into the GAC you can use following bat files:

1.CopyDLLsToHere.bat

copy ..\..\bin\Debug\*.dll .

2.Install_DLLs_Application_into_GAC

@echo off
call GAC_DLLs DLLName

iisreset

GAC_DLLs.bat

ECHO OFF
ECHO Adding %1 to GAC
Set CurrentFolder=%~dp0%
call  "%VS100COMNTOOLS%..\..\VC\vcvarsall.bat" x86
cd %currentFolder%

GACUTIL -if %1.dll

Steps to use:

  • Compile project to product DLL
  •  1.CopyDLLsToHere.bat
  •  2.Install_DLLs_Application_into_GAC
September 11

SharePoint 2010 PowerShell scripts to install Web Parts and Features

For development you can use Visual Studio 2010  features (right click deploy) to install web parts and features, but once you get into testing/staging and production enviornemnts you can use the following script

Web Parts

POWERSHELL-SharePoint-WebPart.ps1

Add-PsSnapin Microsoft.SharePoint.PowerShell

Write-Host "Initializing parameters"
$featureAction=$args[3]
$CurrentDir=$args[0]
$solutionName=$args[1] + ".wsp"
$webpartName=$args[1]
$SolutionPath=$CurrentDir + "\" + $solutionName
$logfile=$CurrentDir + "\" + $webpartName + "_" + $featureAction + ".log"
$urlPath=$args[2]
$installToURL=$args[4]

if (( $urlPath -eq $null) -or ( $installToURL -eq $null ))
{
    $installToURL="No"
}

Write-Host "Logfile: " $logfile " Starting...."
Start-Transcript $logfile

if ( $featureAction -eq "Remove")
{
    Write-Host "Rretracting and uninstalling solution:" $solutionName
    Uninstall-SPSolution -Identity $solutionName  -allwebapplications -Confirm:$false

    Write-Host "Waiting till retaction has finished " -nonewline
    do
    {
        Start-Sleep 2
        Write-Host "." -nonewline
    }
    while ((Get-SPSolution $solutionName).Deployed)

    Start-Sleep 5
    Write-Host "." -nonewline

    Write-Host "Removing solution:" $solutionName " "
    Remove-SPSolution -Identity $solutionName -Confirm:$false

    Write-Host $solutionName " Now Removed!"

}

if ( $featureAction -eq "Install")
{

    Write-Host "Adding solution:" $solutionName " "
    Add-SPSolution $SolutionPath 

    if ( $installToURL -ne "Yes" )
    {
        Write-Host "Deploying solution:" $solutionName "to GAC "
        Install-SPSolution -Identity $solutionName  -AllWebApplications -GACDeployment -CASPolicies -Confirm:$false
    }
    else
    {
        Write-Host "Deploying solution:" $solutionName "to" $urlPath "and GAC "
        Install-SPSolution -Identity $solutionName -WebApplication $urlPath -GACDeployment -Confirm:$false
    }

    Write-Host "Waiting till deployment has finished " -nonewline
    do
    {
        Start-Sleep 2
        Write-Host "." -nonewline
    }
    while ((Get-SPSolution $solutionName).Deployed)

    Start-Sleep 5
    Write-Host "." -nonewline

    Write-Host $solutionName " Now installed!"

}

if ( $featureAction -eq "Update")
{
    Write-Host "Updating solution:" $solutionName " "
    Update-SPSolution -Identity $solutionName -LiteralPath $SolutionPath -GACDeployment -Confirm:$false
    Write-Host $solutionName " Now updated!"
}

Write-Host "" 

Stop-Transcript

Remove-PsSnapin Microsoft.SharePoint.PowerShell
To use POWERSHELL-SharePoint-WebPart.ps1, create dos bat file called
mywebpart-install.bat
@echo off
REM                                                    Current               Site Collection
REM               Script to install webpart            Dir    webpart Name   to Install to       Action (Install, Update, Remove)
REM              ----------------------------------    ------ -------------- ------------------- ------------
powershell -file ".\POWERSHELL-SharePoint-WebPart.ps1" "%CD%" "mywebpart" "http://stage.company.com" "Install"

FEATURES

POWERSHELL-SharePoint-Feature.ps1

Add-PsSnapin Microsoft.SharePoint.PowerShell

Write-Host 'Will initialize parameters'
$CurrentDir=$args[0]
$solutionName=$args[1] + ".wsp"
$featureName=$args[1]
$SolutionPath=$CurrentDir + "\" + $solutionName
$urlPath=$args[2]
$action=$args[3]

$logfile=$CurrentDir + "\" + $args[1] + "_" + $action + ".log"

Write-Host "Logfile: " + $logfile + " Starting...."
Start-Transcript $logfile

$errorActionPreference = 'Inquire'
if ( $action -eq "Remove" )
{
	Write-Host $action ' ' $featureName '....'

	Write-Host 'Will now disable feature, ' $featureName ' for all site in Site Collection in ' $urlPath

	# Get Feature object
	$feature = Get-SPFeature $featureName

	#Get web application
	$webApp = Get-SPWebApplication -Identity $urlPath

	#Deactivate site scoped feature for all site collections in a Web Application (checks to see if the feature is activated before attempting to deactivate)
	Write-Host 'Will now deactivate solution:' $solutionName
	$webApp | Get-SPSite -limit all | ForEach-Object {
    	Write-Host '...Checking Site ' $_.Url ' for ' $solutionName
        if ($_.Features[$feature.ID]) {
            Write-Host '... ...deactiviatng feature ' $solutionName ' from ' $_.Url
            Disable-SPFeature $feature -Url $_.Url -Force -Confirm:$false
		}
	}

    $solution = Get-SPSolution | where-object {$_.Name -eq $solutionName}

	Write-Host 'Will now retract solution:' $solutionName
	Uninstall-SPSolution -Identity $solutionName -Confirm:$false

	#Wait for solution to be uninstalled
    while ($solution.Deployed -eq $true)
    {
        Write-Host '.'  -nonewline
		Start-Sleep -s 1
    }
    #make sure job is finished
    while ( $solution.JobExists )
    {
        write-host '.'  -nonewline
        sleep 1
    }
	write-host ''
	Write-Host 'Will now remove solution:' $solutionName
	Remove-SPSolution -Identity $solutionName -force -Confirm:$false
}

if ( $action -eq "Install")
{

	Write-Host 'Will now add solution:' $solutionName
	Add-SPSolution -LiteralPath $SolutionPath 

	Write-Host 'Will now deploy solution:' $solutionName
	Install-SPSolution -Identity $solutionName -GACDeployment  -force

    $solution = Get-SPSolution | where-object {$_.Name -eq $solutionName}

    while ( $solution.JobExists )
    {
        write-host '.'  -nonewline
        sleep 1
    }
	write-host ''
    write-host 'Solution, ' $solutionName ', ' $action '!'

}

if ( $action -eq "Update")
{
	Write-Host 'Will now update solution:' $solutionName
	Update-SPSolution -Identity $solutionName -LiteralPath $SolutionPath -GACDeployment  -force

    $solution = Get-SPSolution | where-object {$_.Name -eq $solutionName}

    while ( $solution.JobExists )
    {
        write-host '.'  -nonewline
        sleep 1
    }
	write-host ''
    write-host 'Solution, ' $solutionName ', ' $action '!'
}

#place bland line to fix log format
write-host ' '

#Stop Log
Stop-Transcript

#fix output file so it has newlines in notepad
[string]::Join("`r`n",(Get-Content $logfile)) | Out-File $logfile

Remove-PsSnapin Microsoft.SharePoint.PowerShell

To use POWERSHELL-SharePoint-Feature.ps1, create dos bat file called
myFeature-install.bat

@echo off
REM                                                    Current               Site Collection
REM               Script to install feature            Dir    feature Name   to Install to       Action (Install, Update, Remove)
REM              ----------------------------------    ------ -------------- ------------------- ------------
powershell -file ".\POWERSHELL-SharePoint-WebPart.ps1" "%CD%" "myfeature" "http://stage.company.com" "Install"
April 30

Programmatically change theme of newly created site

Add Event Reciever for WebProvisioned:

Right Click on Project->Add-.New Item…->Event Reciever and lets call it WebProvisionedEvent

Now select “A site was provisioned”

Change WebProvisioned method to this

public override void WebProvisioned(SPWebEventProperties properties)
{
   //newly created site
   SPWeb childSite = properties.Web;
   //Get Parent
   SPWeb topSite = childSite.ParentWeb;
   //Set themes to same as parent
   childSite.MasterUrl = topSite.MasterUrl;
   childSite.CustomMasterUrl = topSite.CustomMasterUrl;
   childSite.AlternateCssUrl = topSite.AlternateCssUrl;
   childSite.SiteLogoUrl = topSite.SiteLogoUrl;

   //Set child site to use Parent's Navigation in Top Nav
   childSite.Navigation.UseShared = true;

   //Update
   childSite.Update();

   base.WebProvisioned(properties);

}