Showing posts with label Web part. Show all posts
Showing posts with label Web part. Show all posts

Monday, 3 October 2011

Embedding Google charts into Sharepoint Web Parts

The other day I was developing a portal and at some point the “client” asked to provide a simple pie chart in the landing page. I said to him; “that should be ok”. At that point I was thinking obviously in the lovely Chart Web Part that comes from default in Sharepoint 2010. After talking with him for a while I realised that requirements where quite high, in terms of data collection. I want to clarify I am trying to avoid PerformancePoint Services because I don’t want to activate the service just for one chart.

Obviously I always have plan A,B,C,D…well sometimes I reach Z. I tried to play around a little bit with the Out Of The Box web part, unfortunately plan A was not good enough, I was looking for something sharp, something elegant, something independent from the whole system, and going for plan A should require to create few extra workflows.

Then I tried to create a Visual Webpart, thinking that the System.Web.UI chart control will work properly in Sharepoint 2010. Unfortunately, it didn’t. Big mistake in my side, I was playing with a .NET 4.0 control, obviously Sharepoint 2010 only support .NET 3.5, so I had to abort plan B.

I asked Trev, one of the web developers, and he suggested me Google Charts. In fact he said that they look much better than the .NET ones, because they use AJAX. I went to the Google Chart Tools website and I was amazed about what I saw. Google provides all the information about the API + all the code required, so with a copy paste you can get a nice example in five minutes.

What I did was to create a nice method where you can pass the parameters , build the JavaScript code and embedded into the Web Part. You can use, either a Web Part or a Visual Web Part. In my case I decided to use a Visual Web Part. There is not a particular reason for that.

I am going to do a Step by Step, so you know how to implement it. The result will be a simple pie chart (remember you can create something similar with another Google chart). I will post the project at the end of the article so you can implement it.

- Step 1
Go to Visual Studio 2010->New Project->Sharepoint->2010->Empty Project->call it CPDPointsWebPart and click OK. Select you want to deploy in your farm.

- Step 2
Go to the project, Right click and add->new item…->Sharepoint->2010->Visual Webpart and call it CPDWebPart.

- Step 3
Go to the Feature (Feature1)-> Right click and rename it to CPDWebPartFeature. Your solution should look like this now:
image

- Step 4
Go to CPDWebPartUserControl.ascx.cs, remove all the code and paste this one:

using System;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Collections.Generic;
namespace CPDPointsWebPart.CPDWebPart
{
    public partial class CPDWebPartUserControl : UserControl
    {       
        protected void Page_Load(object sender, EventArgs e)
        {
            
            Dictionary<string, int> _dValues = new Dictionary<string, int>();
            _dValues.Add("CPD Training done", 4);
            _dValues.Add("CPD Training Left to be done", 6);
            
            List<string> _lColumns = new List<string>();
            _lColumns.Add("CPD");
            _lColumns.Add("Hours");
            
            Page.RegisterClientScriptBlock("PieChart", GooglePieChart("CPD Points",_dValues,_lColumns,450,300));
        }        
        public string GooglePieChart(string _sTitle, Dictionary<string, int> _dChartParameters, List<string> _lColumns, int _iWidth, int _iHeight)
        {
            System.Text.StringBuilder _Chart = new System.Text.StringBuilder();
            _Chart.Append(@"<script type='text/javascript' src='https://www.google.com/jsapi'></script>");
            _Chart.Append(@"<script type='text/javascript'> ");
            _Chart.Append(@"google.load('visualization', '1', {packages:['corechart']}); ");
            _Chart.Append(@"google.setOnLoadCallback(drawChart);");
            _Chart.Append(@"function drawChart() {  ");
            _Chart.Append(@"var data = new google.visualization.DataTable();  ");
            _Chart.Append(@"data.addColumn('string', '" + _lColumns[0] + "');");
            _Chart.Append(@"data.addColumn('number', '" + _lColumns[1] + "');");
            _Chart.Append(@"data.addRows(" + _dChartParameters.Count.ToString()+ ");");
    
            int i=0;
            foreach (var item in _dChartParameters)
         {
          _Chart.Append(@"data.setValue("+i.ToString()+", 0, '"+item.Key+"'); ");
                _Chart.Append(@"data.setValue(" + i.ToString() + ", 1, " + item.Value+ "); ");   
                i++;
         }
            _Chart.Append(@"var chart = new google.visualization.PieChart(document.getElementById('chart_div'));");
            _Chart.Append(@"chart.draw(data, {width: " + _iWidth.ToString() + ", height: " + _iHeight.ToString() + ", title: '" + _sTitle + "'}); ");
            _Chart.Append(@"}");
            _Chart.Append(@"</script>");
            return _Chart.ToString();
        }
    }             
}


Notice I use Page.RegisterClientScriptBlock(…) to post the JavaScript code into the Visual Web Part.


- Step 5
Double click on CPDWebPartUserControl.ascx and copy and paste this code. The only line I am going to add is “<div id="chart_div"></div> “ . You can add this line from your code as well, but I think by doing it like this we can see the interaction between the JavaScript code and the ascx code.


- Step 6
Deploy the Visual Web Part, go to your site edit the page, insert the webpart (it will be under custom). This should be the result:
image


Conclusion: Google can provide a very good solution for your charts. There are more chart engines out there you can use, but I find Google the fastest one in terms of performance.


To download the code click in the image.
image

Sunday, 18 September 2011

ToolPart ; How to create a tool part inside of a WebPart

We are going to introduce toolparts. This little “tools” can make the PROPERTIES of you web part quite interesting, as you can add any type of control without limitations. It is what we call, going to the extra mille.

Let’s go to start defining what a ToolPart is.
ToolPart: Defines custom tool parts that display a customized user interface for defining the properties of a Web Part inside of the tool pane.

This is the syntax for the ToolPart class:

[AspNetHostingPermissionAttribute(SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
[AspNetHostingPermissionAttribute(SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
public abstract class ToolPart : EditorPartAdapter

This is how it works. Imagine you need to display a choice control or a dropdown menu in the Properties of the Web Part, what do you do? you only have boring text controls. You create a class that inherits the ToolPart class, add the control and after that you add that control into your webpart.


It will probably better do a step by step so you can understand how this thing works.


What do you need?



  1. Visual Studio 2010
  2. Sharepoint 2010
  3. 20 minutes of your time

Step 1
Let’s go to create the project. Go to Visual Studio 2010->New Project->Sharepoint->2010->Empty Sharepoint Project and call it netsourcecodeToolPart.
image


Step 2
Let’s go to add a webpart to test the project. Go to your project->Right Click->Add-> New Item…->Web Part and call it NSCWebPart.
image



Step 3
We are going to add the class where the ToolPart will be added. Right Click in your project->New->Class. Call the class NSCToolPart.
image


Step 4
Now remove all the code from NSCToolPart.cs ,copy and paste this code into the file (this code is from sandeep’s blog).

using System;
using System.ComponentModel;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
using System.Security.Permissions;
namespace netsourcecodeToolsPart
{
    [AspNetHostingPermissionAttribute(SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
    [AspNetHostingPermissionAttribute(SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
    public class NSCToolPart: Microsoft.SharePoint.WebPartPages.ToolPart
    {
        // First, override the CreateChildControls method. This is where we create the controls.
        protected override void CreateChildControls()
        {
            // create a panel that will hold all of our controls
            Panel toolPartPanel = new Panel();
            // create the actual control
            DropDownList sampleDropDown1 = new DropDownList();
            sampleDropDown1.ID = "sampleDropDown1";
            sampleDropDown1.Items.Add("Item 1");
            sampleDropDown1.Items.Add("Item 2");
            sampleDropDown1.Items.Add("Item 3");
            toolPartPanel.Controls.Add(sampleDropDown1);
            // finally add the panel to the controls collection of the tool part
            Controls.Add(toolPartPanel);
            base.CreateChildControls();
        }
        // Next, override the ApplyChanges method.
        // This method is where we will persist the values that the user selects.
        public override void ApplyChanges()
        {
            // get the parent webpart
            netsourcecodeToolsPart.NSCWebPart parentWebPart = (netsourcecodeToolsPart.NSCWebPart)this.ParentToolPane.SelectedWebPart;
            // loop thru this control's controls until we find the ones that we need to persist.
            RetrievePropertyValues(this.Controls, parentWebPart);
        }
        // Recursive function that tries to locate the values set in the toolpart
        private void RetrievePropertyValues(ControlCollection controls, netsourcecodeToolsPart.NSCWebPart parentWebPart)
        {
            foreach (Control ctl in controls)
            {
                RetrievePropertyValue(ctl, parentWebPart);
                if (ctl.HasControls())
                {
                    RetrievePropertyValues(ctl.Controls, parentWebPart);
                }
            }
        }
        // Method for retrieving the values set by the user.
        private void RetrievePropertyValue(Control ctl, netsourcecodeToolsPart.NSCWebPart parentWebPart)
        {
            if (ctl is DropDownList)
            {
                if (ctl.ID.Equals("sampleDropDown1"))
                {
                    DropDownList drp = (DropDownList)ctl;
                    if (drp.SelectedItem.Value != "")
                    {
                        parentWebPart.myProperty = drp.SelectedItem.Value;
                    }
                }
            }
        }
    }
}

Step 5
Open NSCWebPart and copy and paste this code (this code is from sandeep’s blog).

using System;
using System.ComponentModel;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
using Microsoft.SharePoint.WebPartPages;
namespace netsourcecodeToolsPart
{
    [ToolboxItemAttribute(false)]
    public class NSCWebPart : Microsoft.SharePoint.WebPartPages.WebPart
    {
        private string _property1 = "Default Value";
        public NSCWebPart()
        {
            this.ExportMode = WebPartExportMode.All;
        }
        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);
            Label lbl = new Label();
            lbl.ID = "toolpart_webpart_lbl1";
            lbl.Text = _property1;
            Controls.Add(lbl);
        }
        public string myProperty
        {
            get
            {
                return _property1;
            }
            set
            {
                _property1 = value;
            }
        }
        public override ToolPart[] GetToolParts()
        {
            // resize the tool part array
            ToolPart[] toolparts = new ToolPart[3];
            // instantiate the standard SharePopint tool part
            WebPartToolPart wptp = new WebPartToolPart();
            // instantiate the custom property toolpart if needed.
            // this object is what renders our regular properties.
            CustomPropertyToolPart custom = new CustomPropertyToolPart();
            // instantiate and add our tool part to the array.
            // tool parts will render in the order they are added to this array.
            toolparts[0] = new NSCToolPart();
            toolparts[1] = custom;
            toolparts[2] = wptp;
            return toolparts;
        }
        protected override void CreateChildControls()
        {
        }
    }
}

Step 6
Deploy the solution. If you want to download the code, click on Download.
image

Friday, 15 October 2010

Creating an interactive Sharepoint 2010 Web Part with Visual Studio 2010 using forms and web services.

A web part is one of the most common controls you can add, in a Sharepoint distribution. They have been always there but it has been always difficult to develop anything reliable for previous versions (2003/2007). On Sharepoint 2010 Microsoft decided to do something about it, and try to make the life easier for the software developers. as a result we can count with a very nice environment to program and DEPLOY , Visual Studio 2010.

Of course you have plenty of out-of-the-box web parts, or just by going to Codeplex you will be able to find tons, but you never knows what your organization is going to need.

Because of this I have decided to create a sophisticated web part, that gets the weather from a web service and post it into a textbox. This web part includes events, so we will be able how to interact with events and web parts.

The easiest way to create a from is by using our new classes coming from System.Web.UI.WebControls,
I am going to list all of them so you know what you can do after this tutorial:


1- Create an Empty Sharepoint project, select where you want to debug your project and select "deploy as farm solution". Type the name WeatherWebpart as name of the project.

2- Go to your project Right-Click add new Item and select "Web part" (DO NOT CLICK ON VISUAL WEB PART).

AccessDataSource
AccessDataSourceView
AdCreatedEventArgs
AdRotator
AssociatedControlConverter
AuthenticateEventArgs
AutoGeneratedField
AutoGeneratedFieldProperties
BaseCompareValidator
BaseDataBoundControl
BaseDataList
BaseValidator
BoundColumn
BoundField
BulletedList
BulletedListEventArgs
Button
ButtonColumn
ButtonField
ButtonFieldBase
Calendar
CalendarDay
ChangePassword
CheckBox
CheckBoxField
CheckBoxList
CircleHotSpot
CommandEventArgs
CommandField
CompareValidator
CompleteWizardStep
CompositeControl
CompositeDataBoundControl
Content
ContentPlaceHolder
ContextDataSource
ContextDataSourceContextData
ContextDataSourceView
ControlIDConverter
ControlParameter
ControlPropertyNameConverter
CookieParameter
CreateUserErrorEventArgs
CreateUserWizard
CreateUserWizardStep
CustomValidator
DataBoundControl
DataControlCommands
DataControlField
DataControlFieldCell
DataControlFieldCollection
DataControlFieldHeaderCell
DataGrid
DataGridColumn
DataGridColumnCollection
DataGridCommandEventArgs
DataGridItem
DataGridItemCollection
DataGridItemEventArgs
DataGridPageChangedEventArgs
DataGridPagerStyle
DataGridSortCommandEventArgs
DataKey
DataKeyArray
DataKeyCollection
DataList
DataListCommandEventArgs
DataListItem
DataListItemCollection
DataListItemEventArgs
DataPager
DataPagerCommandEventArgs
DataPagerField
DataPagerFieldCollection
DataPagerFieldCommandEventArgs
DataPagerFieldItem
DayRenderEventArgs
DetailsView
DetailsViewCommandEventArgs
DetailsViewDeletedEventArgs
DetailsViewDeleteEventArgs
DetailsViewInsertedEventArgs
DetailsViewInsertEventArgs
DetailsViewModeEventArgs
DetailsViewPageEventArgs
DetailsViewPagerRow
DetailsViewRow
DetailsViewRowCollection
DetailsViewUpdatedEventArgs
DetailsViewUpdateEventArgs
DropDownList
EditCommandColumn
EmbeddedMailObject
EmbeddedMailObjectsCollection
EntityDataSource
EntityDataSourceChangedEventArgs
EntityDataSourceChangingEventArgs
EntityDataSourceContextCreatedEventArgs
EntityDataSourceContextCreatingEventArgs
EntityDataSourceContextDisposingEventArgs
EntityDataSourceSelectedEventArgs
EntityDataSourceSelectingEventArgs
EntityDataSourceValidationException
EntityDataSourceView
FileUpload
FontInfo
FontNamesConverter
FontUnitConverter
FormParameter
FormView
FormViewCommandEventArgs
FormViewDeletedEventArgs
FormViewDeleteEventArgs
FormViewInsertedEventArgs
FormViewInsertEventArgs
FormViewModeEventArgs
FormViewPageEventArgs
FormViewPagerRow
FormViewRow
FormViewUpdatedEventArgs
FormViewUpdateEventArgs
GridView
GridViewCancelEditEventArgs
GridViewCommandEventArgs
GridViewDeletedEventArgs
GridViewDeleteEventArgs
GridViewEditEventArgs
GridViewPageEventArgs
GridViewRow
GridViewRowCollection
GridViewRowEventArgs
GridViewSelectEventArgs
GridViewSortEventArgs
GridViewUpdatedEventArgs
GridViewUpdateEventArgs
HiddenField
HierarchicalDataBoundControl
HotSpot
HotSpotCollection
HyperLink
HyperLinkColumn
HyperLinkControlBuilder
HyperLinkField
Image
ImageButton
ImageField
ImageMap
ImageMapEventArgs
Label
LabelControlBuilder
LinkButton
LinkButtonControlBuilder
LinqDataSource
LinqDataSourceContextEventArgs
LinqDataSourceDeleteEventArgs
LinqDataSourceDisposeEventArgs
LinqDataSourceInsertEventArgs
LinqDataSourceSelectEventArgs
LinqDataSourceStatusEventArgs
LinqDataSourceUpdateEventArgs
LinqDataSourceValidationException
LinqDataSourceView
ListBox
ListControl
ListItem
ListItemCollection
ListItemControlBuilder
ListView
ListViewCancelEventArgs
ListViewCommandEventArgs
ListViewDataItem
ListViewDeletedEventArgs
ListViewDeleteEventArgs
ListViewEditEventArgs
ListViewInsertedEventArgs
ListViewInsertEventArgs
ListViewItem
ListViewItemEventArgs
ListViewPagedDataSource
ListViewSelectEventArgs
ListViewSortEventArgs
ListViewUpdatedEventArgs
ListViewUpdateEventArgs
Literal
LiteralControlBuilder
Localize
Login
LoginCancelEventArgs
LoginName
LoginStatus
LoginView
MailDefinition
MailMessageEventArgs
Menu
MenuEventArgs
MenuItem
MenuItemBinding
MenuItemBindingCollection
MenuItemCollection
MenuItemStyle
MenuItemStyleCollection
MenuItemTemplateContainer
MonthChangedEventArgs
MultiView
MultiViewControlBuilder
NextPreviousPagerField
NumericPagerField
ObjectDataSource
ObjectDataSourceDisposingEventArgs
ObjectDataSourceEventArgs
ObjectDataSourceFilteringEventArgs
ObjectDataSourceMethodEventArgs
ObjectDataSourceSelectingEventArgs
ObjectDataSourceStatusEventArgs
ObjectDataSourceView
PagedDataSource
PageEventArgs
PagePropertiesChangingEventArgs
PagerSettings
Panel
PanelStyle
Parameter
ParameterCollection
PasswordRecovery
PlaceHolder
PlaceHolderControlBuilder
PolygonHotSpot
ProfileParameter
QueryableDataSource
QueryableDataSourceEditData
QueryableDataSourceView
QueryContext
QueryCreatedEventArgs
QueryExtender
QueryStringParameter
RadioButton
RadioButtonList
RangeValidator
RectangleHotSpot
RegularExpressionValidator
Repeater
RepeaterCommandEventArgs
RepeaterItem
RepeaterItemCollection
RepeaterItemEventArgs
RepeatInfo
RequiredFieldValidator
RoleGroup
RoleGroupCollection
RouteParameter
SelectedDatesCollection
SendMailErrorEventArgs
ServerValidateEventArgs
SessionParameter
SiteMapDataSource
SiteMapDataSourceView
SiteMapHierarchicalDataSourceView
SiteMapNodeItem
SiteMapNodeItemEventArgs
SiteMapPath
SqlDataSource
SqlDataSourceCommandEventArgs
SqlDataSourceFilteringEventArgs
SqlDataSourceSelectingEventArgs
SqlDataSourceStatusEventArgs
SqlDataSourceView
StringArrayConverter
Style
StyleCollection
SubMenuStyle
SubMenuStyleCollection
Substitution
Table
Table.RowControlCollection
TableCell
TableCellCollection
TableCellControlBuilder
TableFooterRow
TableHeaderCell
TableHeaderRow
TableItemStyle
TableRow
TableRow.CellControlCollection
TableRowCollection
TableSectionStyle
TableStyle
TargetConverter
TemplateColumn
TemplatedWizardStep
TemplateField
TemplatePagerField
TextBox
TextBoxControlBuilder
TreeNode
TreeNodeBinding
TreeNodeBindingCollection
TreeNodeCollection
TreeNodeEventArgs
TreeNodeStyle
TreeNodeStyleCollection
TreeView
UnitConverter
ValidatedControlConverter
ValidationSummary
View
ViewCollection
WebColorConverter
WebControl
Wizard
WizardNavigationEventArgs
WizardStep
WizardStepBase
WizardStepCollection
WizardStepControlBuilder
Xml
XmlBuilder
XmlDataSource
XmlDataSourceView
XmlHierarchicalDataSourceView


3- Call this new Web part "GlobalWeatherWebPart".

4- Go to your project, right-click, add service reference->advanced->Add web Reference... (on the bottom) and paste this address: http://ws.cdyne.com/WeatherWS/Weather.asmx?wsdl

5- Call the wen reference WSWeather.

6- On the project menu, right click .

7- On "GlobalWeatherWebPart.cs" copy and paste the following code and deploy it, now you can go to your web->Site Actions->New Page->Insert Ribbon->Web Part->Categories->Custom->Select "GlobalWeatherWebPart"->Add->Format Text->Save and Close:

using System;

using System.ComponentModel;

using System.Web;

using System.Web.UI;

using System.Web.UI.WebControls;

using System.Web.UI.WebControls.WebParts;

using Microsoft.SharePoint;

using Microsoft.SharePoint.WebControls;

using Microsoft.SharePoint.Utilities;

 

namespace WeatherWebpart.GlobalWeatherWebPart

{

[ToolboxItemAttribute(false)]

public class GlobalWeatherWebPart : WebPart

{

//## We declare these variables global in order

//## to be able to capture the text

TextBox _txtCountryName = null;

TextBox _txtZipCode = null;

TextBox _txtForecast = null;

Button _cmdSendForecast = null;

 

 

public GlobalWeatherWebPart()

{

}

 

protected override void CreateChildControls()

{

base.CreateChildControls();

 

//## Table

Table _tWeatherTable = null;

TableRow _trRow = null;

TableCell _tcCell = null;

 

//## Controls

Label _lblTitle = null;

Label _lblCountry = null;

Label _lblCity = null;

Label _lblForecast = null;

 

try

{

//## Creating the table...

_tWeatherTable = new Table();

 

//################################################################

//## Creating the columns ## And Rows

//################################################################

 

//## 1 ROW

_trRow = new TableRow();

_tcCell = new TableCell();

_tcCell.ColumnSpan = 2;

_tcCell.VerticalAlign = VerticalAlign.Top;

_lblTitle = new Label();

_lblTitle.Text = "Real-Time Forecast Checker";

_lblTitle.Font.Bold = true;

_lblTitle.Font.Size = 14;

_tcCell.Controls.Add(_lblTitle);

_trRow.Controls.Add(_tcCell);

_tWeatherTable.Controls.Add(_trRow);

//## 2 ROW COUNTRY ##

//-- [LABEL PART] --

_trRow = new TableRow();

_tcCell = new TableCell();

_tcCell.Style["padding-top"] = "7px";

_tcCell.VerticalAlign = VerticalAlign.Top;

_lblCountry = new Label();

_lblCountry.Text = "Name of the country:";

_tcCell.Controls.Add(_lblCountry);

_trRow.Controls.Add(_tcCell);

 

//## 2 ROW COUNTRY ##

//-- [TEXTBOX PART] --

_tcCell = new TableCell();

_tcCell.VerticalAlign = VerticalAlign.Top;

_txtCountryName = new TextBox();

_txtCountryName.ID = "_txtCountryName";

_txtCountryName.Width = Unit.Pixel(200);

_tcCell.Controls.Add(_txtCountryName);

_trRow.Controls.Add(_tcCell);

_tWeatherTable.Controls.Add(_trRow);

 

//## 3 ROW CITY ##

//-- [LABEL PART] --

_trRow = new TableRow();

_tcCell = new TableCell();

_tcCell.Style["padding-top"] = "7px";

_tcCell.VerticalAlign = VerticalAlign.Top;

_lblCity = new Label();

_lblCity.Text = "Name of the city:";

_tcCell.Controls.Add(_lblCity);

_trRow.Controls.Add(_tcCell);

 

//## 3 ROW CITY ##

//-- [TEXTBOX PART] --

_tcCell = new TableCell();

_tcCell.VerticalAlign = VerticalAlign.Top;

_txtZipCode = new TextBox();

_txtZipCode.ID = "_txtZipCode";

_txtZipCode.Width = Unit.Pixel(200);

_tcCell.Controls.Add(_txtZipCode);

_trRow.Controls.Add(_tcCell);

_tWeatherTable.Controls.Add(_trRow);

 

//## 4 ROW FORECAST Label ##

_trRow = new TableRow();

_tcCell = new TableCell();

_tcCell.ColumnSpan = 2;

_tcCell.VerticalAlign = VerticalAlign.Top;

_lblForecast = new Label();

_lblForecast.Text = "Forecast:";

_tcCell.Controls.Add(_lblForecast);

_trRow.Controls.Add(_tcCell);

_tWeatherTable.Controls.Add(_trRow);

 

//## 5 ROW FORECAST TEXTBOX ##

//-- [TEXTBOX PART] --

_trRow = new TableRow();

_tcCell = new TableCell();

_tcCell.ColumnSpan = 2;

_tcCell.VerticalAlign = VerticalAlign.Top;

_txtForecast = new TextBox();

_txtForecast.ID = "_txtForecast";

_txtForecast.Height = Unit.Pixel(100);

_txtForecast.Width = Unit.Pixel(200);

_txtForecast.TextMode = TextBoxMode.MultiLine;

_txtForecast.Wrap = true;

_txtForecast.Enabled = false;

_tcCell.Controls.Add(_txtForecast);

_trRow.Controls.Add(_tcCell);

_tWeatherTable.Controls.Add(_trRow);

 

//## 6 ROW Empty

_trRow = new TableRow();

_tcCell = new TableCell();

_trRow.Controls.Add(_tcCell);

 

//## 7 ROW Nice Submit button

_trRow = new TableRow();

_tcCell = new TableCell();

_cmdSendForecast = new Button();

_cmdSendForecast.Text = "Check weather forecast";

_cmdSendForecast.Width = 200;

_cmdSendForecast.Height = 30;

_cmdSendForecast.Click += new EventHandler(_cmdSendForecast_Click);

_tcCell.Controls.Add(_cmdSendForecast);

_trRow.Controls.Add(_tcCell);

_tWeatherTable.Controls.Add(_trRow);

 

this.Controls.Add(_tWeatherTable);

}

catch

{

LiteralControl Literal = new LiteralControl("<H5>Error uploading the webpart, please contact with your administrator</H5>");

}

}

 

void _cmdSendForecast_Click(object sender, EventArgs e)

{

WSWeather.Weather WS = new WSWeather.Weather();

WS.Credentials = System.Net.CredentialCache.DefaultNetworkCredentials;

WSWeather.ForecastReturn ReturnWeather = WS.GetCityForecastByZIP(_txtZipCode.Text);

 

_txtForecast.Text = "";

_txtForecast.Text += ReturnWeather.City + "\r\n";

_txtForecast.Text += ReturnWeather.State + "\r\n";

_txtForecast.Text += ReturnWeather.WeatherStationCity + "\r\n";

_txtForecast.Text += ReturnWeather.ResponseText + "\r\n";

 

foreach (WSWeather.Forecast item in ReturnWeather.ForecastResult)

{

_txtForecast.Text += item.Date + "\r\n";

_txtForecast.Text += item.Desciption + "\r\n";

_txtForecast.Text += item.ProbabilityOfPrecipiation + "\r\n";

_txtForecast.Text += item.Temperatures + "\r\n";

}

 

_txtForecast.Enabled = true;

}

}

}

 

 


Conclusion
Visual Studio will allow you to create anything with Web Parts but be aware you have what we call "Visual Web Parts", where you can design the forms in a ASP.NET way... in 5 minutes...