In order to develop this, I used C# / Visual Studio 2008 and Sharpoint 2007. This should also work in Visual Studio 2005, although you will have to install the web part manually - Visual Studio 2008 has far tighter links to Sharepoint, meaning debugging and deploying is much easier. It should also work in VS2010 / Sharepoint 2010.
The following method will return a SPContentType object, you only need to pass it a list name and content type name. The SPContentType object can be used later to iterate through its fields in oder to render controls based on the content type's fields.
/// <summary> /// Returns the content type object /// </summary> /// <param name="listName"></param> /// <param name="contentTypeName"></param> /// <returns></returns> SPContentType ReadContentType(string listName, string contentTypeName) { //get the web this._web = Microsoft.SharePoint.SPContext.Current.Web; SPList dirList = this._web.Lists[listName]; SPContentType contentType = dirList.ContentTypes[contentTypeName]; //You could simply iterate here like this if you wish, like this: //foreach (SPField field in _contentType.Fields) //{ // string dispName = field.Title; // SPFieldType type = field.Type; // object defaultValue = field.DefaultValue; //} return contentType; }
The following code overrides the "CreateChildControls" Sharepoint method to create our own controls based on the content type. In this example, only text fields and date-times are rendered, but hopefully it straight forward enough for you can see how you could extend this. Simply change:
"Your_List_Name" and "Your_Content_Type_Name"to your actual values from your Sharepoint site.
I use the "LiteralControl" method to render raw HTML on the page to format the form, which feels really nasty but is efective.
protected override void CreateChildControls() { //Controls.Clear(); //base.CreateChildControls(); // Read in the content type for the target list SPContentType contentType = ReadContentType("Your_List_Name", "Your_Content_Type_Name"); Controls.Add(new LiteralControl("<TABLE>")); foreach (SPField field in contentType.Fields) { // Ignore hidden or readonly fields if (field.Hidden) continue; if (field.ReadOnlyField) continue; if (field.Type == SPFieldType.Text) { string dispName = field.Title; string staticName = field.StaticName; SPFieldType type = field.Type; object defaultValue = field.DefaultValue; Controls.Add(new LiteralControl("<TR>")); Controls.Add(new LiteralControl("<TD>")); Label lbl = new Label(); lbl.Text = dispName; Controls.Add(lbl); Controls.Add(new LiteralControl("</TD>")); // Textbox TextBox tb = new TextBox(); // I give my controls a unique ID so I can reference them later tb.ID = "xx_ctl_xx" + dispName; if(defaultValue != null) tb.Text = defaultValue.ToString(); Controls.Add(new LiteralControl("<TD>")); Controls.Add(tb); Controls.Add(new LiteralControl("</TD>")); Controls.Add(new LiteralControl("</TR>")); } else if (field.Type == SPFieldType.DateTime) { string dispName = field.Title; string staticName = field.StaticName; SPFieldType type = field.Type; object defaultValue = field.DefaultValue; Label lbl = new Label(); lbl.Text = dispName; Controls.Add(new LiteralControl("<TR>")); Controls.Add(new LiteralControl("<TD>")); Controls.Add(lbl); Controls.Add(new LiteralControl("</TD>")); // Datetime picker SPDatePickerControl dtp = new SPDatePickerControl(); dtp.ID = "xx_ctl_xx" + staticName; if (defaultValue != null) dtp.SelectedDate = defaultValue.ToString(); Controls.Add(new LiteralControl("<TD>")); Controls.Add(dtp); Controls.Add(new LiteralControl("</TD>")); Controls.Add(new LiteralControl("</TR>")); } } Controls.Add(new LiteralControl("</TABLE>")); //In my code, I use the controls to perform a custom search. The following code plugs in //the event handler to do this, based on the values the user puts into the controls rendered above. //This blog post will not go into the detail of this so I have commented the following lines out. //cmdSearch = new Button(); //cmdSearch.Text = "Start Search"; //cmdSearch.Click += new EventHandler(cmdSearch_Click); //this.Controls.Add(cmdSearch); //lblQueryResult = new Label(); //this.Controls.Add(lblQueryResult); base.CreateChildControls(); }
Once deployed, you can add this web part to your site in the normal way using the web front end. Depending on the fields in your content type, it should render something like this (web part highlighted in pink):
No comments:
Post a Comment