Programatically Highlighting Current Step In ASP.NET Wizard

This was frustrating, so gonna save some folks the time that are using the ASP.NET wizard in a SharePoint WebPart.

I found a lot of examples of how to highlight the current step in the ASP.NET wizard control via WebForm markup, but there was a severe lack of examples that show how to do it in straight code behind. In essence you are relegated to implement various sets of ITemplates for the ASP.NET wizard corresponding DataList, notably instantiating against the SelectedItemTemplate and ItemTemplate properties. ITemplates defines the behavior for populating a templated ASP.NET server control with child controls. The child controls represent the inline templates defined on the page, or in this case, within a composite control. The important part to remember when creating the various templates is the SideBarList control must contain an IButtonControl with ID SideBarButton in every item template, this may include ItemTemplate, EditItemTemplate, SelectedItemTemplate or AlternatingItemTemplate if they exist. As stated before, we just need to focus on two properties.

So, firstly for your strongly typed Wizard object in CreateChildControls or wherever set the SideBarTemplate

[csharp]

[SomeAspNetWizardObject].SideBarTemplate = new SideBarHighlighter();

[/csharp]

Now onto ITemplate fiesta:

[csharp]

public class SelectedItemTemplateMerged :ITemplate
    {
        public void InstantiateIn(Control container)
        {
            LinkButton activeSideBarButton = new LinkButton();
            activeSideBarButton.ID = “ActiveSideBarButton”;
            LinkButton sideBarButton = new LinkButton();
            sideBarButton.ID = “SideBarButton”;
            sideBarButton.Visible = false;
            container.Controls.Add(activeSideBarButton);
            container.Controls.Add(sideBarButton);
        }
    }

    public class SideBarItem :ITemplate
    {
        public void InstantiateIn(Control container)
        {
            LinkButton sideBarButton = new LinkButton();
            sideBarButton.ID = “SideBarButton”;
            container.Controls.Add(sideBarButton);
        }
    }

    public class SideBarHighlighter : ITemplate
    {
        public void InstantiateIn(Control container)
        {
            DataList sideBarList = new DataList();
            sideBarList.ItemDataBound += SideBarList_ItemDataBound;
            sideBarList.SelectedItemTemplate = new SelectedItemTemplateMerged();
            sideBarList.ItemTemplate = new SideBarItem();
            sideBarList.ID = “SideBarList”;
            sideBarList.SelectedItemStyle.Font.Bold = true;
            sideBarList.RepeatLayout = RepeatLayout.Flow;
            container.Controls.Add(sideBarList);
        }

        private void SideBarList_ItemDataBound(object sender, DataListItemEventArgs e)
        {
            WizardStep stepCurrent = (WizardStep) e.Item.DataItem;
            if (stepCurrent.Wizard.ActiveStepIndex == e.Item.ItemIndex)
            {
                LinkButton activeSideBarButton = (LinkButton) e.Item.FindControl(“ActiveSideBarButton”);
                activeSideBarButton.BorderStyle = BorderStyle.Solid;
                activeSideBarButton.BorderColor = Color.White;
                activeSideBarButton.BackColor = Color.White;
                activeSideBarButton.Font.Bold = true;
                activeSideBarButton.Style.Add(HtmlTextWriterStyle.Color, “#000000”);
                activeSideBarButton.Text = string.Format(“>> {0}”, stepCurrent.Title);           
            }
        }
    }

[/csharp]

 The obvious important part is the ItemDataBound event, since that’s where the text is mutated.

Share

I Hate Mr. There Is A SharePoint Product For Everything

I hate you! You know who you are. You are the guy that no matter what comes up, there is your stupid third party solution that although you think will work, it never does and I get blamed for you being inept. You mainly suggest your stupid little solution during project conversation because you know god damn well that the company has already spent an obscene amount of money on it and you really, really are looking for any justification to use it because you brought the solution to the company! Sometimes I wonder whether you just troll the net looking for SharePoint products just so that you have something to suggest and say at meetings.
Let’s take an example conversation of why I hate these types of people.

[Management]: Well Adam, we need to rollup a subset of data across our instance. It’s a one stop shop, where need it done fast, and not very generic in terms of data aggregation. This is a very specific goal folks and has high visibility on this project!

[Mr. There Is A SharePoint Product For Everything]: Corasworks will work great for this! They have some super awesome rollup! Because it has the name Wizard in it! It has to be great!

[Adam]: No, no, no. Don’t you dare suggest that. Mr. Management man, Corasworks software (I choose Corasworks in this example because what I am about to say about them as a SharePoint product vendor is accurate IMHO. And everyone knows I think Corasworks is a stupid purchase decision), under the hood, is absolutely terribly written, mostly consisting of hackneyed inefficient code. I have seen several instances where the product itself was the cause of several acute server issues pegging processes due to poor programming design decisions. They fail drastically in handling basic environmental respect issues, making the product an even poorer decision for use, an example of which is not handling relative URL’s in their WebParts (IMHO, if you are asking for a site reference you should always be offered the option to tokenize this). This is a bad idea, and I would encourage you to disregard that suggestion. In order to develop this will take pretty much as much time as this meeting is going to take, this is not a very intensive task.

[Mr. There Is A SharePoint Product For Everything]: This isn’t a bad idea! It’s called the Data Rollup Wizard! Why wouldn’t it work, it has a cool name! And we already own it!

[Adam]: Which is why you are suggesting it, that’s all this is about. In the time that you are able to get this “amazing” data rollup whatever to work, it easily could have been hand coded to the specifications that management is handing down. Seriously, I don’t think it’s a good idea. I really think that the benefits of doing custom development will far outweigh those of staying within the defined limitations of a company that knows nothing about our business or practices, and I think its wise all in all to follow the concept of “Do not use a cannon to kill a mosquito”, principally when that cannon hardly works and has all sorts of internal design problems. There are several intrinsic benefits to the in-house development decision as well, such as being able to extend the source code to OUR needs, and being able to recycle methods that we write in future development efforts.

[Mr. There Is A SharePoint Product For Everything]: Ok! Well don’t you worry Adam. I have 50 other products in mind that will do this. I encourage us to go buy more crap to make Adam’s life miserable!

Seriously, I am sure if you are a SharePoint developer than you have had some variation of this conversation. There is always that one guy on the team, that no matter what the problem is, he always has a company that offers a product that solves it, even if its not an entire solution, surely it is better than spending in-house development time on it. I really hate that guy, because a lot of the time the products that he recommends don’t get used, and it gives an awful ding on project reports because there is an obscene amount of money spent on his meaningless suggestions, both consisting of obviously the product cost itself, but there is also a huge time investment as they product has to be explored, questioned, tested, implemented, and configured. Then you don’t even know that you did it right because you are relying on a guide that some intern wrote.

Look, I am all for buying something that helps the project along. There are some things that are so generic in purpose that it truly does not make sense to develop them in-house, like interface controls provided through companies like Telerik or Infragistics. Honestly, there isn’t a ton of purpose in writing that yourself. But taking a piece of software and trying to wrap your business goal around it, instead of programming TOWARDS a business goal, is arbitrary, and well, just plain stupid. That is trying to fit a square peg in a round hole, and generally I see costing entirely more much time and money than just sitting done and hashing it out with custom work.

Share

Managing Data Connections and Universal Data Connection V2 (UDC) Files

InfoPath exposes several external data sources that are available for consumption either as a primary or secondary data connection. Most of the consumed data connections can be called from within the Data Connection Wizard that InfoPath provides. When using the Data Connection Wizard, you can choose to create a new data source for fetching or submitting. In relation to SharePoint, it is possible to crawl a Microsoft Office Server instance to harvest available data connections, by only supplying the site that you wish to crawl as an argument, usually the site from which the InfoPath .XSN is going to be made available.

The InfoPath data sources are:

  • Microsoft Office Access database
  • Microsoft SQL Server database (a browser enabled form cannot be submit to a database directly)
  • Email
  • Web service
  • XML file
  • HTTP Post
  • Web service
  • SharePoint Document Library or List

UDC Files

The most manageable way to service users creating InfoPath forms is to provide the data connections by storing UDC files in SharePoint Data Connection Libraries (DCL). UDC’s are a method of black-boxing data connections to hide the piping of the data connection, and call the relevant forms. By doing this, the connection used by the InfoPath form is not held within it, but called when needed at run-time from the DCL, so can be requested from any number of InfoPath forms. This allows the management and consolidation of data connections so if a specific database or web service is frequently used by several enterprise forms, it can be entered once, and called many times, while the actual data connection architecture is black-boxed.


Figure 14-3

Because the UDC files are held within what is basically a specialized SharePoint Document Library, there are granular levels of security that can be applied. Similar to the SharePoint Document Libraries, Contributors on the site can submit content, meaning new UDC files. However, within a DCL only UDC’s that have been approved can be consumed by any number of deployed InfoPath forms.

UDC files, like other InfoPath assets, are composed of well-formed XML. UDCs, like other document blueprints that are stored in Office Server 2007, are stored as content types. Content types, in order to provide the appropriate metadata will push the relevant properties to populate the needed columns using <FieldRefs> element when stored within the SharePoint Data Connection Library. When building custom UDC files, there are two ways for a developer to approach it. The first is using the inherent Conversion functions that are offered through InfoPath. Using the Convert option in the Manage Data Connections section of InfoPath, it is possible to publish a UDC file to a SharePoint Data Connection Library. The other way is to hand craft UDC files since it is composed of just XML elements. Some of the elements that compose a UDC file are optional, while others are required for it to function (see the following table).

General UDC File Elements

Element Name

 

Element Description

 

ContentTypeID

 

The ContentTypeID element specifies the diagram blueprint that will be used to populate the columns that are used in the Data Connection Library. To gather some of this information, this element couples with the name and description elements.

 

DataSource

 

Defines the UDC namespace and the version.

 

Name

 

Optional element that declares name information about the UDC file, used to populate information in the SharePoint Data Connection Library.

 

Description

 

Optional element that declares description information about the UDC file, used to populate information in the SharePoint Data Connection Library.

 

Type

 

Required element which defines the data type that the UDC is using, such as a web service or database.

 

ConnectionInfo

 

Describes the purpose of the connection, whether it is Read/Write/Both, as well as describing how the actual connection is made to the back-end data source.

 

ConnectionInfo for SharePoint List

The most populated portion of the UDC file is the ConnectionInfo element, which defines where the actual consumed datasource is located. A common UDC file is one that queries a frequently hit SharePoint list to gather values. In order to construct a SharePoint list UDC file, within the ConnectionInfo element, specify the SelectCommand element to grab the relevant values by passing in the ListId and WebUrl child elements.

[xml]

<udc:ConnectionInfo Purpose=ReadOnly>
<udc:SelectCommand>
<udc:ListId>{B78D5A41-BD83-49f0-999C-22B3FB9253A4}</udc:ListId>
<udc:WebUrl>http://localhost/sharepointsite</udc:WebUrl>
</udc:SelectCommand>
</udc:ConnectionInfo>

[/xml]

Web Service ConnectionInfo

Optionally to collect list items from a SharePoint list the SharePoint lists.asmx web service in the _vti_bin directory can be called and used in the same type of fashion as the above. Since the Lists.asmx WebService allows using the GetListItems operation, it is possible to retrieve list values using this web service by supplying a few parameters. This could be manipulated as well to include other web services outside of SharePoint if there are other external sources that house the desired values.

[xml]

<udc:ConnectionInfo Purpose=ReadOnly>
<udc:WsdlUrl>
http://localhost/_vti_bin/lists.asmx?wsdl
</udc:WsdlUrl>
<udc:SelectCommand>
<udc:ServiceUrl>
http://localhost/_vti_bin/lists.asmx
</udc:ServiceUrl>
<udc:SoapAction>
http://localhost/_vti_bin/lists.asmx?op=GetListItems
</udc:SoapAction>
</udc:SelectCommand>
</udc:ConnectionInfo>

[/xml]

One of the most frequently confusing things in terms of web services is the authentication scheme that is used in order to verify the requesting user against the web service. For most web services, it is common that a service account will be used in order to pass the appropriate credentials to the service, however InfoPath 2007 does not contain a native method to implement .NET impersonation such as that provided by the WindowsIdentity class in .NET commonly known as double hop authentication problem . However, this facility is provided through the inherent Web Service Proxy Configuration that is provided by Forms Server 2007 which will allow the users working with the InfoPath form to harvest values out of the web service on behalf of the service account as opposed to passing the requesting users login token. In order to use the Web Service proxy, it is necessary for the <udc:ServiceUrl> parent element to have the UseFormsServiceProxy attribute set to a value of 1.

Share