Social Icons

twitter google plus linkedin rss feed

Pages

8.9.11

Filter Provider Web Part with a Silverlight Tree in a ModalDialog window

I started with this a couple of days ago… I didn’t want to do it, because I knew it was going to be painful… But they made me… An then I thought it would be a perfect post for the blog because of the painful.
What we wanted to achieve was to filter the items in a List View Web Part by Entity. We have an entity hierarchy, so we thought it would be a good idea to have a web part showing the hierarchy as a tree.

Alright so we need web part with a TreeView that is able to send the selected entity as a filter to a LVWP. Great. I built it… And no-one liked it. They wanted it to be Silverlight, and not only that, they wanted it to be in a pop up window. Yes, they got me. I have never done anything like that. But hey, where’s your spirit of adventure?

It is a lot of code, most of it ugly. So I’ll only post the most tricky parts (basically the parts related to the communication of the pages and the Silverlight) and the URL’s from where I got the ideas.

The firs thing is to get a proper Filter Provider Web Part working. To do so, I followed the instructions from here. My first try was with IWebPartRow, but it wasn’t what I was looking for, so I went for ITransformableFilterValues. It’s pretty straightforward so I won’t comment anything here.
The second thing is to create the PopUp Window. After googling a while I found this post a good point to start. My code in the web part ended like this:
        protected override void OnLoad(EventArgs e)
        {
            if (Page.IsPostBack)
            {
                if (!string.IsNullOrEmpty(GetFormValue("HiddenEntityName")))
                {
                    Page.Session["SelectedEntityName"] = Page.Request.Form["HiddenEntityName"];
                    Page.Session["SelectedEntityID"] = Page.Request.Form["HiddenEntityID"];

                    RenderHeader();

                    //SelectedEntityText.Text = string.Format("{0}  ", Page.Request.Form["HiddenEntityName"], Page.Request.Form["HiddenEntityID"]);
                }
                else
                    RenderHeader();
            }

            string CurrentWeb = SPContext.Current.Web.Url;
            string height = "500";
            string width = "500";
            string page = "/_layouts/stratex/EntityTree.aspx";

            // use next line for direct with  between  and  
            string scrp = @"
                            ";

            Type t = this.GetType();
            if (!Page.ClientScript.IsClientScriptBlockRegistered(t, "bindWebserviceToAutocomplete"))
                Page.ClientScript.RegisterClientScriptBlock(t, "bindWebserviceToAutocomplete", scrp);
        }

I had problems retrieving the values from the ModalDialog. I was not able to find the controls in the web part because the IDs and the Titles of the were being dynamically. The trick I used to fix this was to create two hidden fields in the CreateChildControls:
        protected override void CreateChildControls()
        {
            base.CreateChildControls();

            ...

            Page.ClientScript.RegisterHiddenField("HiddenEntityName", "");
            Page.ClientScript.RegisterHiddenField("HiddenEntityID", "");

            ...
        }

Hey Chan, have you noticed that you could use the session and forget about the HiddenFields? Don’t ask. I’m warning you…

The next part is to get the new aspx page for the modal dialog. I created a new directory in the layouts folder and created my page there. It looks like this:
<%@ Page Language="C#" Inherits="StratExFramework.EntityTree,StratExFramework,Version=2.2.0.0,Culture=neutral,PublicKeyToken=311246df7412ca98" %>

<html>
<head>
<title>Select Entity for filtering</title>
<script type='text/javascript'>
    function PassParameterAndClose(EntityName, EntityID) {

        window.returnValue = new Array( EntityName, EntityID) ;

        var version = parseFloat(navigator.appVersion.split('MSIE')[1]);
        if (version >= 7) 
            { window.open('', '_parent', ''); }
        else
            { window.opener = self; }

        window.close();
    }
</script>
</head>
<body></body>
</html>

I have also created a code behind class as you can see in the first line of the aspx… :
    public class EntityTree : WebPartPage
    {
        string CurrentWeb;
        string SelectedEntityID;

        protected void Page_Load(object sender, System.EventArgs e)
        {
            CurrentWeb = Request.Params["CurrentWeb"];
            SelectedEntityID = Request.Params["SelectedEntityID"];
        }

        protected override void CreateChildControls()
        {
            base.CreateChildControls();

            string Source = CurrentWeb + "/Lists/XAPLibrary/SilverlightEntityTreeSelector.xap";
            string SilverlightHeight = "515";
            string SilverlightWidth = "500";

            LiteralControl obj = new LiteralControl();
            obj.Text = "<object id='silverlightHost' style='height: " + SilverlightHeight + "; width: " + SilverlightWidth + @"; margin: 0; padding: 0;' data='data:application/x-silverlight-2,' type='application/x-silverlight-2'>
                            <param name='Source' value='" + Source + @"' />
                            <param name='MinRuntimeVersion' value='3.0.40624.0' />
                            <param name='Background' value='#FFFFFFFF' />
                            <param name='initParams' value='" +
                                string.Format("{0}={1}", "site", HttpUtility.UrlEncode(CurrentWeb)) +
                                string.Format(", {0}={1}", "selectedentityid", HttpUtility.UrlEncode(SelectedEntityID)) +
                                @"' />
                            </object>";
            this.Controls.Add(obj);
        }

        public override void VerifyRenderingInServerForm(Control control)
        {
            return;
        }
    }

What I am doing here is getting the parameters and passing them to the Silverlight. I use the CurrentWeb to tell the web services I use in the Silverlight what’s the context and the SelectedEntityID to highlight the previously selected Entity in case it’s not null. This is the code of the Silverlight:
namespace SilverlightEntityTreeSelector
{
    public partial class MainPage : UserControl
    {
        public MainPage()
        {
            InitializeComponent();

            Tree.PropertyChanged += new System.ComponentModel.PropertyChangedEventHandler(Tree_PropertyChanged);

            Tree.Show(string.Empty);
        }

        void Tree_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
        {
            if (e.PropertyName == "SelectedEntityID")
                HtmlPage.Window.Invoke("PassParameterAndClose", Tree.SelectedEntityName, Tree.SelectedEntityID);
            else if (e.PropertyName == "TreeLoaded")
                if (Application.Current.Resources.Contains("selectedentityid"))
                    if (!string.IsNullOrEmpty(Application.Current.Resources["selectedentityid"] as string))
                        Tree.ChangeSelectedItemTo(Application.Current.Resources["selectedentityid"] as string);
        }
    }
}

Now we have all the components.

The way it works is: You chose an entity in the Silverlight tree, then the Silverlight calls the javascript function in the modal window that returns the parameters to the parent web part window and closes the ModalDialog. And then the web part sends the filter to the List View Web Part.


If you try to use this code you’ll be missing some methods, but what I wanted to share here is the solution I've used mainly because I don’t want to think about this again if I’m asked to do something similar in the future.



I would love to share some pics but the web parts haven’t been retouched by the skilled hand of Adam, our designer, and your eyes could pop out of their sockets.

18.8.11

Creating a Windows Forms application for SharePoint 2010

In my usual style, I think I have stumbled upon each and every possible problem before I could execute my application.

What with MOSS2007 it was bliss and cheerful laughter has become in SharePoint 2010 a task that took me at least an hour… And I was lucky because in my usual style again I am really late to 2010 and most of the problems have been solved and talked about in forums…

Well, I’ll write here my experience, so I wont forget the necessary steps next time hopefully.


I added the Microsoft.SharePoint.dll as usual to the references and started coding. I wrote my 3 lines application (I just wanted a tool to help me code) and hit F5.

“The type or namespace name 'SharePoint' does not exist in the namespace 'Microsoft' (are you missing an assembly reference?)”

Well, I was not missing anything, the problem was that you have to target the solution to the .Net Framework 3.5…

image

That was easy. There are a couple of places where you can find that. OK, F5 again.

“The Web application at http://localhost could not be found. Verify that you have typed the URL correctly. If the URL should be serving existing content, the system administrator may need to add a new request URL mapping to the intended application”


- Oh come on! It’s there! Why can’t you find it? + Because you haven’t targeted me to 64 bits and I am not running natively. - Oops, sorry for that. + It’s OK, you just have to read my error codes, they really point you in the right direction.

image

This one was a bit trickier. But after changing that I happily clicked F5 again and… Surprise!

“The Web application at http://localhost could not be found. Verify that you have typed the URL correctly. If the URL should be serving existing content, the system administrator may need to add a new request URL mapping to the intended application”


Yep, same error again… And I couldn’t find more info on the internet… What if it’s a permission problem?
image

Finally I started the Visual Studio as an administrator and it worked. Finally!

5.8.11

Hiding the Scrollbars in the SharePoint 2010 Web Parts

After deploying the first alpha version of our solution in SharePoint 2010 I realized that my Silverlight web parts were showing ugly scrollbars. I noticed that if I change the height and width to auto they will disappear… but then my web part will not have the right size…
I read this post: http://blog.benfox.info/?p=11 and, as you could have guessed, I went for the inelegant approach.
Then I found that the javascript code was in a picture… how inconvenient… and then I thought “I’ll show everyone that I can be as dull in SharePoint 2010 as I have always been in SharePoint 2007” Why not creating a post about that?
<script type="text/javascript">

 function HideScrollBars()
 {
 document.getElementById('WebPartWPQ2').style.overflowX = "hidden";
 document.getElementById('WebPartWPQ2').style.overflowY = "hidden";

 document.getElementById('WebPartWPQ3').style.overflowX = "hidden";
 document.getElementById('WebPartWPQ3').style.overflowY = "hidden";
 }

_spBodyOnLoadFunctionNames.push("HideScrollBars")</script>
And after struggling with the new Content Editor Web Part for at least 15 minutes I finally managed to hide the vertical and the horizontal scrollbars in my web parts.
Now I can proudly send a picture of the site in the SharePoint 2010 view.

--- Update --- I have changed the web part code so we don't need to use this crappy javascript code.

25.7.11

Cloning a SharePoint Virtual Machine And Changing its Name in the process

The first problem I found was that after copying the virtual machine is that I couldn’t add it to my a new VM because the UUID in the VHD was the same as in the previous VM… I did this:

VBoxManage.exe internalcommands sethduuid g:\StratexPoint\StratexPointBigger.vhd

And then it worked. But now we have the tricky part. We have to change the name of the SharePoint WFE.

After we change the name of the server we try to connect to the central administration, but we get “Cannot connect to the configuration database.” so we ran the SharePoint Products and Technologies Configuration Wizard.

It complains that it can’t detect whether we are connected to a farm or not… OK. Then it disconnects the server from the farm and closes.

I must insist, my dear. I run the wizard again and select create a new farm. It tries to connect to the database server that happens to be the same server we have just changed the name…

SQL is not so delicate about names and it works.

Now we have to create a new Config_Database, ok, ok, and it looks like it’s going to work… but nooo.

System.Security.Principal.IdentityNotMappedException: Some or all identity references could not be translated.

After checking this post I changed the username of the identity of the SharePoint Central Administration V3 application and it worked .. but failed after a while, so I deleted the site, the directory and the application pool and tried again.

 

And It worked!


After that I started the services, created an 80 web application and attached the old content database to it.

 

Who said it was impossible?

11.7.11

HTTP 500 (No authority could be contacted for authentication.) in SharePoint

I was getting an HTTP error 500 after restoring my SharePoint development server in a different network (at home). The thing was a bit curious because I could see the SharePoint site from the virtual server, but not from my physical server and yes, I checked the IPs and they were OK. The first thing I did was to configure the IE9 to show me the HTTP errors the way I like them, the “unfriendly” way.

To do so I went to Tools –> Internet Options –> Advanced, and there in the tree below Browsing I unchecked the “Show friendly HTTP error messages”.

After that I could see that the problem I was having when connecting from outside was “No authority could be contacted for authentication.” Here I saw that the easiest way to fix the problem was to remove the server from the domain and then add it again.

And it worked... Finally…

8.7.11

Hiding List View web parts when they are empty

Today I have been required to hide the List View web parts of the solution when they are empty… Even though I don’t like javascript, it was the obvious way to go so I asked Google and it sent me to this post.

I copied the code to a Content Editor Web Part and it worked more or less, but when I tried to hide the column headers and adding a message instead it was only working for two of my the three listview web parts in the page… After a bit more of googling I changed it to:

<script type="text/javascript">
 function HideEmptyWebParts()
 {
   var itemsfound = new Array;
   var elements = document.getElementsByTagName('*');
   for(var i=0;i<elements.length;i++)
   {
      if(elements[i].className == 'ms-vb')
      {
         itemsfound.push(elements[i]);
      }
   }
  
   for (var i=0;i<itemsfound.length;i++)
   {
       if (itemsfound[i].innerHTML.indexOf("There are no items to show in this view of the")>-1)
       {
                itemsfound[i].parentNode.parentNode.parentNode.parentNode.innerHTML="<div class='ms-vb'>Not enough data to produce a dashboard.</div>";
         
       }
   }
 }

_spBodyOnLoadFunctionNames.push("HideEmptyWebParts")
 
</script>

And after that it worked as expected.

1.7.11

Debugging applications in the Phone after updating to “Mango”

I have just updated my phone to Windows Phone 7.1 codename “Mango”. I can’t say much about it because I haven’t had the time to test it properly, by now I’ll just say it’s faster.

 

Some of the features are not yet implemented and they have a “Coming soon!” but that’s not what I want to say here today.

 

After the upgrade I couldn’t debug my applications on my phone as before. The emulator was being launched (and this was causing all my vBox Virtual Machines to crash!)

 

After a while looking around I realised that it was easier than I thought… There’s a dropdown list up there for you to select how you want to debug:

image

You just have to chose Windows Phone Device and in my case unlock again the phone with the Developer Phone Registration tool and you are ready to go!

24.5.11

Microsoft Case Study for StratexSystems’ SharePoint based Risk Management Solution

I am really happy to see how StratexPoint has helped HML to improve their risk management and reduce their operational losses.
We have worked a lot on the solution this last year and it’s very fulfilling for me to see that our job has an actual effect on the Real World™. Most of the time I forget it...

22.4.11

Stratex Systems is On The Cloud

I have just received the link to join the Office 365 beta program… Sadly (again) I don’t have the time to test it properly today, but I will on Tuesday hopefully.

I’ll keep you posted.

 

image

 

A lot of licenses to assign, a lot of software to try…

21.4.11

Debugging Windows Phone 7 applications

Finally I managed to upload and debug my application in my phone, but it wasn’t that easy…
First of all I found the instructions in this page http://msdn.microsoft.com/en-us/library/ff941089(v=vs.92).aspx#BKMK_Register
 
There, it says that you have to register in the App Hub before you are able to do anything with your phone (and it costs USD100…) the textual words are:

“You should register for membership as a Windows Phone developer before you begin creating applications because some development tasks, such as installing your application on a physical phone for testing, require App Hub membership”

Well this means you have to pay $100 only to be able to test the application… Pay before, decide later. I can’t say I like the philosophy.
 
Well, in the end my boss registered to the APP HUB with his personal Live ID. Huge mistake. We knew we could add up to three development phones, but no one told us that all of them should be linked to the same Live ID…  We thought you would be able to invite your developers to the App Hub or something like that, but no. And there’s no turning back, you can’t link your subscription to a different Live ID once you are registered… Not happy with this one either. Want to know how we solve it? With a great dose of trustfulness on his side.
 
Once you have your Live ID registered to the App Hub everything is easier…
 
I got to unlock and register the phone using  the Developer Phone Registration tool http://msdn.microsoft.com/en-us/library/ff769508(VS.92).aspx… Cool… Now what?
Well, now you have everything set up.
 
If you want to run your application in your phone anytime you want you have to deploy it with the “Application Deployment” tool as described in http://msdn.microsoft.com/en-us/library/gg588378(v=vs.92).aspx
 
Or if you prefer, you can hit F5 on your Visual Studio get the application running on my phone, and finally… Debug!

Creating a Expander Control for Silverlight for Windows Phone

I was migrating a solution to WP7 when I realized that there was not expander control available… I downloaded then the Silverlight  for Windows Phone Toolkit but realized that there wasn’t an expander there either.
 
I really couldn’t conceive a new version of the tool without expanders so I have created a rudimentary Expander for WP7. It's composed by a Grid, a StackPanel and a TextBlock.

It is very limited and of course it's not supposed to be a substitute of the good old Expander (it's focused to the specific problem I was trying to solve), but maybe it can help someone else out there.

The XAP code of the control is:
<Grid x:Name="LayoutRoot">
  <Border VerticalAlignment="Top" BorderBrush="#FF929EB0" BorderThickness="1" CornerRadius="2" Background="#FFE9E9E9" Margin="5,2">
            <Grid d:LayoutOverrides="Width">
    <Grid.RowDefinitions>
     <RowDefinition Height="Auto" MinHeight="20"/>
     <RowDefinition Height="Auto" MinHeight="5"/>
    </Grid.RowDefinitions>
    <TextBlock x:Name="Header" TextWrapping="Wrap" d:LayoutOverrides="Width" Foreground="#FF656565" Margin="15,2,0,0" VerticalAlignment="Top"/>
    <StackPanel x:Name="ChildrenPanel" VerticalAlignment="Top" d:LayoutOverrides="Width" Margin="0,2,0,0" Grid.Row="1"/>
   </Grid>
  </Border>
 </Grid>
The trick is adding a TextBlock in the header of the "expander" and subscribe to the MouseLeftButtonUp event of the TextBlock to control the folding and unfolding. I have also added a Folded property so I can externally set up the status of the expander.

If the expander is folded I add the items to the stack panel, if the expander is unfolded I remove the items. Sounds really simple, but I couldn't make it work. The StackPanel will remain the same size it was when it has all the items in it, but empty… without any Children… too ugly.

After a while trying to fake the behaviour changing the Height of the StakPanel I found the solution.

I was trying to delete all the items in the StackPanel at once with Children.Clear and that was driving it nuts. The solution was to remove the items inside the children one by one.

The code for the Expander class is here.
public partial class Expander : UserControl
 {
        bool _Folded;
        public bool Folded
        {
            get { return _Folded; }
            set
            {
                _Folded = !value;
                ExpanderSwitch();
            }
        }
        List ChildrenList;


  public Expander()
  {
   // Required to initialize variables
   InitializeComponent();

            ChildrenList = new List();

            Header.MouseLeftButtonUp += new System.Windows.Input.MouseButtonEventHandler(UserActivity_MouseLeftButtonUp);
  }

        void UserActivity_MouseLeftButtonUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            ExpanderSwitch();
        }

        private void ExpanderSwitch()
        {
            if (Folded)
            {
                foreach (var child in ChildrenList)
                    ChildrenPanel.Children.Add(child);
            }
            else
            {
                if (ChildrenList.Count == 0)
                    foreach (var item in ChildrenPanel.Children)
                        ChildrenList.Add(item);

                while (ChildrenPanel.Children.Count > 0)
                    ChildrenPanel.Children.RemoveAt(0);
            }

            _Folded = !_Folded;
        }
 }
And to use it you just have to add the control:
<Grid x:Name="LayoutRoot">
        <this:Expander x:Name="UserNews" />
    </Grid>
In code behind you can do something like this:
UserNews.Header.Text = GetHeader(News[0]);

            foreach (FrameworkNews news in News)
                UserNews.ChildrenPanel.Children.Add(new NewsDetail(news.Link, GetDetail(news), news.Where));

            UserNews.Folded = true;
If you have time you can add images and animations to the expander as well as a better "Folding Control"… Sadly I can't spend more time working on it, even though I'd love to :(

4.2.11

Ephemeral and Free Virtual Machines in CloudShare

This last week I've been looking for a way of hiring IaaS great! I've learnt a new acronym for torturing people and via twitter Luis Ruiz, a friend of mine, told me to try CloudShare. I was busy and I didn't listen to his advice at first... TOO BAD.

At CloudShare they offer you can create virtual environments for free. With the software and licenses for the same price.

They have a lot of basic virtual machine templates that will help you to have your virtual machine up & running in less than 10 minutes (including the registration time).


For a reasonable price of nothing at all they give you 3 CPUs, 120GB of HD and 6144MB of RAM plus the licenses and software for your machines.

If you decide to pay for a ProPlus account (49$) you can choose more complex templates like SharePoint 2010:

Yes it works here but not in Azure VM Role...

When you start your machine you'll have your URL available to access it, everything surprisingly easy. You can share your virtual machines with other CloudShare users and you can take snapshots and revert to them in case you break something...

The downside of this is that the virtual machines are suspended after 30 minutes of inactivity (and when you wake them up they have a different external IP), but even though it's a fantastic free environment for demoing and testing.

Use my advice and try it.

And you can't connect through VPN in the free version, just in case you were thinking in avoiding MegaVideo time limit...

1.2.11

Not SharePoint nor SQL Servers are working on the Azure VM Role

As you know, if you read me, I have been trying to be accepted in the Azure VM Role beta program, well, I have finally got a meeting with the guys that could grant me access and they've asked me the most feared question... What do you want it for?

My idea was to set up a farm in the cloud with SQL and SharePoint so I could use SSIS, our BI cube, Reporting services and SharePoint.

Well, this Microsoft guys say that "At the moment that's impossible"... Looks like there are connectivity problems between the machines in VM Role so not SharePoint nor SQL are working properly.

The advice they have for me is to set everything up on Office 365. But, what happens to my BI cube and my reporting services if I can't use web services from the Office 365's sandbox? Hmmm they won't work, so I'll just have half of my solution working and the other half sadly forgotten in the recesses of my hard disk.

The solution they provide... wait until summer.

I'll try to convince my boss to give me six months off, but if this doesn't work I am going to be forced to look for another place to set up my farm on.

Oh and, in case someone doubts it, I wasn't granted the access to the beta program.

And in the meantime Google is giving away laptops for the developers to test their new Chrome OS...

28.1.11

Uploading Machines to Azure VM Role

As all the technology we use at Stratex Systems is from Microsoft it looks simple logic to host our virtual machines in the Azure cloud... Beta!, now I'm scared. There's not too much information available about this at the moment, so I'll try to write about my experience.

The first thing I want to tell to anyone who is trying to test the VM Role is that you need to be accepted in the beta program. There are a lot of web pages including several from Microsoft that say that you'll only need to sing up and that's enough to start working, but it's not true.

If you don't know what's this all about, Azure VM Role is a new system to sell IaaS (Infrastructure as a Service) where you can upload your Hyper-V hard disks after installing all the software you need and they'll bring them to live. After that, they'll charge you for the storage, processor number and the amount of RAM you use (per hour).

Well, to say the truth, I can't talk much more about this topic because I'm still waiting to be accepted in the beta program...



Now I feel like a 15 year old boy, a lot of theory, but very little practice.