How do I create custom properties in Visual Web Parts?
n this post of my Visual Web Part post series we are going to see how to setup custom properties in Visual Web Parts. As you probably know, the most interesting aspect of Visual Web Parts is the ability to configure them directly on a SharePoint page by changing properties during runtime. These properties are stored into the database and reused on each page load. This provides endless scenarios to build configurable pages.
We will follow the creation process of a simple Web Part storing addresses. This Web Part will provide custom properties that are modifiable by a SharePoint user. We will follow the steps that we already covered in detail here. The address Web Part will look like the Web Part in the next figure. We have a simple address consisting of a name, street, zip code and city. We want that these settings are configurable on each single page by our customers.
This post is subdivided into three sections:
- Preparing the project: we setup the Visual Web Part project and check the settings that we might want to change before deploying our Web Part
- Personalize the Address Web Part: we see how we can add customizable properties, and how we connect them to our Visual Web Part
- Some improvements: we make some small modifications to the Web Part that we created to improve the “look & feel” and “usability” of our Web Part
- Points to consider: some notes to consider during Web Part development
Preparing the project
Let us jump in directly in the creation of the Visual Studio project with the Visual Web Part project template for SharePoint 2010.
- create a new Visual Web Part project named “Examples.AddressWebPart” (if you don’t know how to do it, follow this link).
- since the assembly name is called exactly the same, we don’t need to make further changes in the project property page
- delete the Visual Web Part called “VisualWebPart1”
- add a new “Visual Web Part” and call it “Address”
- open the “Features” folder and double click on “Feature 1”. Change the feature name to “Addresses Feature” and description to “This feature activates the address-related Web Parts”. Ensure that the “Address” Web Part is listed in this feature on the right side. You see an example in the next picture:
- we don’t make any changes to the package name, because it will be called like our project name. This is good for us.
Now, we are going to make small changes to our Web Part configuration files “Address.webpart” and “Elements.xml” in the “Address” container. We make these changes to complete our configuration process and to provide a better description to our Web Part on our SharePoint site.
- Let us change the description shown in the Web Part catalog. Double click on the Address.webpart file in the Address container and change the description of the Web Part to “Displays a personalizable address on the screen”. The code will look similar to the next code snipped:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| <? xml version = "1.0" encoding = "utf-8" ?> < webparts > <? XML:NAMESPACE PREFIX = [default] http://schemas.microsoft.com/WebPart/v3 NS = "http://schemas.microsoft.com/WebPart/v3" /><? XML:NAMESPACE PREFIX = [default] http://schemas.microsoft.com/WebPart/v3 NS = "http://schemas.microsoft.com/WebPart/v3" /><? XML:NAMESPACE PREFIX = [default] http://schemas.microsoft.com/WebPart/v3 NS = "http://schemas.microsoft.com/WebPart/v3" /><? XML:NAMESPACE PREFIX = [default] http://schemas.microsoft.com/WebPart/v3 NS = "http://schemas.microsoft.com/WebPart/v3" /><? XML:NAMESPACE PREFIX = [default] http://schemas.microsoft.com/WebPart/v3 NS = "http://schemas.microsoft.com/WebPart/v3" />< webpart xmlns = "http://schemas.microsoft.com/WebPart/v3" > < metadata > < type name = "Examples.AddressWebPart.Address.Address, $SharePoint.Project.AssemblyFullName$" ></ type > < importerrormessage >$Resources:core,ImportErrorMessage;</ importerrormessage > </ metadata > < data > < properties > < property name = "Title" type = "string" >Address</ property > < property name = "Description" type = "string" >Displays a personalizable address on the screen</ property > </ properties > </ data > </ webpart ></ webparts > |
- Finally, we change the category associated to our Web Part in the Web Part catalog. We will change the property value to “Utilities”.
1
2
3
4
5
6
7
8
| <? xml version = "1.0" encoding = "utf-8" ?> <? XML:NAMESPACE PREFIX = [default] http://schemas.microsoft.com/sharepoint/ NS = "http://schemas.microsoft.com/sharepoint/" /><? XML:NAMESPACE PREFIX = [default] http://schemas.microsoft.com/sharepoint/ NS = "http://schemas.microsoft.com/sharepoint/" /><? XML:NAMESPACE PREFIX = [default] http://schemas.microsoft.com/sharepoint/ NS = "http://schemas.microsoft.com/sharepoint/" /><? XML:NAMESPACE PREFIX = [default] http://schemas.microsoft.com/sharepoint/ NS = "http://schemas.microsoft.com/sharepoint/" />< elements xmlns = "http://schemas.microsoft.com/sharepoint/" > < module name = "Address" url = "_catalogs/wp" list = "113" > < file type = "GhostableInLibrary" url = "Address.webpart" path = "AddressAddress.webpart" > < property name = "Group" value = "Utilities" ></ property > </ file > </ module > </ elements > |
Personalize the Address Web Part
Development of Visual Web Parts is simple if you know the most important files to change:
- “Address.cs”: the class inheriting from the Web Part base class and used to setup personalization settings. In addition, this class is loading the web user control needed for our Visual Web Part functionalities
- “AddressUserControl.ascx”: this controls gives us the design time capabilities of Visual Studio 2010
The basic approach is:
- configure the properties of the Web Part class to be persisted
- combine the Web Part class with the web user control to control the rendering behavior
First, let us add the properties that we want to persist with the Web Part framework by adding some code in the “Address.cs” file. Follow the next code example.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
| namespace Examples.AddressWebPart.Address { [ToolboxItemAttribute( false )] public class Address : WebPart { // Visual Studio might automatically update this path when you change the Visual Web Part project item. private const string _ascxPath = @"~/_CONTROLTEMPLATES/Examples.AddressWebPart/Address/AddressUserControl.ascx" ; [Personalizable(), WebBrowsable] public String Firstname { get ; set ; } [Personalizable(), WebBrowsable] public String Lastname { get ; set ; } [Personalizable(), WebBrowsable] public String Street { get ; set ; } [Personalizable(), WebBrowsable] public int Zip { get ; set ; } [Personalizable(), WebBrowsable] public String City { get ; set ; } protected override void CreateChildControls() { Control control = Page.LoadControl(_ascxPath); Controls.Add(control); } } } |
We added some basic type properties to the class. Important is to consider the attributes associated to our properties:
- “Personalizable” tells the Web Part framework to store this property in the database
- “WebBrowsable” tells the Web Part framework to display the property in the editor zone of your Web Part. If you don’t use this attribute, the property can be used for storage, but is not displayed in the editor zone to your end user.
You can store any type that is serializable with the Web Part framework (basic types and complex types).
if you want to make your custom class serializable, put the “Serializable” attribute on the top of your class definition. These properties are only persisted when the Web Part is in “edit mode”. So, if you change some properties in the Web Part class above, they won’t be saved in the database.
Let us see what we did until now on our SharePoint site. Deploy the solution and add the Web Part to any page. When you press the “Edit Web Part” button, you will notice the five properties that we specified before added in the “miscellaneous” category of our editor part as textboxes. In addition, each textbox has a label with text containing the property name.
Start inserting some values into the textboxes and press “OK” to confirm your choice. The Web Part framework stores the values into the database and associates them with the Web Part instance that you are editing. That means, after each page load, the properties in the Web Part class are populated with the settings that you defined in the editor part. However, until now nothing happens in our Web Part because we did not add some controls for rendering into our “AddressUserControl.ascx”. Before we start adding controls, we have to make a last change to our “AddressUserControl.ascx.cs” file. You see them in the next code snipped:
1
2
3
4
5
6
7
| namespace Examples.AddressWebPart.Address { public partial class AddressUserControl : UserControl { public Address WebPart { get ; set ; } } } |
To end it, we have to make a small change in the “Address.cs” class and edit the “CreateChildControls” event:
1
2
3
4
5
6
7
8
9
10
11
| protected override void CreateChildControls() { AddressUserControl control = Page.LoadControl(_ascxPath) as AddressUserControl; if (control != null ) { control.WebPart = this ; } Controls.Add(control); } |
With the code changes above we are telling our “AddressUserControl” to populate the property that we specified with the instance of our Web Part. In this way, we are able to access the Web Part properties specified in the “Address.cs” class.
Finally, we are able to add some controls to our “AddressUserControl.ascx” file that looks like that (please note that I used the designer to create this code):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| <%@ Assembly Name="$SharePoint.Project.AssemblyFullName$" %> <%@ Assembly Name="Microsoft.Web.CommandUI, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %> <%@ Register Tagprefix="SharePoint" Namespace="Microsoft.SharePoint.WebControls" Assembly="Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %> <%@ Register Tagprefix="Utilities" Namespace="Microsoft.SharePoint.Utilities" Assembly="Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %> <%@ Register Tagprefix="asp" Namespace="System.Web.UI" Assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" %> <%@ Import Namespace="Microsoft.SharePoint" %> <%@ Register Tagprefix="WebPartPages" Namespace="Microsoft.SharePoint.WebPartPages" Assembly="Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %> <%@ Control Language="C#" AutoEventWireup="true" CodeBehind="AddressUserControl.ascx.cs" Inherits="Examples.AddressWebPart.Address.AddressUserControl" %> <? xml:namespace prefix = asp />< asp:label style = "font-weight: 700" id = "lblFirstname" runat = "server" ></ asp:label > < asp:label style = "font-weight: 700" id = "lblLastname" runat = "server" ></ asp:label > < br > < br > < asp:label id = "lblStreet" runat = "server" ></ asp:label > < br > < asp:label id = "lblZip" runat = "server" ></ asp:label > -&nb |
The last step is to add in the “OnPrerender” event of the “AddressUserControls.ascx.cs” file. We are simply assigning to the text properties of the labels the corresponding Web Part properties that are persisted by the Web Part framework. The code looks like that:
1
2
3
4
5
6
7
8
9
10
11
12
| protected override void OnPreRender(EventArgs e) { base .OnPreRender(e); if ( this .WebPart != null ) { this .lblFirstname.Text = this .WebPart.Firstname; this .lblLastname.Text = this .WebPart.Lastname; this .lblStreet.Text = this .WebPart.Street; this .lblZip.Text = this .WebPart.Zip.ToString(); this .lblCity.Text = this .WebPart.City; } } |
Let us deploy the solution, add a Web Part to a page and modify it’s properties. The result may look like the next figure:
Some improvements
To end our Address development, we want to improve two aspects of our Web Part. First, we want to remove the label “Address” on the top of our Web Part when looking at our page. Something similar to the next figure:
Second, we want to prohibit the end user, to minimize, hide or close the Web Part. In addition, we improve the editor zone by moving the properties from the “miscellaneous” section to a section that we are going to call “address settings”. Finally, we change the label associated to our city textbox to “city or town”.
This is done by changing some attributes and properties of our “Address.cs” class. The changes that we made are:
- set the “AllowMinimize” and “AllowHide” property to false to disable minimizing and hiding capabilities
- set the “ChromType” of the Web Part to hide the chrome around our Web Part during page load
- added to each property the attribute “Category("Address settings")” to move the property in the new category of our editor part
- added to the city property the attribute “WebDisplayName("City or Town")” to change the label associated to the textbox “city”
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
| namespace Examples.AddressWebPart.Address { [ToolboxItemAttribute( false )] public class Address : WebPart { public Address() { this .AllowMinimize = false ; this .AllowHide = false ; this .AllowClose = false ; this .ChromeType = PartChromeType.None; } // Visual Studio might automatically update this path when you change the Visual Web Part project item. 15: private const string _ascxPath = @"~/_CONTROLTEMPLATES/Examples.AddressWebPart/Address/AddressUserControl.ascx"; [Personalizable(), WebBrowsable, Category( "Address settings" )] public String Firstname { get ; set ; } [Personalizable(), WebBrowsable, Category( "Address settings" )] public String Lastname { get ; set ; } [Personalizable(), WebBrowsable, Category( "Address settings" )] public String Street { get ; set ; } [Personalizable(), WebBrowsable, Category( "Address settings" )] public int Zip { get ; set ; } [Personalizable(), WebBrowsable, WebDisplayName( "City or Town" ), Category( "Address settings" )] public String City { get ; set ; } protected override void CreateChildControls() { AddressUserControl control = Page.LoadControl(_ascxPath) as AddressUserControl; if (control != null ) { control.WebPart = this ; } Controls.Add(control); } } } |
Points to consider
During Web Part development consider following points:
- Never change assembly name, namespace or class name of a Web Part used by your customers. The customer will get an exception to this.
- Never change property names that are personalized to change the description in the editor zone. Use the “WebDisplayName” instead
- If you set a property in your Web Part class, this setting will not be stored in the database.
- Base types are rendered automatically in your editor zone. If you want “complex” types, you need to extend the editor zone with custom code
- Complex types must be serializable, or you will get exceptions on runtime
Summing up
In this post we created a simple address Web Part with customizable properties. We saw how to combine the Web Part class with our web user control and how to personalize some basic Web Part and Editor Part settings. If you want to get more information about Visual Web Part development, simply follow my post series.
Hope this helps,
Karu.Karthi
No comments:
Post a Comment