<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-5355607642937633928</id><updated>2011-11-28T01:09:00.915Z</updated><category term='Web Parts'/><category term='ASP.NET AJAX'/><category term='Web Part Connections'/><category term='OWL'/><category term='information architecture'/><category term='SemWeb'/><category term='SemWeb SQLite'/><category term='RDF'/><category term='topic maps'/><title type='text'>What I Think About...</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://waitink.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5355607642937633928/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://waitink.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Steve</name><uri>http://www.blogger.com/profile/11965922935328480623</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp3.blogger.com/_0uqP4s-XjUg/RjW1BDZI5cI/AAAAAAAAAAU/Yw7Z-g4efIw/s200/Picture+002.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>12</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-5355607642937633928.post-8809831208109425726</id><published>2008-10-10T09:01:00.017+01:00</published><updated>2008-10-25T07:28:14.059+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ASP.NET AJAX'/><category scheme='http://www.blogger.com/atom/ns#' term='Web Part Connections'/><category scheme='http://www.blogger.com/atom/ns#' term='Web Parts'/><title type='text'>Ajax Web Parts Part 4 - Dynamic Web Part Connections</title><content type='html'>&lt;span style="font-family:arial;"&gt;&lt;strong&gt;Posts In This Series: &lt;/strong&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;a href="http://waitink.blogspot.com/2008/06/aspnet-ajax-and-web-parts.html"&gt;&lt;span style="font-family:arial;"&gt;Introduction - ASP.NET AJAX and Web Parts&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family:arial;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;a href="http://waitink.blogspot.com/2008/06/ajax-web-parts-part-1-drag-and-drop.html"&gt;&lt;span style="font-family:arial;"&gt;Ajax Web Parts Part 1 - Drag and Drop&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;&lt;a href="http://waitink.blogspot.com/2008/09/ajax-web-parts-part-2-web-part.html"&gt;&lt;span style="font-family:arial;"&gt;Ajax Web Parts Part 2 - Web Part Connections&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href="http://waitink.blogspot.com/2008/10/ajax-web-parts-part-3-dynamic-web-parts.html"&gt;&lt;span style="font-family:arial;"&gt;Ajax Web Parts Part 3 - Dynamic Web Parts&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href="http://waitink.blogspot.com/2008/10/ajax-web-parts-part-4-dynamic-web-part.html"&gt;&lt;span style="font-family:arial;"&gt;Ajax Web Parts Part 4 - Dynamic Web Part Connections&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.whatithinkabout.net/download/tutorial/ajaxwebparts1.zip"&gt;&lt;span style="font-family:arial;"&gt;Download the source - Part 1&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.whatithinkabout.net/download/tutorial/ajaxwebparts2.zip"&gt;&lt;span style="font-family:arial;"&gt;Download the source - Part 2&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.whatithinkabout.net/download/tutorial/ajaxwebparts3.zip"&gt;&lt;span style="font-family:arial;"&gt;Download the source - Part 3&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.whatithinkabout.net/download/tutorial/ajaxwebparts4.zip"&gt;&lt;span style="font-family:arial;"&gt;Download the source - Part 4&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;font face="arial"&gt;&lt;strong&gt;Introduction&lt;/strong&gt;&lt;/font&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;font face="arial"&gt;Currently the dynamically created Web Parts (described in part 3) cannot be moved between zones. In addition, doing a postback results in more dynamically generated Web Parts appearing. This occurs because the Web Part Manager assigns each dynamically created Web Part a random ID when its &lt;em&gt;AddWebPart()&lt;/em&gt; function is called. To fix this problem we need a Web Part Manager that doesn’t assign random IDs and, luckily for us, &lt;/font&gt;&lt;a href="http://leedale.wordpress.com/2008/01/10/dynamically-adding-webparts-using-webpartmanagerinternals-class/"&gt;&lt;font face="arial"&gt;Lee Dale&lt;/font&gt;&lt;/a&gt;&lt;font face="arial"&gt; has created just what we’re after.&lt;br /&gt;&lt;br /&gt;Modifying Lee’s code slightly, so that it derives from the Preview DLL’s &lt;em&gt;WebPartManager&lt;/em&gt;, rather than the standard &lt;em&gt;WebPartManager&lt;/em&gt; (to ensure cross browser drag and drop), gives the following:&lt;br /&gt;&lt;br /&gt;&lt;pre class="c#" name="code"&gt;&lt;br /&gt;namespace AjaxWebParts.Controls&lt;br /&gt;{&lt;br /&gt;  public class DynamicWebPartManager &lt;br /&gt;  : Microsoft.Web.Preview.UI.Controls.WebParts.WebPartManager&lt;br /&gt;  {&lt;br /&gt;    public void AddDynamicWebPart(WebPart webPart,&lt;br /&gt;                Microsoft.Web.Preview.UI.Controls.WebParts.WebPartZone zone)&lt;br /&gt;    {&lt;br /&gt;      Internals.AddWebPart(webPart);&lt;br /&gt;      Internals.SetZoneID(webPart, zone.ID);&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;To use this new Web Part Manager we need to make the following changes:&lt;br /&gt;&lt;br /&gt;In our &lt;em&gt;DynamicWebParts&lt;/em&gt; class, make the following changes:&lt;br /&gt;&lt;br /&gt;1. change the &lt;em&gt;WebPartManager&lt;/em&gt; alias at the top of the line to become the following:&lt;br /&gt;&lt;br /&gt;&lt;pre class="c#" name="code"&gt;&lt;br /&gt;using WebPartManager = AjaxWebParts.Controls.DynamicWebPartManager;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;2. change the addition of the dynamically created Web Part to the Web Part Zone to use the &lt;em&gt;DynamicWebPartManger’s&lt;/em&gt; function. So the current&lt;br /&gt;&lt;br /&gt;&lt;pre class="c#" name="code"&gt;&lt;br /&gt;return itsManager.AddWebPart(genericWebPart, zone, 0);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;is replaced by:&lt;br /&gt;&lt;br /&gt;&lt;pre class="c#" name="code"&gt;&lt;br /&gt;itsManager.AddDynamicWebPart(genericWebPart, zone);&lt;br /&gt;return genericWebPart;  &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;In the default.aspx page the following changes are required:&lt;br /&gt;&lt;br /&gt;1. Add the following to the set of namespace registrations:&lt;br /&gt;&lt;br /&gt;&lt;pre class="c#" name="code"&gt;&lt;br /&gt;&lt;%@ Register Namespace="AjaxWebParts.Controls" TagPrefix="awp" %&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;2. Change the reference to the Web Part Manager from “cc1:WebPartManager” to “awp:DynamicWebPartManager”&lt;br /&gt;&lt;br /&gt;After these changes have been made everything should now work as it should: the dynamically created Web Parts should now be able to be dragged between zones and multiple Web Parts should not appear when postbacks occur. All that is required now is to implement the connection between the dynamic Web Parts.&lt;/font&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;font face="Arial"&gt;&lt;/font&gt; &lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;font face="Arial"&gt;&lt;/font&gt; &lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;font face="Arial"&gt;&lt;strong&gt;Creating Dynamic Web Part Connections&lt;/strong&gt;&lt;/font&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;font face="Arial"&gt;Once dynamic Web Parts exist, with non-random ID values, creating the connections between them is relatively straightforward. We simply need to get the connection point from each Web Part and then, if a connection can be made between the Web Parts, simply create a connection that joins the two connection points. &lt;/font&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt; &lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;font face="Arial"&gt;We therefore need to add a new function to our DynamicWebParts class to create the Web Part connection, as follows:&lt;/font&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;font face="Arial"&gt;&lt;/font&gt; &lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;font face="Arial"&gt;  &lt;br /&gt;&lt;br /&gt;&lt;textarea class="xml" name="code" rows="10" cols="60"&gt;&lt;br /&gt;/// &lt;summary&gt;&lt;br /&gt;/// Form a connection between the suplied provider and consumer web parts&lt;br /&gt;/// &lt;/summary&gt; &lt;br /&gt;/// &lt;param name="aProvider"&gt;the provider web part&lt;/param&gt;&lt;br /&gt;/// &lt;param name="aConsumer"&gt;the consumer web part&lt;/param&gt; &lt;br /&gt;public void FormWebPartConnection(WebPart aProvider, WebPart aConsumer)&lt;br /&gt;{&lt;br /&gt;  if (aProvider != null &amp;amp;&amp;amp; aConsumer != null)&lt;br /&gt;  {&lt;br /&gt;    // get the connection points collections for each web part&lt;br /&gt;    ProviderConnectionPointCollection providerConnectionPoints = itsManager.GetProviderConnectionPoints(aProvider);&lt;br /&gt;    ConsumerConnectionPointCollection consumerConnectionPoints = itsManager.GetConsumerConnectionPoints(aConsumer);&lt;br /&gt;&lt;br /&gt;    // each web part only has a single connection point, so take the first one of each&lt;br /&gt;    ProviderConnectionPoint provPoint = providerConnectionPoints[0];&lt;br /&gt;    ConsumerConnectionPoint connPoint = consumerConnectionPoints[0];&lt;br /&gt;&lt;br /&gt;    if (provPoint != null &amp;amp;&amp;amp; connPoint != null)&lt;br /&gt;    {&lt;br /&gt;      // check that these web parts can be connected&lt;br /&gt;      if (itsManager.CanConnectWebParts(aProvider, provPoint, aConsumer, connPoint))&lt;br /&gt;      {&lt;br /&gt;        // create the connection&lt;br /&gt;        WebPartConnection newconn = new WebPartConnection();&lt;br /&gt;        newconn.ID = "AutoConnection";&lt;br /&gt;        newconn.ConsumerID = aConsumer.ID;&lt;br /&gt;        newconn.ProviderID = aProvider.ID;&lt;br /&gt;        itsManager.StaticConnections.Add(newconn);&lt;br /&gt;      }&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/textarea&gt;&lt;br /&gt;&lt;/font&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt; &lt;/div&gt;&lt;br /&gt;&lt;div&gt; &lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;font face="Arial"&gt;Finally we need to call this function from our default.aspx.cs code-behind file. The &lt;em&gt;Page_Init()&lt;/em&gt; function now becomes:&lt;/font&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;&lt;font face="Arial"&gt;  &lt;br /&gt;&lt;br /&gt;&lt;textarea class="xml" name="code" rows="10" cols="60"&gt;&lt;br /&gt;protected void Page_Init(object sender, EventArgs e)&lt;br /&gt;{&lt;br /&gt;  // create an instance of the dynamic web part class&lt;br /&gt;  DynamicWebParts dynamicWebParts = new DynamicWebParts(this);&lt;br /&gt;  dynamicWebParts.Manager = WebPartManager1;&lt;br /&gt;&lt;br /&gt;  // create 2 web parts&lt;br /&gt;  WebPart provider = dynamicWebParts.AddWebPartToZone("WebPartZone1", &lt;br /&gt;                                                      "UserControls/Provider.ascx", &lt;br /&gt;                                                      "Dynamic Provider");&lt;br /&gt;  WebPart consumer = dynamicWebParts.AddWebPartToZone("WebPartZone2", &lt;br /&gt;                                                      "UserControls/Consumer.ascx", &lt;br /&gt;                                                      "Dynamic Consumer");&lt;br /&gt;&lt;br /&gt;  // create a connection between the web parts&lt;br /&gt;  dynamicWebParts.FormWebPartConnection(provider, consumer);&lt;br /&gt;}&lt;br /&gt;&lt;/textarea&gt;&lt;br /&gt;&lt;/font&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;font face="Arial"&gt;&lt;/font&gt; &lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;font face="Arial"&gt;Now, when the Web Page is run, the dynamically generated Web Parts will be connected. Typing a value into the dynamic provider's text box and clicking the button will result in the value being displayed in the dynamically created consumer Web Part.&lt;/font&gt;&lt;/p&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;strong&gt;Creating Dynamic Web Part Zones&lt;br /&gt;&lt;/strong&gt;&lt;br /&gt;Now that we can dynamically create Web Parts, lets move on to create the rest of the page dynamically, starting with the Web Part Zones.&lt;br /&gt;This is very straightforward – it’s simply a case of creating an instance of a WebPartZone and adding it to the page (note that the WebPartZone that gets created is from the Preview DLL, due to the alias that was declared).&lt;br /&gt;&lt;br /&gt;The DynamicWebParts class  member function therefore appears as follows:&lt;br /&gt;&lt;br /&gt;&lt;textarea class="xml" name="code" rows="10" cols="60"&gt;&lt;br /&gt;/// &lt;summary&gt;&lt;br /&gt;/// Create a new web part zone and give it the supplied title&lt;br /&gt;/// (the title is also used as the ID of the zone)&lt;br /&gt;/// &lt;/summary&gt;&lt;br /&gt;/// &lt;param name="aZoneTitle"&gt;&lt;/param&gt;&lt;br /&gt;/// &lt;returns&gt;&lt;/returns&gt;&lt;br /&gt;public WebPartZone CreateWebPartZone(string aZoneTitle)&lt;br /&gt;{&lt;br /&gt;  WebPartZone webPartZone = new WebPartZone();&lt;br /&gt;  webPartZone.ID = aZoneTitle.Replace(" ", "");&lt;br /&gt;  webPartZone.HeaderText = aZoneTitle;&lt;br /&gt;  return webPartZone;&lt;br /&gt;} &lt;br /&gt;&lt;/textarea&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Similarly, we can create the WebPartManager:&lt;br /&gt;&lt;br /&gt;&lt;textarea class="xml" name="code" rows="10" cols="60"&gt;&lt;br /&gt;/// &lt;summary&gt;&lt;br /&gt;/// Create a new dynamic web part manager&lt;br /&gt;/// &lt;/summary&gt;&lt;br /&gt;/// &lt;returns&gt;&lt;/returns&gt;&lt;br /&gt;public DynamicWebPartManager CreateWebPartManager()&lt;br /&gt;{&lt;br /&gt;  DynamicWebPartManager webPartManager = new DynamicWebPartManager();&lt;br /&gt;  webPartManager.ID = "WebPartManager1";&lt;br /&gt;  return webPartManager;&lt;br /&gt;}&lt;br /&gt;&lt;/textarea&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;and the UpdatePanel:&lt;br /&gt;&lt;br /&gt;&lt;textarea class="xml" name="code" rows="10" cols="60"&gt;&lt;br /&gt;/// &lt;summary&gt;&lt;br /&gt;/// Create a new update panel with the supplied ID&lt;br /&gt;/// &lt;/summary&gt;&lt;br /&gt;/// &lt;param name="aID"&gt;&lt;/param&gt;&lt;br /&gt;/// &lt;returns&gt;&lt;/returns&gt;&lt;br /&gt;public UpdatePanel CreateUpdatePanel( string aID )&lt;br /&gt;{   &lt;br /&gt;  UpdatePanel updatePanel = new UpdatePanel();&lt;br /&gt;  updatePanel.ID = aID;&lt;br /&gt;  return updatePanel;&lt;br /&gt;}&lt;br /&gt;&lt;/textarea&gt;&lt;br /&gt;&lt;br /&gt;Since all the page components can now be created dynamically, the static components in the page markup are no longer required. This page therefore simplifies down to:&lt;br /&gt;&lt;br /&gt;&lt;textarea class="xml" name="code" rows="10" cols="60"&gt;&lt;br /&gt;  &lt;form id="form1" runat="server"&gt;&lt;br /&gt;    &lt;div&gt;&lt;br /&gt;      &lt;h2&gt;Click and hold the Web Part title to drag it to the second Web Part Zone:&lt;/h2&gt;    &lt;br /&gt;      &lt;asp:button id="ResetButton" runat="server" text="Reset" onclick="ResetButton_Click"&gt;          &lt;br /&gt;      &lt;asp:scriptmanager id="ScriptManager1" runat="server"&gt;   &lt;br /&gt;      &lt;asp:placeholder id="PlaceHolder1" runat="server"&gt;&lt;br /&gt;    &lt;/div&gt;&lt;br /&gt;  &lt;/form&gt;&lt;br /&gt;&lt;/textarea&gt;&lt;br /&gt;&lt;br /&gt;Note that a PlaceHolder component has been added to give us somewhere to add our dynamic components.&lt;br /&gt;&lt;br /&gt;In the Default.aspx.cs code behind file the Page_Init function now becomes:&lt;br /&gt;&lt;br /&gt;&lt;textarea class="xml" name="code" rows="10" cols="60"&gt;&lt;br /&gt;protected void Page_Init(object sender, EventArgs e)&lt;br /&gt;{&lt;br /&gt;  // create an instance of the dynamic web part class&lt;br /&gt;  DynamicWebParts dynamicWebParts = new DynamicWebParts(this);&lt;br /&gt;&lt;br /&gt;  // create a new update panel&lt;br /&gt;  UpdatePanel updatePanel = dynamicWebParts.CreateUpdatePanel("DynamicUpdatePanel");&lt;br /&gt;&lt;br /&gt;  // add the web part manager to the update panel&lt;br /&gt;  updatePanel.ContentTemplateContainer.Controls.Add(dynamicWebParts.Manager);&lt;br /&gt;&lt;br /&gt;  // add 2 web part zones to the update panel&lt;br /&gt;  WebPartZone dynamicZone1 = dynamicWebParts.CreateWebPartZone("Dynamic Zone 1");&lt;br /&gt;  updatePanel.ContentTemplateContainer.Controls.Add(dynamicZone1);&lt;br /&gt;  WebPartZone dynamicZone2 = dynamicWebParts.CreateWebPartZone("Dynamic Zone 2");&lt;br /&gt;  updatePanel.ContentTemplateContainer.Controls.Add(dynamicZone2);&lt;br /&gt;&lt;br /&gt;  // add the update panel to the page&lt;br /&gt;  PlaceHolder1.Controls.Add(updatePanel);&lt;br /&gt;&lt;br /&gt;  // create 2 web parts&lt;br /&gt;  WebPart provider = dynamicWebParts.AddWebPartToZone(dynamicZone1.ID, &lt;br /&gt;                                                      "UserControls/Provider.ascx", &lt;br /&gt;                                                      "Dynamic Provider");&lt;br /&gt;  WebPart consumer = dynamicWebParts.AddWebPartToZone(dynamicZone2.ID, &lt;br /&gt;                                                      "UserControls/Consumer.ascx", &lt;br /&gt;                                                      "Dynamic Consumer");&lt;br /&gt;&lt;br /&gt;  // create a connection between the web parts&lt;br /&gt;  dynamicWebParts.FormWebPartConnection(provider, consumer);&lt;br /&gt;}&lt;br /&gt;&lt;/textarea&gt;&lt;br /&gt;&lt;br /&gt;And, since the page markup no longer defines a WebPartManager, this needs to obtained dynamically when needed. So the Page_load function now changes to become:&lt;br /&gt;&lt;br /&gt;&lt;textarea class="xml" name="code" rows="10" cols="60"&gt;&lt;br /&gt;protected void Page_Load(object sender, EventArgs e)&lt;br /&gt;{&lt;br /&gt;  if (!Page.IsPostBack)&lt;br /&gt;  {&lt;br /&gt;    // set the display mode to "Design" to allow drag and drop&lt;br /&gt;    WebPartManager manager = WebPartManager.GetCurrentWebPartManager(this);&lt;br /&gt;    if (manager != null)&lt;br /&gt;    {&lt;br /&gt;      WebPartDisplayMode mode = manager.SupportedDisplayModes["Design"];&lt;br /&gt;      if (mode != null)&lt;br /&gt;      {&lt;br /&gt;        manager.DisplayMode = mode;&lt;br /&gt;      }&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/textarea&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.whatithinkabout.net/tutorials/part4/default.aspx"&gt;Click here to see this in action&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Putting this all together results in an ASP.NET AJAX page, featuring 2 Web Part Zones and 2 dragable, connected, Web Parts. Everything has now been created dynamically and is therefore just what’s required for populating tab pages.&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5355607642937633928-8809831208109425726?l=waitink.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://waitink.blogspot.com/feeds/8809831208109425726/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5355607642937633928&amp;postID=8809831208109425726' title='11 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5355607642937633928/posts/default/8809831208109425726'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5355607642937633928/posts/default/8809831208109425726'/><link rel='alternate' type='text/html' href='http://waitink.blogspot.com/2008/10/ajax-web-parts-part-4-dynamic-web-part.html' title='Ajax Web Parts Part 4 - Dynamic Web Part Connections'/><author><name>Steve</name><uri>http://www.blogger.com/profile/11965922935328480623</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp3.blogger.com/_0uqP4s-XjUg/RjW1BDZI5cI/AAAAAAAAAAU/Yw7Z-g4efIw/s200/Picture+002.jpg'/></author><thr:total>11</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5355607642937633928.post-4389407850966641337</id><published>2008-10-07T21:05:00.037+01:00</published><updated>2008-10-25T07:21:23.466+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ASP.NET AJAX'/><category scheme='http://www.blogger.com/atom/ns#' term='Web Parts'/><title type='text'>Ajax Web Parts Part 3 - Dynamic Web Parts</title><content type='html'>&lt;span style="font-family:arial;"&gt;&lt;strong&gt;Posts In This Series: &lt;/strong&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;a href="http://waitink.blogspot.com/2008/06/aspnet-ajax-and-web-parts.html"&gt;&lt;span style="font-family:arial;"&gt;Introduction - ASP.NET AJAX and Web Parts&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family:arial;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;a href="http://waitink.blogspot.com/2008/06/ajax-web-parts-part-1-drag-and-drop.html"&gt;&lt;span style="font-family:arial;"&gt;Ajax Web Parts Part 1 - Drag and Drop&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;&lt;a href="http://waitink.blogspot.com/2008/09/ajax-web-parts-part-2-web-part.html"&gt;&lt;span style="font-family:arial;"&gt;Ajax Web Parts Part 2 - Web Part Connections&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href="http://waitink.blogspot.com/2008/10/ajax-web-parts-part-3-dynamic-web-parts.html"&gt;&lt;span style="font-family:arial;"&gt;Ajax Web Parts Part 3 - Dynamic Web Parts&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href="http://waitink.blogspot.com/2008/10/ajax-web-parts-part-4-dynamic-web-part.html"&gt;&lt;span style="font-family:arial;"&gt;Ajax Web Parts Part 4 - Dynamic Web Part Connections&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.whatithinkabout.net/download/tutorial/ajaxwebparts1.zip"&gt;&lt;span style="font-family:arial;"&gt;Download the source - Part 1&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.whatithinkabout.net/download/tutorial/ajaxwebparts2.zip"&gt;&lt;span style="font-family:arial;"&gt;Download the source - Part 2&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.whatithinkabout.net/download/tutorial/ajaxwebparts3.zip"&gt;&lt;span style="font-family:arial;"&gt;Download the source - Part 3&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.whatithinkabout.net/download/tutorial/ajaxwebparts4.zip"&gt;&lt;span style="font-family:arial;"&gt;Download the source - Part 4&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;&lt;strong&gt;Introduction&lt;/strong&gt; &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;&lt;br /&gt;So far, in this series on Ajax Web Parts, all the components have been created at design time. The Web Part Zones, the Web Parts themselves, and the connections between them, have all been added statically to the page markup.&lt;br /&gt;&lt;br /&gt;In order to achieve our ultimate goal, of movable Web Parts in a user created tab framework, we now need to change to using dynamically created components:&lt;br /&gt;&lt;/span&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;&lt;span style="font-family:arial;"&gt;Web Part Zones need to be dynamically created so that, eventually, they can be used to populate each tab page.&lt;/span&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;span style="font-family:Arial;"&gt;Web Parts and their connections need to be generated at run time to populate the Web Part Zones. &lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;span style="font-family:arial;"&gt;Therefore, we will now investigate how the previous project can be changed to add these dynamic components.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Creating Dynamic Page Components&lt;br /&gt;&lt;/strong&gt;&lt;br /&gt;The easiest way to create dynamic page components is by copying static components – that is, firstly create the required components in the ASP.NET markup and then, once this is working, copy the structure to create the same components dynamically.&lt;br /&gt;We will use this approach to replace the Web Part components that were statically created in the last posts, with a new class that can dynamically generate the same components.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;A Dynamic Web Part Class&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;Rather than simply adding everything to the web form’s code-behind file, we will create a class to create the dynamic components. So first of all, we need to add a new class to the project as follows:&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;span style="font-family:arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;&lt;span style="font-family:arial;"&gt;Right-click on the project’s “app_code” node and choose “Add New Item”. &lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Arial;"&gt;In the dialog that appears choose to add a new class and give this the name “DynamicWebParts.cs”.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Arial;"&gt;Once the class has been added to the project, change the constructor so that it takes an instance of the page and add a property to hold a reference to this value. This is required to give us something to add our components to. The page comes from the System.Web.UI namespace, so a “using” line needs to be added for this. &lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;span style="font-family:arial;"&gt;&lt;br /&gt;At this stage the class should look as follows:&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;textarea class="xml" name="code" rows="10" cols="60"&gt;&lt;br /&gt;using System.Web.UI;&lt;br /&gt;&lt;br /&gt;public class DynamicWebParts&lt;br /&gt;{&lt;br /&gt;  /// &lt;summary&gt;&lt;br /&gt;  /// the page to which components will be added&lt;br /&gt;  /// &lt;/summary&gt;&lt;br /&gt;  private Page itsPage;&lt;br /&gt;&lt;br /&gt;  public DynamicWebParts(Page aPage)&lt;br /&gt;  {&lt;br /&gt;    itsPage = aPage;    &lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/textarea&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;In addition to a page, to which the Web Parts can be added, the other thing that is required to create dynamic Web Parts is a Web Part Manager. For now we will simply pass through the static Web Part Manager that exists on the page and store this into a property as follows:&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;/p&gt;&lt;pre class="c#" name="code"&gt;&lt;br /&gt;&lt;br /&gt;  private WebPartManager itsManager;&lt;br /&gt;  public WebPartManager Manager&lt;br /&gt;  {&lt;br /&gt;    set { itsManager = value; }&lt;br /&gt;  }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="font-family:arial;"&gt;&lt;strong&gt;Namespace Selection&lt;br /&gt;&lt;/strong&gt;&lt;br /&gt;If you remember from the previous posts, to get cross-browser drag and drop support we needed to use the Web Part Manager from the Microsoft Web Preview release. Therefore we need to use the same version here in our class. Therefore, at the top of the page the following “using” statement is required:&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;pre class="c#" name="code"&gt;&lt;br /&gt;using Microsoft.Web.Preview.UI.Controls.WebParts;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;&lt;br /&gt;This namespace is used to give us the Web Part Manager and Web Part Zones needed for cross-browser drag and drop. &lt;/span&gt;&lt;span style="font-family:arial;"&gt;However, the Web Parts themselves still come from the standard System.Web.UI.WebControls.WebParts namespace. Therefore, to avoid a clash, we need to explicitly state that the Web Part Manager and Web Part Zones come from Preview DLL. This can be done by specifying the full namespace every time we refer to the WebPartManager and WebPartZones. However this is rather cumbersome.&lt;br /&gt;&lt;br /&gt;A more elegant approach is to add an alias so that both WebPartManager and WebPartZone will always reference the Preview DLL's versions. To do this the following lines should be added:&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="c#" name="code"&gt;&lt;br /&gt;using WebPartManager = Microsoft.Web.Preview.UI.Controls.WebParts.WebPartManager;&lt;br /&gt;using WebPartZone = Microsoft.Web.Preview.UI.Controls.WebParts.WebPartZone;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;&lt;br /&gt;(Another approach that can be used to specify which DLL to use, when referring to a control, is to use tag mapping in the web.config file. However, this will only work for controls declared in markup and is therefore not appropriate for dynamically created controls. See &lt;a href="http://blogs.neudesic.com/blogs/david_barkol/archive/2006/11/07/631.aspx"&gt;David Barkol's blog&lt;/a&gt; for details)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Dynamic Web Parts&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;Everything is now in place to allow us to dynamically add some Web Parts to the page. As a first step, let’s replace the static Provider and Consumer Web Parts that were created in the last part of the series. Both of these Web Parts were formed by taking User Controls and adding them to Web Part Zones to create Web Parts. We will use a similar approach when dynamically generating the Web Parts. The function to take a User Control and add it to a Web Part Zone is shown below:&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;textarea class="xml" name="code" rows="10" cols="60"&gt;&lt;br /&gt;/// &lt;summary&gt;&lt;br /&gt;/// Create a web part from the specified control and add it to the specified zone.&lt;br /&gt;/// &lt;/summary&gt;&lt;br /&gt;/// &lt;param name="aZoneName"&gt;the zone to which the control will be added&lt;/param&gt;&lt;br /&gt;/// &lt;param name="aControlName"&gt;the virtual path to the control file&lt;/param&gt;&lt;br /&gt;/// &lt;param name="aWebPartTitle"&gt;the title to give the newly created Web Part&lt;/param&gt;&lt;br /&gt;/// &lt;returns&gt;&lt;/returns&gt;&lt;br /&gt;public WebPart AddWebPartToZone(string aZoneName, &lt;br /&gt;                                string aControlPath, &lt;br /&gt;                                string aWebPartTitle)&lt;br /&gt;{&lt;br /&gt;  // load the control from the supplied path&lt;br /&gt;  Control control = itsPage.LoadControl(aControlPath);&lt;br /&gt;&lt;br /&gt;  // remove spaces from the control's path to form the ID&lt;br /&gt;  control.ID = aWebPartTitle.Replace(" ", "");&lt;br /&gt;&lt;br /&gt;  // find the specified web part zone in the manager's list of zones&lt;br /&gt;  WebPartZone zone = itsManager.Zones[aZoneName] as WebPartZone;&lt;br /&gt;  if (zone != null)&lt;br /&gt;  {&lt;br /&gt;    GenericWebPart genericWebPart = itsManager.CreateWebPart(control);&lt;br /&gt;    genericWebPart.Title = aWebPartTitle;&lt;br /&gt;&lt;br /&gt;    // add the web part to the zone&lt;br /&gt;    return itsManager.AddWebPart(genericWebPart, zone, 0);            &lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  // the web part could not be added to the zone&lt;br /&gt;  return null;&lt;br /&gt;}&lt;br /&gt;&lt;/textarea&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;&lt;br /&gt;Notice how the steps required to dynamically add a Web Part closely resemble those used to statically add one:&lt;br /&gt;&lt;br /&gt;· once again a User Control is loaded (using the Page’s &lt;em&gt;LoadControl&lt;/em&gt; function)&lt;br /&gt;· a Web Part is then created (by calling the Web Part Manager’s &lt;em&gt;CreateWebPart&lt;/em&gt; function) and added to a Zone (using the Web Part Manager’s &lt;em&gt;AddWebPart&lt;/em&gt; function).&lt;br /&gt;&lt;br /&gt;Other points to note here are:&lt;br /&gt;1. We’ve created a unique ID for control by simply taking the title supplied for the Web Part and removing any spaces from it.&lt;br /&gt;2. To get the Web Part Zone we need to search the Web Part Manager’s list of Zones until the supplied name is found.&lt;br /&gt;3. The Web Part Manager’s AddWebPart function takes a copy of the supplied Web Part and returns a reference to the copy. Therefore it is this that needs to be returned to get access to the Web Part that actually exists on the page (rather than the Web Part that was created using CreateWebPart).&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;All that’s required now is to actually use this new function to programmatically generate some Web Parts. Therefore, back in the Default.aspx.cs code behind file, add the following:&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;textarea class="xml" name="code" rows="10" cols="60"&gt;&lt;br /&gt;protected void Page_Init(object sender, EventArgs e)&lt;br /&gt;{&lt;br /&gt;  // create an instance of the dynamic web part class&lt;br /&gt;  DynamicWebParts dynamicWebParts = new DynamicWebParts(this);&lt;br /&gt;  dynamicWebParts.Manager = WebPartManager1;&lt;br /&gt;&lt;br /&gt;  // create 2 web parts&lt;br /&gt;  dynamicWebParts.AddWebPartToZone("WebPartZone1", &lt;br /&gt;                                   "UserControls/Provider.ascx", &lt;br /&gt;                                   "Dynamic Provider");&lt;br /&gt;  dynamicWebParts.AddWebPartToZone("WebPartZone2", &lt;br /&gt;                                   "UserControls/Consumer.ascx", &lt;br /&gt;                                   "Dynamic Consumer");&lt;br /&gt;}&lt;br /&gt;&lt;/textarea&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;&lt;br /&gt;This creates an instance of our new class, sets the Web Part Manager to the one that exists in the markup and then creates 2 Web Parts – a Provider, which is added to the first Web Part Zone and a Consumer, which is added to the second Web Part Zone.&lt;br /&gt;&lt;br /&gt;Running this should give the following output:&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;a href="http://2.bp.blogspot.com/_0uqP4s-XjUg/SOvNHm5K9DI/AAAAAAAAACQ/A5ERqYFUi3g/s1600-h/DynamicWebParts.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://2.bp.blogspot.com/_0uqP4s-XjUg/SOvNHm5K9DI/AAAAAAAAACQ/A5ERqYFUi3g/s400/DynamicWebParts.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5254518920840934450" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.whatithinkabout.net/tutorials/part3/default.aspx"&gt;Click here to see this in action&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Note, that at this stage, the dynamic Web Parts cannot be moved between zones. Trying to move them results in more Web Parts appearing. This is a result of the way in which the standard Web Part Manager assigns IDs to the Web Parts and we'll look at this more closely in the next post. &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;Both statically and dynamically created Web Parts now exist on the page. The statically created Web Parts have a connection between them; any text typed into the input field of the provider Web Part will appear in the label of the consumer Web Part when the button is clicked. The dynamically created Web Parts are not yet connected and, as we'll see in the next part of this series, creating this connection is not as straightforward as it should be (this seems to be a recurring theme!). In addition, drag and drop doesn't yet work for the dynamically created Web Parts - this is something that will also be resolved in the next post. &lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5355607642937633928-4389407850966641337?l=waitink.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://waitink.blogspot.com/feeds/4389407850966641337/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5355607642937633928&amp;postID=4389407850966641337' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5355607642937633928/posts/default/4389407850966641337'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5355607642937633928/posts/default/4389407850966641337'/><link rel='alternate' type='text/html' href='http://waitink.blogspot.com/2008/10/ajax-web-parts-part-3-dynamic-web-parts.html' title='Ajax Web Parts Part 3 - Dynamic Web Parts'/><author><name>Steve</name><uri>http://www.blogger.com/profile/11965922935328480623</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp3.blogger.com/_0uqP4s-XjUg/RjW1BDZI5cI/AAAAAAAAAAU/Yw7Z-g4efIw/s200/Picture+002.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_0uqP4s-XjUg/SOvNHm5K9DI/AAAAAAAAACQ/A5ERqYFUi3g/s72-c/DynamicWebParts.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5355607642937633928.post-2147554065616063984</id><published>2008-09-15T22:56:00.036+01:00</published><updated>2008-10-25T07:22:19.896+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ASP.NET AJAX'/><category scheme='http://www.blogger.com/atom/ns#' term='Web Part Connections'/><category scheme='http://www.blogger.com/atom/ns#' term='Web Parts'/><title type='text'>Ajax Web Parts Part 2 - Web Part Connections</title><content type='html'>&lt;span style="font-family:arial;"&gt;&lt;strong&gt;Posts In This Series: &lt;/strong&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;a href="http://waitink.blogspot.com/2008/06/aspnet-ajax-and-web-parts.html"&gt;&lt;span style="font-family:arial;"&gt;Introduction - ASP.NET AJAX and Web Parts&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family:arial;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;a href="http://waitink.blogspot.com/2008/06/ajax-web-parts-part-1-drag-and-drop.html"&gt;&lt;span style="font-family:arial;"&gt;Ajax Web Parts Part 1 - Drag and Drop&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;&lt;a href="http://waitink.blogspot.com/2008/09/ajax-web-parts-part-2-web-part.html"&gt;&lt;span style="font-family:arial;"&gt;Ajax Web Parts Part 2 - Web Part Connections&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href="http://waitink.blogspot.com/2008/10/ajax-web-parts-part-3-dynamic-web-parts.html"&gt;&lt;span style="font-family:arial;"&gt;Ajax Web Parts Part 3 - Dynamic Web Parts&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href="http://waitink.blogspot.com/2008/10/ajax-web-parts-part-4-dynamic-web-part.html"&gt;&lt;span style="font-family:arial;"&gt;Ajax Web Parts Part 4 - Dynamic Web Part Connections&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.whatithinkabout.net/download/tutorial/ajaxwebparts1.zip"&gt;&lt;span style="font-family:arial;"&gt;Download the source - Part 1&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.whatithinkabout.net/download/tutorial/ajaxwebparts2.zip"&gt;&lt;span style="font-family:arial;"&gt;Download the source - Part 2&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.whatithinkabout.net/download/tutorial/ajaxwebparts3.zip"&gt;&lt;span style="font-family:arial;"&gt;Download the source - Part 3&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.whatithinkabout.net/download/tutorial/ajaxwebparts4.zip"&gt;&lt;span style="font-family:arial;"&gt;Download the source - Part 4&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;&lt;strong&gt;Introduction&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;The first part of this series introduced the components required to perform basic Web Part drag and drop.&lt;br /&gt;&lt;br /&gt;In that post a simple Web Part was created from the Calendar component. This was then used to illustrate how a Web Part could be moved between Web Part Zones that had been created at design time.&lt;br /&gt;&lt;br /&gt;Although the Calendar component was useful for illustrating how a Web Part can be moved between zones, it doesn’t really give a realistic view of how Web Parts would be used in a real-world situation. For this we need something slightly more complex – a pair of Web Parts that communicate via a connection.&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:arial;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.whatithinkabout.net/tutorials/part2/default.aspx"&gt;Click here to see what will be created&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;&lt;strong&gt;Web Part Connections&lt;br /&gt;&lt;/strong&gt;&lt;br /&gt;Two Web Parts are required to form a Web Part Connection; a Provider Web Part to initiate the connection and a Consumer Web Part to receive the connection.&lt;br /&gt;&lt;br /&gt;For our example, both of these Web Parts can be formed by creating a standard User Control and then adding it to a WebPartZone (by dragging it from the Solution Explorer window and dropping it into the WebPartZone in the Design view of the Web Form).&lt;br /&gt;&lt;br /&gt;For simplicity the Provider part consists of only 2 items: a text box to enter a string and a button to send the string to the Consumer part. So, in the markup, the Provider is given by:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;textarea class="xml" name="code" rows="10" cols="60"&gt;&lt;br /&gt;&lt;%@ Control Language="C#" &lt;br /&gt;            AutoEventWireup="true" &lt;br /&gt;            CodeFile="Provider.ascx.cs" &lt;br /&gt;            Inherits="User_Controls_Provider" %&gt;&lt;br /&gt;&lt;asp:TextBox ID="TextBox1" runat="server" /&gt; &lt;br /&gt;&lt;asp:Button ID="Button1" runat="server" Text="Button" /&gt;&lt;br /&gt;&lt;/textarea&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;The Consumer only contains a label, to display the string that is received from the Provider. Its markup is therefore as follows:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;textarea class="xml" name="code" rows="10" cols="60"&gt;&lt;br /&gt;&lt;%@ Control Language="C#" &lt;br /&gt;            AutoEventWireup="true" &lt;br /&gt;            CodeFile="Consumer.ascx.cs" &lt;br /&gt;            Inherits="User_Controls_Consumer" %&gt;&lt;br /&gt;&lt;span&gt;Message: &lt;/span&gt;&lt;br /&gt;&lt;asp:Label ID="Label1" runat="server" Font-Bold="true" &gt;&lt;/asp:Label&gt;&lt;br /&gt;&lt;/textarea&gt;&lt;br /&gt;&lt;p /&gt;&lt;br /&gt;&lt;br /&gt;To allow these Web Parts to communicate we must now define the connection between them. This is done by creating an interface that specifies the type and name of parameters that may be passed between the Web Parts.&lt;br /&gt;&lt;br /&gt;In our case we are only sending a string (the text entered into the text box) from the Provider to the Consumer. The interface (in the sample download code this is defined in IWebPartInterface.cs within the App_Code directory) therefore defines that the Consumer can get a single string, called Message, from the Provider and appears as follows:&lt;br /&gt;&lt;br /&gt;&lt;pre class="c#" name="code"&gt;&lt;br /&gt;public interface IWebPartInterface&lt;br /&gt;{&lt;br /&gt;  string Message { get;}&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p /&gt;&lt;br /&gt;&lt;br /&gt;In the code-behind the User Controls must specify the part they play in the connection.&lt;br /&gt;&lt;br /&gt;The Provider, as its name suggests, must provide the interface. It does this by having a function that returns the interface. This function is identified by using the ConnectionProvider attribute. Each end of the connection is referred to as a Connection Point. The ConnectionProvider attribute takes a parameter that assigns a name to the connection point (for our provider we’ve radically called it “ProviderConnectionPoint”).&lt;br /&gt;&lt;br /&gt;Since, in our case, the Provider class inherits from the IWebPartInterface the member function can simply return an instance of its class (i.e. it returns this).&lt;br /&gt;&lt;br /&gt;Finally, the Provider needs to actually return some data to give to the consumer. In our case this is simply the value that gets entered into the text box and, from the interface we’ve defined, we know that this value should be labelled as Message.&lt;br /&gt;&lt;br /&gt;Therefore the complete code-behind of the Provider class is as follows:&lt;br /&gt;&lt;br /&gt;&lt;pre class="c#" name="code"&gt;&lt;br /&gt;public partial class User_Controls_Provider&lt;br /&gt;: System.Web.UI.UserControl, IWebPartInterface&lt;br /&gt;{&lt;br /&gt;  [ConnectionProvider("ProviderConnectionPoint")]&lt;br /&gt;  public IWebPartInterface GetProviderData()&lt;br /&gt;  {&lt;br /&gt;    return this;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  public string Message&lt;br /&gt;  {&lt;br /&gt;    get { return TextBox1.Text; }&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p /&gt;&lt;br /&gt;&lt;br /&gt;In the Consumer the ConnectionConsumer attribute is used to specify that the SetProviderData method is used to get the interface and store it into a local variable.&lt;br /&gt;&lt;br /&gt;Once the connection has been established between the Provider and the Consumer, the Consumer can use it to set the text of its label and this is done at the pre-render stage of the page lifecycle.&lt;br /&gt;&lt;br /&gt;&lt;pre class="c#" name="code"&gt;&lt;br /&gt;public partial class User_Controls_Consumer&lt;br /&gt;: System.Web.UI.UserControl&lt;br /&gt;{&lt;br /&gt;  IWebPartInterface itsProvider = null;&lt;br /&gt;&lt;br /&gt;  [ConnectionConsumer("ConsumerConnectionPoint")]&lt;br /&gt;  public void SetProviderData(IWebPartInterface aProviderData)&lt;br /&gt;  {&lt;br /&gt;    itsProvider = aProviderData;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  protected override void OnPreRender(EventArgs e)&lt;br /&gt;  {&lt;br /&gt;    if (itsProvider != null)&lt;br /&gt;    {&lt;br /&gt;      Label1.Text = itsProvider.Message;&lt;br /&gt;    }&lt;br /&gt;    base.OnPreRender(e);&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p /&gt;&lt;br /&gt;&lt;br /&gt;Finally, the connection needs to be specified in the Web Part Manager. This needs to define which Web Part acts as the provider of the connection and which as the consumer. So, for the Web Parts we’ve defined, the markup appears as follows:&lt;br /&gt;&lt;br /&gt;&lt;textarea class="xml" name="code" rows="10" cols="60"&gt;&lt;br /&gt;&lt;cc1:WebPartManager ID="WebPartManager1" runat="server"&gt;&lt;br /&gt;  &lt;StaticConnections&gt;&lt;br /&gt;    &lt;asp:WebPartConnection ID="WebPartConnection1" &lt;br /&gt;                           ProviderID="Provider1" &lt;br /&gt;                           ConsumerID="Consumer1" /&gt;                    &lt;br /&gt;  &lt;/StaticConnections&gt;        &lt;br /&gt;&lt;/cc1:WebPartManager&gt;&lt;br /&gt;&lt;/textarea&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Putting this all together results in a Web Page consisting of 2 Web Parts that can be dragged between the Web Part Zones and that can communicate. Entering some text into the provider Web Part’s text box and clicking on the button results in the text appearing in the consumer Web Part, as shown below:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://1.bp.blogspot.com/_0uqP4s-XjUg/SM7gRJKw5WI/AAAAAAAAACI/KzpjYzbMqCw/s1600-h/WebPartConnections.png"&gt;&lt;img id="BLOGGER_PHOTO_ID_5246377201056671074" style="DISPLAY: block; MARGIN: 0px auto 10px; CURSOR: hand; TEXT-ALIGN: center" alt="" src="http://1.bp.blogspot.com/_0uqP4s-XjUg/SM7gRJKw5WI/AAAAAAAAACI/KzpjYzbMqCw/s400/WebPartConnections.png" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.whatithinkabout.net/tutorials/part2/default.aspx"&gt;Click here to see this in action&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;&lt;strong&gt;Conclusion&lt;br /&gt;&lt;/strong&gt;&lt;br /&gt;This post has expanded our Web Part example to show how 2 Web Parts can communicate using a Web Part Connection. Everything has still been created statically at design time. In the next post I’ll look at how these Web Parts and Web Part Zones can be created dynamically to form a tab framework.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Links&lt;/strong&gt; &lt;/p&gt;&lt;br /&gt;&lt;p&gt;More information on Web Part Connections can be found at the following:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.carlosag.net/Articles/WebParts/connectionsTutorial.aspx"&gt;http://www.carlosag.net/Articles/WebParts/connectionsTutorial.aspx&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;span style="font-family:Arial;"&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.webparts.webpartconnection.aspx"&gt;http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.webparts.webpartconnection.aspx&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="font-family:Arial;"&gt;&lt;/span&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="font-family:Arial;"&gt;&lt;/span&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5355607642937633928-2147554065616063984?l=waitink.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://waitink.blogspot.com/feeds/2147554065616063984/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5355607642937633928&amp;postID=2147554065616063984' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5355607642937633928/posts/default/2147554065616063984'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5355607642937633928/posts/default/2147554065616063984'/><link rel='alternate' type='text/html' href='http://waitink.blogspot.com/2008/09/ajax-web-parts-part-2-web-part.html' title='Ajax Web Parts Part 2 - Web Part Connections'/><author><name>Steve</name><uri>http://www.blogger.com/profile/11965922935328480623</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp3.blogger.com/_0uqP4s-XjUg/RjW1BDZI5cI/AAAAAAAAAAU/Yw7Z-g4efIw/s200/Picture+002.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_0uqP4s-XjUg/SM7gRJKw5WI/AAAAAAAAACI/KzpjYzbMqCw/s72-c/WebPartConnections.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5355607642937633928.post-4418766730830901463</id><published>2008-06-07T16:03:00.089+01:00</published><updated>2008-12-09T00:14:04.142Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='ASP.NET AJAX'/><category scheme='http://www.blogger.com/atom/ns#' term='Web Parts'/><title type='text'>Ajax Web Parts Part 1 - Drag and Drop</title><content type='html'>&lt;span style="font-family:arial;"&gt;&lt;strong&gt;Posts In This Series: &lt;/strong&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;a href="http://waitink.blogspot.com/2008/06/aspnet-ajax-and-web-parts.html"&gt;&lt;span style="font-family:arial;"&gt;Introduction - ASP.NET AJAX and Web Parts&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family:arial;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;a href="http://waitink.blogspot.com/2008/06/ajax-web-parts-part-1-drag-and-drop.html"&gt;&lt;span style="font-family:arial;"&gt;Ajax Web Parts Part 1 - Drag and Drop&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;&lt;a href="http://waitink.blogspot.com/2008/09/ajax-web-parts-part-2-web-part.html"&gt;&lt;span style="font-family:arial;"&gt;Ajax Web Parts Part 2 - Web Part Connections&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href="http://waitink.blogspot.com/2008/10/ajax-web-parts-part-3-dynamic-web-parts.html"&gt;&lt;span style="font-family:arial;"&gt;Ajax Web Parts Part 3 - Dynamic Web Parts&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href="http://waitink.blogspot.com/2008/10/ajax-web-parts-part-4-dynamic-web-part.html"&gt;&lt;span style="font-family:arial;"&gt;Ajax Web Parts Part 4 - Dynamic Web Part Connections&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.whatithinkabout.net/download/tutorial/ajaxwebparts1.zip"&gt;&lt;span style="font-family:arial;"&gt;Download the source - Part 1&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.whatithinkabout.net/download/tutorial/ajaxwebparts2.zip"&gt;&lt;span style="font-family:arial;"&gt;Download the source - Part 2&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.whatithinkabout.net/download/tutorial/ajaxwebparts3.zip"&gt;&lt;span style="font-family:arial;"&gt;Download the source - Part 3&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.whatithinkabout.net/download/tutorial/ajaxwebparts4.zip"&gt;&lt;span style="font-family:arial;"&gt;Download the source - Part 4&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;div align="justify"&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;&lt;br /&gt;&lt;strong&gt;Introduction&lt;/strong&gt;&lt;br /&gt;In this post I'm going to describe the very basic steps required to get Web Parts drag and drop up and running from scratch. This will use a Calendar item, added to a Web Part Zone, to make a generic Web Part. This is the standard demonstration of Web Parts that has been used in a multitude of other Web Part tutorials - it's replication here is purely to get the basic components in place before moving on to other, more advanced, topics.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.whatithinkabout.net/tutorials/part1/default.aspx"&gt;Click here to see what will be created&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Required Components&lt;/strong&gt;&lt;br /&gt;At present, due to the evolving nature of the subject, there are a large number of different versions of ASP.NET and its related components. These components can appear in releases with titles such as “futures”, “extensions” and “Community Technology Previews (CTPs)". As a result, one of the major challenges when working with ASP.NET is finding the appropriate set of components to use – each release appears to have its own unique fixes and quirks and, consequently, it can be difficult to find the correct combination to achieve the desired results. Hopefully ASP.NET 4.0 will fix all the bugs and tie everything together!&lt;br /&gt;&lt;br /&gt;Therefore, when working with ASP.NET AJAX and Web Parts we will require more than the standard ASP.NET framework; extra components are needed either to add functionality or to fix problems in the current release. To begin with we will start with a standard system and add these extra components as required.&lt;br /&gt;&lt;br /&gt;Initially, to follow along with the code in these posts, you will require 2 things:&lt;br /&gt;&lt;br /&gt;1. Visual Studio 2008 or &lt;a href="http://www.microsoft.com/express/download/"&gt;Visual Web Developer Express &lt;/a&gt;&lt;br /&gt;2. The &lt;a href="http://www.asp.net/AJAX/downloads/"&gt;ASP.NET AJAX Control Toolkit&lt;/a&gt; &lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;&lt;br /&gt;&lt;strong&gt;Creating the initial project&lt;/strong&gt;&lt;br /&gt;From the file menu, select "New Web Site" and then choose "&lt;em&gt;AJAX Control Toolkit WebSite&lt;/em&gt;" from the list of available options:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;p align="center"&gt;&lt;a href="http://3.bp.blogspot.com/_0uqP4s-XjUg/SFAnW--pxhI/AAAAAAAAABc/ZolFSiYnqBo/s1600-h/ProjectSelection.png"&gt;&lt;img id="BLOGGER_PHOTO_ID_5210708044684051986" style="CURSOR: hand" alt="" src="http://3.bp.blogspot.com/_0uqP4s-XjUg/SFAnW--pxhI/AAAAAAAAABc/ZolFSiYnqBo/s400/ProjectSelection.png" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;&lt;br /&gt;&lt;div align="justify"&gt;&lt;br /&gt;&lt;strong&gt;Adding the Web Part Components&lt;/strong&gt;&lt;br /&gt;Now we need to add a few components to the page to give us something to work with.&lt;br /&gt;From the toolbox, when in design or split mode, drag the following items onto the default.aspx page:&lt;br /&gt;From the WebParts toolbox tab:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;1 x Web Part Manager&lt;/li&gt;&lt;li&gt;2 x Web Part Zones&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;Then, from the Standard toolbox tab, drag a Calendar component and drop it into the first Web Part Zone - this will automatically convert the Calendar into a generic Web Part.&lt;br /&gt;&lt;br /&gt;After the addition of these items, the default.aspx page should look as shown below (it also includes a ToolkitScriptManager which is there as a consequence of the initial project choice we made. At present this isn't being used, but will be required later.)&lt;br /&gt;&lt;/div&gt;&lt;p align="center"&gt;&lt;a href="http://4.bp.blogspot.com/_0uqP4s-XjUg/SFApq9He40I/AAAAAAAAABk/dhKDLwu6j7M/s1600-h/WebPartZones1.png"&gt;&lt;img id="BLOGGER_PHOTO_ID_5210710586804855618" style="CURSOR: hand" alt="" src="http://4.bp.blogspot.com/_0uqP4s-XjUg/SFApq9He40I/AAAAAAAAABk/dhKDLwu6j7M/s400/WebPartZones1.png" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;br /&gt;&lt;div align="justify"&gt;&lt;p&gt;Before we can actually run this project, and get the drag and drop behaviour that we’re after, we need to make a small addition to the code behind.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;strong&gt;Display Modes and Personalization&lt;/strong&gt;&lt;br /&gt;If you were to run the project in its current state, you would see one of two things - either you would get a database error, or you would see the Calendar component, but would be unable to change its position.&lt;/p&gt;&lt;p&gt;The reason why drag and drop is not yet possible is due to the display mode setting of the Web Part Manager. Display modes are used to define what operations can be performed on the Web Parts; the default display mode is "Browse" and this is the mode currently used by our page. In this mode it's only possible to do basic operations, such as minimize and close; it's not possible to perform drag and drop. To enable drag and drop requires, at a minimum, the display mode to be changed to "Display".&lt;/p&gt;&lt;p&gt;However, things aren't quite so simple. When web parts are moved on the page it's necessary to save the information about their new positions so that they can be restored to these locations the next time the page is rendered. This information is stored into a personalization table in a database. Thus, to enable the more advanced features of Web Parts, such as drag and drop, requires a database to be available. If you haven't yet got a database the easiest option is to download &lt;a href="http://www.microsoft.com/sql/editions/express/default.mspx"&gt;SQL Server Express&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;To set the Web Part Manager’s display mode, add the following code into the Default.aspx.cs file: &lt;/span&gt;&lt;/p&gt;&lt;/div&gt;&lt;br /&gt;&lt;pre class="c#" name="code"&gt;&lt;br /&gt;protected void Page_Load(object sender, EventArgs e)&lt;br /&gt;{&lt;br /&gt;  if (!Page.IsPostBack)&lt;br /&gt;  {&lt;br /&gt;    // set the display mode to "Design" to allow drag and drop&lt;br /&gt;    WebPartDisplayMode mode = WebPartManager1.SupportedDisplayModes["Design"];&lt;br /&gt;    if (mode != null)&lt;br /&gt;    {&lt;br /&gt;      WebPartManager1.DisplayMode = mode;&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="font-family:arial;"&gt;If this is the first time that the page is being rendered (i.e. not a postback), then this code checks the Web Part Manager to see if the "Design" mode is contained in its list of supported display modes. If it is, then it sets this to be the current display mode.&lt;/span&gt;&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;We now have everything in place to enable drag and drop. Press F5 to run the project and hopefully you should see the following output:&lt;br /&gt;&lt;/p&gt;&lt;p align="center"&gt;&lt;a href="http://3.bp.blogspot.com/_0uqP4s-XjUg/SFNt7RO4LmI/AAAAAAAAABs/Nu7Aiiiz7sw/s1600-h/WebPartZones2.png"&gt;&lt;img id="BLOGGER_PHOTO_ID_5211630058803310178" style="CURSOR: hand" alt="" src="http://3.bp.blogspot.com/_0uqP4s-XjUg/SFNt7RO4LmI/AAAAAAAAABs/Nu7Aiiiz7sw/s400/WebPartZones2.png" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;span style="font-family:arial;"&gt;If you have run this using Internet Explorer, drag and drop functionality should now be enabled:&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;- when the cursor is hovered over the title bar it should change to the directional cursor &lt;/span&gt;&lt;a href="http://3.bp.blogspot.com/_0uqP4s-XjUg/SFNwdGyJ03I/AAAAAAAAAB0/dQ8SYgaNSNA/s1600-h/WebPartsCursor2.png"&gt;&lt;span style="font-family:arial;"&gt;&lt;img id="BLOGGER_PHOTO_ID_5211632839137284978" style="CURSOR: hand" alt="" src="http://3.bp.blogspot.com/_0uqP4s-XjUg/SFNwdGyJ03I/AAAAAAAAAB0/dQ8SYgaNSNA/s320/WebPartsCursor2.png" border="0" /&gt;&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family:arial;"&gt;and clicking and holding on the Calendar web part's title bar should enable it to be selected and dragged to the second Web Part Zone.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;However, with the current release of ASP.NET 3.5, if you have run this in a browser other than IE (e.g. Firefox), then the chances are that the drag and drop won't be working - to fix this we need to make another modification.&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;&lt;br /&gt;&lt;strong&gt;Web Part Drag and Drop in Firefox&lt;/strong&gt;&lt;br /&gt;For some reason Microsoft have chosen not to include the fix for Firefox (and other non-IE) browsers in the latest releases of the ASP.NET framework. To get things working in all browsers requires the download of the &lt;/span&gt;&lt;a href="http://www.asp.net/Downloads/futures/"&gt;Microsoft ASP.NET Futures (July 2007) Release &lt;/a&gt;- obviously this is a technology preview release and is therefore not supported for production sites - however, the alternative is to not have drag and drop support for all non-Microsoft browsers, so you need to choose which of these is the most important to you.&lt;br /&gt;&lt;br /&gt;Once this futures release has been downloaded, its components need to be added to your Visual Studio toolbox. To do this, you need to do the following steps:&lt;br /&gt;&lt;ol&gt;&lt;br /&gt;&lt;li&gt;In the toolbox window, move the cursor into the bottom tab pane and right click to bring up the context menu. From this choose "Add Tab" and create a new tab for the futures release.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;From within this new tab pane, select "Choose Items.." from the right-click context menu.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;In the dialog that appears choose browse and locate the futures DLL (mine was downloaded to C:\Program Files\Microsoft ASP.NET\ASP.NET Futures July 2007\v1.3.61025\3.5).Click on OK once all the components of this DLL have been selected. All these components should then be added to the new tab of the toolbox, as shown below.&lt;/li&gt;&lt;br /&gt;&lt;/ol&gt;&lt;br /&gt;&lt;/span&gt;&lt;p align="center"&gt;&lt;a href="http://4.bp.blogspot.com/_0uqP4s-XjUg/SFQlj3C-m-I/AAAAAAAAACA/m9KoDzahfoQ/s1600-h/Toolbox.png"&gt;&lt;img id="BLOGGER_PHOTO_ID_5211831966776597474" style="CURSOR: hand" alt="" src="http://4.bp.blogspot.com/_0uqP4s-XjUg/SFQlj3C-m-I/AAAAAAAAACA/m9KoDzahfoQ/s400/Toolbox.png" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p align="justify"&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;As you can see, the toolbox now contains both a &lt;em&gt;WebPartManager&lt;/em&gt; and &lt;em&gt;WebPartZone&lt;/em&gt; that have been added from the Futures release. All we need to do now are replace the standard versions of these that we'd added already with these new Futures versions and that should fix our Web Parts drag and drop for all browsers.&lt;/span&gt;&lt;/p&gt;&lt;p align="justify"&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;&lt;br /&gt;&lt;strong&gt;AJAX Enabling The Web Parts&lt;/strong&gt;&lt;br /&gt;We've only one thing left to do, and that's remove the annoying postbacks that occur when the Web Parts are moved. To do this we simply need to wrap everything in an UpdatePanel from the AJAX Extensions tab of the toolbox. We already have a ScriptManager present from the AJAX Control Toolbox - however, for consistency, I've chosen to remove this and replace it with the standard version. Once everything is in place, the body of my default.aspx file now looks as follows:&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;textarea class="xml" name="code" rows="10" cols="60"&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;  &lt;form id="form1" runat="server"&gt;&lt;br /&gt;&lt;br /&gt;  &lt;div&gt;&lt;br /&gt;&lt;br /&gt;    &lt;asp:scriptmanager id="ScriptManager1" runat="server"&gt;&lt;br /&gt;&lt;br /&gt;    &lt;/asp:ScriptManager&gt;&lt;br /&gt;&lt;br /&gt;    &lt;asp:updatepanel id="UpdatePanel1" runat="server"&gt;&lt;br /&gt;&lt;br /&gt;      &lt;contenttemplate&gt;&lt;br /&gt;&lt;br /&gt;        &lt;cc1:webpartmanager id="WebPartManager1" runat="server"&gt;&lt;br /&gt;&lt;br /&gt;        &lt;/cc1:WebPartManager&gt;&lt;br /&gt;&lt;br /&gt;        &lt;cc1:webpartzone id="WebPartZone1" runat="server"&gt;&lt;br /&gt;&lt;br /&gt;          &lt;zonetemplate&gt;&lt;br /&gt;&lt;br /&gt;            &lt;asp:calendar id="Calendar1" runat="server"&gt;&lt;/asp:Calendar&gt;&lt;br /&gt;&lt;br /&gt;          &lt;/zonetemplate&gt;&lt;br /&gt;&lt;br /&gt;        &lt;/cc1:WebPartZone&gt;&lt;br /&gt;&lt;br /&gt;        &lt;cc1:webpartzone id="WebPartZone2" runat="server"&gt;&lt;br /&gt;&lt;br /&gt;        &lt;/cc1:WebPartZone&gt;&lt;br /&gt;&lt;br /&gt;      &lt;/contenttemplate&gt;&lt;br /&gt;&lt;br /&gt;    &lt;/asp:UpdatePanel&gt;&lt;br /&gt;&lt;br /&gt;  &lt;/div&gt;&lt;br /&gt;&lt;br /&gt;  &lt;/form&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/textarea&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;&lt;br /&gt;&lt;p align="justify"&gt;&lt;br /&gt;&lt;a href="http://www.whatithinkabout.net/tutorials/part1/default.aspx"&gt;Click here to see this in action&lt;/a&gt;.&lt;br /&gt;&lt;/p&gt;&lt;p align="justify"&gt;&lt;br /&gt;This concludes the introduction to Web Parts. In future posts I'll expand apon this simple project to show how Web Parts can be combined with both the ASP.NET AJAX framework and the ASP.NET AJAX Toolkit Tab component.&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5355607642937633928-4418766730830901463?l=waitink.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://waitink.blogspot.com/feeds/4418766730830901463/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5355607642937633928&amp;postID=4418766730830901463' title='23 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5355607642937633928/posts/default/4418766730830901463'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5355607642937633928/posts/default/4418766730830901463'/><link rel='alternate' type='text/html' href='http://waitink.blogspot.com/2008/06/ajax-web-parts-part-1-drag-and-drop.html' title='Ajax Web Parts Part 1 - Drag and Drop'/><author><name>Steve</name><uri>http://www.blogger.com/profile/11965922935328480623</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp3.blogger.com/_0uqP4s-XjUg/RjW1BDZI5cI/AAAAAAAAAAU/Yw7Z-g4efIw/s200/Picture+002.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_0uqP4s-XjUg/SFAnW--pxhI/AAAAAAAAABc/ZolFSiYnqBo/s72-c/ProjectSelection.png' height='72' width='72'/><thr:total>23</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5355607642937633928.post-1666403982075492116</id><published>2008-06-05T09:06:00.016+01:00</published><updated>2008-10-25T07:23:10.456+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ASP.NET AJAX'/><category scheme='http://www.blogger.com/atom/ns#' term='Web Parts'/><title type='text'>ASP.NET AJAX and Web Parts</title><content type='html'>&lt;span style="font-family:arial;"&gt;&lt;strong&gt;Posts In This Series: &lt;/strong&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;a href="http://waitink.blogspot.com/2008/06/aspnet-ajax-and-web-parts.html"&gt;&lt;span style="font-family:arial;"&gt;Introduction - ASP.NET AJAX and Web Parts&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family:arial;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;a href="http://waitink.blogspot.com/2008/06/ajax-web-parts-part-1-drag-and-drop.html"&gt;&lt;span style="font-family:arial;"&gt;Ajax Web Parts Part 1 - Drag and Drop&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;&lt;a href="http://waitink.blogspot.com/2008/09/ajax-web-parts-part-2-web-part.html"&gt;&lt;span style="font-family:arial;"&gt;Ajax Web Parts Part 2 - Web Part Connections&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href="http://waitink.blogspot.com/2008/10/ajax-web-parts-part-3-dynamic-web-parts.html"&gt;&lt;span style="font-family:arial;"&gt;Ajax Web Parts Part 3 - Dynamic Web Parts&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href="http://waitink.blogspot.com/2008/10/ajax-web-parts-part-4-dynamic-web-part.html"&gt;&lt;span style="font-family:arial;"&gt;Ajax Web Parts Part 4 - Dynamic Web Part Connections&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.whatithinkabout.net/download/tutorial/ajaxwebparts1.zip"&gt;&lt;span style="font-family:arial;"&gt;Download the source - Part 1&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.whatithinkabout.net/download/tutorial/ajaxwebparts2.zip"&gt;&lt;span style="font-family:arial;"&gt;Download the source - Part 2&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.whatithinkabout.net/download/tutorial/ajaxwebparts3.zip"&gt;&lt;span style="font-family:arial;"&gt;Download the source - Part 3&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.whatithinkabout.net/download/tutorial/ajaxwebparts4.zip"&gt;&lt;span style="font-family:arial;"&gt;Download the source - Part 4&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Introduction&lt;/strong&gt;&lt;br /&gt;&lt;div align="justify"&gt;In my quest to create a database capable of storing anything and everything (see earlier posts), my attention over the last few months has turned from the back end to the front end UI. &lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div align="justify"&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;One obvious way to display a set of disparate information is to use a &lt;a href="http://en.wikipedia.org/wiki/Web_Portal"&gt;Web Portal&lt;/a&gt; style framework - a set of widgets (small window components) within a tab framework - the tabs can be used to represent the general categories and each widget can be used to display a sub-set of information for that category. Since I’m coming from an ASP.NET background, &lt;a href="http://en.wikipedia.org/wiki/Web_part"&gt;Web Parts&lt;/a&gt; sounded like a perfect fit for the implementation of these widgets, and the &lt;a href="http://www.asp.net/AJAX/AjaxControlToolkit/Samples/Tabs/Tabs.aspx"&gt;Tab Control&lt;/a&gt;, from the ASP.NET AJAX Toolkit, sounded like the ideal way to wrap all these Web Parts together. &lt;/span&gt;&lt;/div&gt;&lt;span style="font-family:arial;"&gt;&lt;div align="justify"&gt;&lt;br /&gt;In theory, the creation of this Web Portal sounded like it would be a breeze - just drop a few Web Part Zones onto the Tab Control, and populate them with the Web Parts to show information from each category. In reality, as usual, things turned out to be not quite so simple. Over the next few posts I’m going to describe the creation of a simple version of this Web Portal and highlight the problems, and workarounds, involved with each stage. &lt;/div&gt;&lt;div align="justify"&gt;&lt;br /&gt;To start I’ll be describing the very basics of getting Web Parts up and running, before moving onto some more complex issues, such as dynamically generating the Web Parts and creating new tab pages on demand. &lt;/div&gt;&lt;div align="justify"&gt; &lt;/div&gt;&lt;div align="justify"&gt;The content of these posts won’t really provide any information that can’t be found elsewhere, however I hope that by bringing it all together, into a single place, that this will be of benefit to some - certainly it would have helped me. As mentioned, most of the stuff concerning the dynamic creation of Web Parts can be found in other locations and, when I can remember where I obtained information from, I’ll try and reference these other sources. One things that these posts won’t be are in-depth overviews of either Web Parts or ASP.NET AJAX - a basic knowledge of these is assumed - if you’d like more information on either of these topics, I can recommend the books shown in the reading list.&lt;br /&gt; &lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5355607642937633928-1666403982075492116?l=waitink.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://waitink.blogspot.com/feeds/1666403982075492116/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5355607642937633928&amp;postID=1666403982075492116' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5355607642937633928/posts/default/1666403982075492116'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5355607642937633928/posts/default/1666403982075492116'/><link rel='alternate' type='text/html' href='http://waitink.blogspot.com/2008/06/aspnet-ajax-and-web-parts.html' title='ASP.NET AJAX and Web Parts'/><author><name>Steve</name><uri>http://www.blogger.com/profile/11965922935328480623</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp3.blogger.com/_0uqP4s-XjUg/RjW1BDZI5cI/AAAAAAAAAAU/Yw7Z-g4efIw/s200/Picture+002.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5355607642937633928.post-3204865900412935471</id><published>2007-07-03T12:56:00.000+01:00</published><updated>2007-07-03T15:16:11.895+01:00</updated><title type='text'>Using SemWeb with MySQL</title><content type='html'>Getting SemWeb to work with MySQL is pretty much the same as for SQLite (see the last post). Again, using the news.rdf file from Mozilla, the command line to enter data into the MySQL database now becomes:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;rdfstorage news.rdf --out "mysql:rdf:database=news;username=test"&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;This assumes that a new database (schema) called "news" has been created in MySQL and that a user "test" exists that doesn't require a password (both these things can be done using the MySQL Administrator UI).&lt;br /&gt;&lt;br /&gt;Initially running this command line in the installed version of the&lt;em&gt; SemWeb\bin&lt;/em&gt; directory results in the following error being generated:&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#006600;"&gt;&lt;em&gt;System.IO.FileNotFoundException: Could not load file or assembly 'MySql.Data, Version=1.0.8.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d' or one of its dependencies. The system cannot find the file specified.&lt;/em&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;This error means that the MySQL.Data.dll is missing, so the first step is to get this from &lt;a href="http://dev.mysql.com/downloads/connector/net/5.0.html"&gt;MySQL ADO.Net Data Provider 5.0.7&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;After placing this DLL in the bin directory and running the command line again, the following error will appear:&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#006600;"&gt;&lt;em&gt;System.IO.FileLoadException: Could not load file or assembly 'MySql.Data, Version=1.0.8.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)&lt;/em&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;In this case the important part is the "&lt;em&gt;manifest definition does not match the assembly reference&lt;/em&gt;" bit - as happened with the SQLite DLL, this MySQL DLL is newer than the version that was used to build the SemWeb.MySQLStore.dll and so the 2 DLLs are incompatible. We need to rebuild this SemWeb DLL.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;The steps to do this are as follows:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Open the SemWeb solution in Visual Studio&lt;/li&gt;&lt;li&gt;Add a new project of type "Class Library" and called "SemWeb.MySQLStore"&lt;/li&gt;&lt;li&gt;Delete the default "Class1.cs" that gets added to the project &lt;/li&gt;&lt;li&gt;Choose to add an existing item to the project and pick "MySQLStore.cs" from the SemWeb\src directory&lt;/li&gt;&lt;li&gt;Add a reference to the "MySQL.Data.dll " that should already be in the SemWeb\bin directory&lt;/li&gt;&lt;li&gt;Add a reference to the SemWeb project&lt;/li&gt;&lt;li&gt;In the project properties, set the output path to the SemWeb\bin directory&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;These are the exact same steps that were required for the SQLiteStore DLL (although obviously referencing different files). However, building the MySQLStore DLL now results in the following compiler error:&lt;/p&gt;&lt;p&gt;&lt;em&gt;&lt;span style="color:#006600;"&gt;The type or namespace name 'MySqlConnection' could not be found (are you missing a using directive or an assembly reference?) &lt;/span&gt;&lt;/em&gt;&lt;/p&gt;&lt;p&gt;To fix this error the following needs to be added to the top of the MySQLStore.cs file:&lt;/p&gt;&lt;p&gt;&lt;em&gt;&lt;span style="color:#3333ff;"&gt;using MySql.Data.MySqlClient;&lt;/span&gt;&lt;/em&gt;&lt;/p&gt;&lt;em&gt;&lt;span style="color:#3333ff;"&gt;&lt;/span&gt;&lt;/em&gt;&lt;p&gt;&lt;br /&gt;So the complete set of using directives at the top of the file should now appear as: &lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;em&gt;&lt;span style="color:#3333ff;"&gt;using System;&lt;br /&gt;using System.Collections;&lt;br /&gt;using MySql.Data.MySqlClient;&lt;br /&gt;using System.Data;&lt;br /&gt;&lt;/span&gt;&lt;/em&gt;&lt;br /&gt;The project should now rebuild successfully and the new SemWeb.MySQLStore.dll should now appear in the SemWeb\bin directory.&lt;/p&gt;&lt;p&gt;Unfortunately this still isn't the end of the process - running the command line again results in the following error:&lt;/p&gt;&lt;p&gt;&lt;em&gt;&lt;span style="color:#006600;"&gt;MySql.Data.MySqlClient.MySqlException: Table 'news.rdf_statements' doesn't exist&lt;/span&gt;&lt;/em&gt;&lt;/p&gt;&lt;p&gt;The DLL is now ok, its just that the database that its creating has a few problems; inspecting the database in MySQL Administrator shows that the "rdf_literals" and "rdf_entities" tables have been created but the "rdf_statements" table hasn't been made.&lt;/p&gt;&lt;p&gt;Setting the SEMWEB_DEBUG_SQL environment variable (type "&lt;span style="font-family:courier new;"&gt;set SEMWEB_DEBUG_SQL=1&lt;/span&gt;" at the command prompt) and then running the command line again generates some debug information (alternatively put a break point on the "&lt;br /&gt;CreateTable" function in the SQLStore.cs file and run the program in the debugger, after first setting up the command line arguments in the project properties). The error generated is:&lt;/p&gt;&lt;p&gt;&lt;em&gt;&lt;span style="color:#006600;"&gt;System.FormatException: Input string was not in a correct format.&lt;/span&gt;&lt;/em&gt;&lt;/p&gt;&lt;p&gt;This is caused by the SemWeb database "Open" function (from MySQLStore.cs) querying the version of the database and then trying to set this into the .NET Version class; however, the version string returned from my version of MySQL is "5.0.41-community-nt" and this doesn't match with the expected .NET version string format, which is expecting only integers seperated by a period character ('.') - hence an error is thrown on the first call to "Open" and so the creation of the first database table ("rdf_statements") fails.&lt;/p&gt;&lt;p&gt;To fix this I've just put a try-catch around the setting of the version string, so basically I just ignore when the version can't be set.&lt;/p&gt;&lt;br /&gt;&lt;pre style="BORDER-RIGHT: #999999 1px dashed; PADDING-RIGHT: 5px; BORDER-TOP: #999999 1px dashed; PADDING-LEFT: 5px; FONT-SIZE: 12px; PADDING-BOTTOM: 5px; OVERFLOW: auto; BORDER-LEFT: #999999 1px dashed; WIDTH: 100%; COLOR: #000000; LINE-HEIGHT: 14px; PADDING-TOP: 5px; BORDER-BOTTOM: #999999 1px dashed; FONT-FAMILY: Andale Mono, Lucida Console, Monaco, fixed, monospace; BACKGROUND-COLOR: #eee"&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;private void Open()&lt;br /&gt;{&lt;br /&gt;  if (connection != null)&lt;br /&gt;    return;&lt;br /&gt;  MySqlConnection c = new MySqlConnection(connectionString);&lt;br /&gt;  c.Open();&lt;br /&gt;  connection = c; // only set field if open was successful&lt;br /&gt;&lt;br /&gt;  using (IDataReader reader = RunReader(@"show variables like 'version'"))&lt;br /&gt;  {&lt;br /&gt;    reader.Read();&lt;br /&gt;    try&lt;br /&gt;    {&lt;br /&gt;      version = new Version(reader.GetString(1));&lt;br /&gt;    }&lt;br /&gt;    catch(Exception e)&lt;br /&gt;    {&lt;br /&gt;      if (Debug) Console.Error.WriteLine(e.Message);&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Finally, rebuilding the SemWeb DLL and re-running the command line successfully adds the RDF to the database:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;news.rdf 0m0s, 81 statements, 1728 st/sec&lt;br /&gt;Total Time: 0m2s, 81 statements, 30 st/sec&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5355607642937633928-3204865900412935471?l=waitink.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://waitink.blogspot.com/feeds/3204865900412935471/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5355607642937633928&amp;postID=3204865900412935471' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5355607642937633928/posts/default/3204865900412935471'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5355607642937633928/posts/default/3204865900412935471'/><link rel='alternate' type='text/html' href='http://waitink.blogspot.com/2007/07/using-semweb-with-mysql.html' title='Using SemWeb with MySQL'/><author><name>Steve</name><uri>http://www.blogger.com/profile/11965922935328480623</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp3.blogger.com/_0uqP4s-XjUg/RjW1BDZI5cI/AAAAAAAAAAU/Yw7Z-g4efIw/s200/Picture+002.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5355607642937633928.post-2395972602161835059</id><published>2007-07-02T17:15:00.000+01:00</published><updated>2007-07-02T18:19:26.692+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='SemWeb SQLite'/><title type='text'>Using SemWeb with SQLite</title><content type='html'>As mentioned in the previous post I've had a few problems getting SemWeb, the C# RDF library, to persist data to a database. Here I describe the steps I've had to follow to get things working.&lt;br /&gt;&lt;br /&gt;I've been using Visual Studio on Windows - I suspect that these problems may not exist when using Mono on Linux.&lt;br /&gt;&lt;br /&gt;I'm using the following versions:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Visual Studio 2005&lt;/li&gt;&lt;li&gt;&lt;a href="http://razor.occams.info/code/semweb/"&gt;SemWeb 1.0&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://dev.mysql.com/downloads/mysql/5.0.html"&gt;MySQL Server 5.0&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://dev.mysql.com/downloads/connector/net/5.0.html"&gt;MySQL ADO.Net Data Provider 5.0.7&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.mono-project.com/Downloads"&gt;Mono 1.2.4&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.sqlite.org/download.html"&gt;SQLite 3.4.0&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;strong&gt;SQLite&lt;/strong&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;Following the approach described in the SemWeb documentation, I first tried to set up a database connection to a SQLite database.&lt;br /&gt;&lt;br /&gt;Following the SemWeb documentation I performed the following steps:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Placed the "sqlite3.dll" (from the SQLite download) into my windows System32 directory&lt;/li&gt;&lt;li&gt;Added the "Mono.Data.SqliteClient.dll" from the the Mono install directory "Mono-1.2.4\lib\mono\2.0" into my SemWeb\bin directory&lt;/li&gt;&lt;li&gt;Downloaded the sample RDF file from &lt;a href="http://www.mozilla.org/news.rdf"&gt;http://www.mozilla.org/news.rdf&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Entered the specified command line at a DOS prompt in the SemWeb\bin directory:&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;rdfstorage.exe news.rdf --out "sqlite:rdf:Uri=file:news.sqlite;version=3"&lt;/span&gt;&lt;/li&gt;&lt;li&gt;Pressed return and stood well back.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;I was greeted with the following:&lt;/p&gt;&lt;p&gt;&lt;em&gt;System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---&gt; System.IO.FileLoadException: The located assembly's manifest definition with the name 'Mono.Data.SqliteClient' does not match the assembly reference.&lt;/em&gt;&lt;/p&gt;&lt;p&gt;Basically my Mono SQLite adapter was newer than the version that the SemWeb.SqliteStore.dll had been built with.&lt;/p&gt;&lt;p&gt;Unfortunately the SemWeb Visual Studio solution doesn't come with a SemWeb.SqliteStore project, so the following steps are required:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Open the SemWeb solution in Visual Studio&lt;/li&gt;&lt;li&gt;Add a new project of type "Class Library" and called "SemWeb.SqliteStore"&lt;/li&gt;&lt;li&gt;Delete the default "Class1.cs" that gets added to the project &lt;/li&gt;&lt;li&gt;Choose to add an existing item to the project and pick "SQLiteStore.cs" from the SemWeb\src directory&lt;/li&gt;&lt;li&gt;Add a reference to the "Mono.Data.SqliteClient.dll" that should already be in the SemWeb\bin directory&lt;/li&gt;&lt;li&gt;Add a reference to the SemWeb project&lt;/li&gt;&lt;li&gt;In the project properties, set the output path to the SemWeb\bin directory&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;I also rebuilt the SemWeb and RDFStorage projects (after setting their output directories to the bin directory). Once built I re-ran the command line and this time obtained the expected result:&lt;/p&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;news.rdf 0m0s, 81 statements, 1036 st/sec&lt;br /&gt;Total Time: 0m1s, 81 statements, 42 st/sec&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Courier New;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Courier New;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:+0;"&gt;Next time I'll describe the steps I've had to follow to get SemWeb up and running with MySQL.&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5355607642937633928-2395972602161835059?l=waitink.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://waitink.blogspot.com/feeds/2395972602161835059/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5355607642937633928&amp;postID=2395972602161835059' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5355607642937633928/posts/default/2395972602161835059'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5355607642937633928/posts/default/2395972602161835059'/><link rel='alternate' type='text/html' href='http://waitink.blogspot.com/2007/07/using-semweb-with-sqlite-and-mysql.html' title='Using SemWeb with SQLite'/><author><name>Steve</name><uri>http://www.blogger.com/profile/11965922935328480623</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp3.blogger.com/_0uqP4s-XjUg/RjW1BDZI5cI/AAAAAAAAAAU/Yw7Z-g4efIw/s200/Picture+002.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5355607642937633928.post-6878409552005457459</id><published>2007-07-02T09:53:00.000+01:00</published><updated>2007-07-02T11:18:37.944+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='OWL'/><category scheme='http://www.blogger.com/atom/ns#' term='SemWeb'/><category scheme='http://www.blogger.com/atom/ns#' term='topic maps'/><category scheme='http://www.blogger.com/atom/ns#' term='RDF'/><title type='text'>Topic Maps, OWL and RDF</title><content type='html'>It's been quite a while since my last post. This has mostly been due to spending a large amount of time playing with some Topic Map (the &lt;a href="http://www.ontopia.net/omnigator/models/index.jsp"&gt;Ontopia Omnigator&lt;/a&gt;) and OWL (&lt;a href="http://protege.stanford.edu/plugins/owl/"&gt;Protege&lt;/a&gt;) software. Both of these are excellent applications and I was especially impressed by the ability of OWL to form advanced object relationships. &lt;br /&gt;&lt;br /&gt;However, at the end of all this research, I think that neither Topic Maps nor OWL are suitable for my purposes; yes, both can perform complex classifications and describe advanced relationships between classes but, for my purposes of creating a heterogeneous database, I only require simple classifications and relationships. Therefore using either of these technologies would probably be like taking the proverbial hammer to a nut. For me, a stronger argument against using these technologies is that, at this moment in time, neither is freely available for C# - the language that I'd like to work with.&lt;br /&gt;&lt;br /&gt;So my requirements are a technology that can describe simple classifications and relationships and that is freely available in C#. The one application that seems to match these requirements is Joshua Tauberer's &lt;a href="http://razor.occams.info/code/semweb/"&gt;SemWeb&lt;/a&gt; - an RDF library for C#. The RDF and RDFS support provided by this package can perform categorisation and describe the relationships between objects to a level suitable for my requirements. An added bonus is that this library is still under active development - version 1.0 was only released on the 10th June 2007 (unlike the other C# RDF library &lt;a href="http://www.driverdf.org/"&gt;Drive&lt;/a&gt; - the web page of which had actually expired the last time I looked).&lt;br /&gt;&lt;br /&gt;This doesn't mean to say that SemWeb is perfect - like most things I've encountered on this journey, using SemWeb is not as straightforward as it could be. The main reason for this is that SemWeb has been developed on &lt;a href="http://www.mono-project.com/Main_Page"&gt;Mono&lt;/a&gt;, as opposed to Microsoft's Visual Studio that I want to use. As a result of this the supplied Visual Studio solutions are incomplete (I needed to refer to the makefiles to create the required projects) and the package currently doesn't support SQL Server, the Express version of which I'd been using for some other areas of this project (such as user administration). I've therefore now switched databases to use MySQL and am now struggling to add and retrieve some RDF data from this. I'll give more details of this struggle in the next post.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5355607642937633928-6878409552005457459?l=waitink.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://waitink.blogspot.com/feeds/6878409552005457459/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5355607642937633928&amp;postID=6878409552005457459' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5355607642937633928/posts/default/6878409552005457459'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5355607642937633928/posts/default/6878409552005457459'/><link rel='alternate' type='text/html' href='http://waitink.blogspot.com/2007/07/topic-maps-owl-and-rdf.html' title='Topic Maps, OWL and RDF'/><author><name>Steve</name><uri>http://www.blogger.com/profile/11965922935328480623</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp3.blogger.com/_0uqP4s-XjUg/RjW1BDZI5cI/AAAAAAAAAAU/Yw7Z-g4efIw/s200/Picture+002.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5355607642937633928.post-6025039287819538713</id><published>2007-05-16T07:19:00.000+01:00</published><updated>2007-05-16T13:23:24.351+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='OWL'/><category scheme='http://www.blogger.com/atom/ns#' term='topic maps'/><category scheme='http://www.blogger.com/atom/ns#' term='RDF'/><title type='text'>RDF - An alternative to Topic Maps?</title><content type='html'>In my last post I described how Topic Maps appeared to be a possible mechanism for creating a flexible database, capable of storing a range of different, and possibly unrelated, items - a &lt;em&gt;heterogeneous database&lt;/em&gt;. However, as I also mentioned previously, a couple of things worried me about Topic Maps; namely that work in the area seems to have gone a bit quiet in the last couple of years and, secondly, that there appears to be quite a large European bias to the companies and institutions working in the field - not that this is a bad thing, but what are everyone else up to?&lt;br /&gt;&lt;br /&gt;These two things were playing on my mind, so rather than rushing headlong into Topic Maps, I decided to take a step back and spend a bit more time investigating other possible solutions. This search revealed that there is another possible solution to the problem - &lt;a href="http://en.wikipedia.org/wiki/Resource_Description_Framework"&gt;RDF - the Resource Description Framework&lt;/a&gt; (I'd already suggested in my last post that this could be a possibility). Indeed RDF and Topic Maps appear to cover very similar ground and, from an initial study of the available information, it's hard to decide between the two. It may be that subtle differences exist between the two technologies but my initial impression is that they are pretty much going head-to-head against each other – another VHS versus Betamax, but with probably slightly less interest from the general public.&lt;br /&gt;&lt;br /&gt;So what are the actual differences between RDF and Topic Maps and which technology is the most suitable for my purposes? As with Topic Maps, the documentation for RDF is rather sparse and also seems to mostly be a couple of years old - the only book I could find that described both subjects was &lt;a href="http://www.amazon.co.uk/gp/product/1932394206?ie=UTF8&amp;tag=whaithiabo-21&amp;linkCode=as2&amp;camp=1634&amp;creative=6738&amp;creativeASIN=1932394206"&gt;The Explorer's Guide to the Semantic Web&lt;/a&gt;, published in 2004. While this provided a good overview of both technologies, it didn't really cover them at a low enough level for my needs and, by the end, I was still left uncertain of the differences in the two. In addition, RDF has other related technologies - namely RDFS (&lt;a href="http://en.wikipedia.org/wiki/RDF_Schema"&gt;RDF Schema&lt;/a&gt;) and OWL (&lt;a href="http://en.wikipedia.org/wiki/Web_Ontology_Language"&gt;Web Ontology Language&lt;/a&gt; - which surely should be called WOL, although this would have reduced the oportunities to publish books with bird covers) and I felt that these weren't covered in enough detail. The only thing for it was to dig a bit deeper into each subject. &lt;br /&gt;&lt;br /&gt;&lt;strong&gt;RDF, RDFS and OWL&lt;/strong&gt;&lt;br /&gt;The definitive (and about the only) text on RDF is Shelley Power's &lt;a href="http://www.amazon.co.uk/gp/product/0596002637?ie=UTF8&amp;tag=whaithiabo-21&amp;linkCode=as2&amp;camp=1634&amp;creative=6738&amp;creativeASIN=0596002637"&gt;Practical RDF&lt;/a&gt;. This book did give low level descriptions of RDF, RDFS and OWL and I'd definitely recommend it for anyone interested in RDF. My only criticism would be that the chapters describing RDF tools are now a bit out of date (the book was published in 2003) and I found quite a few typos and mistakes in the RDF examples - a new edition of the book is surely required. However, by the end, I felt that I'd gained enough knowledge to pursue RDF a bit further. &lt;br /&gt;&lt;br /&gt;I think I now understand how RDF, RDFS and OWL fit together. My interpretation is that RDF is a mechanism that can describe simple relationships (subject-predicate-object expressions, known as triples e.g. apples have the colour green). RDF can be serialized using RDF\XML (i.e. an XML based language can be used to describe the RDF relationships). RDF Schema can then be used, in much the same way as XML Schema (XSD) are used with XML, to describe the contents and structure of the RDF, allowing relationships to be created. OWL is effectively built on top of RDFS, extending it to allow the generation of complex class and sub-class relationships.&lt;br /&gt;&lt;br /&gt;I'm still not sure about the differences in Topic Maps and RDF (the RDF book didn't cover Topic Maps), so I think the only thing for it is to play with the two technologies. I'll let you know how it goes in the next post.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5355607642937633928-6025039287819538713?l=waitink.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://waitink.blogspot.com/feeds/6025039287819538713/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5355607642937633928&amp;postID=6025039287819538713' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5355607642937633928/posts/default/6025039287819538713'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5355607642937633928/posts/default/6025039287819538713'/><link rel='alternate' type='text/html' href='http://waitink.blogspot.com/2007/05/rdf-alternative-to-topic-maps.html' title='RDF - An alternative to Topic Maps?'/><author><name>Steve</name><uri>http://www.blogger.com/profile/11965922935328480623</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp3.blogger.com/_0uqP4s-XjUg/RjW1BDZI5cI/AAAAAAAAAAU/Yw7Z-g4efIw/s200/Picture+002.jpg'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5355607642937633928.post-5092771436128134413</id><published>2007-04-15T22:26:00.000+01:00</published><updated>2007-04-15T22:26:22.368+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='information architecture'/><category scheme='http://www.blogger.com/atom/ns#' term='topic maps'/><title type='text'>Information Architecture and Topic Maps</title><content type='html'>Umm... things aren't as straightforward as I'd initially imagined. On investigating what's required for heterogeneous databases I've discovered that there's a whole world of stuff out there that I know little or nothing about: &lt;a href="http://en.wikipedia.org/wiki/Faceted_classification"&gt;facets&lt;/a&gt;, &lt;a href="http://en.wikipedia.org/wiki/Synonym_Ring"&gt;synonym rings&lt;/a&gt;, and &lt;a href="http://en.wikipedia.org/wiki/Controlled_vocabulary"&gt;controlled vocabularies &lt;/a&gt;to name but a few. In fact this world has a name: &lt;a href="http://en.wikipedia.org/wiki/Information_Architecture"&gt;Information Architecture&lt;/a&gt; and even its own bible, the legendary &lt;a href="http://www.amazon.co.uk/gp/redirect.html?ie=UTF8&amp;location=http%3A%2F%2Fwww.amazon.co.uk%2FInformation-Architecture-World-Wide-Web%2Fdp%2F0596527349%3Fie%3DUTF8%26s%3Dbooks%26qid%3D1176282450%26sr%3D1-3&amp;amp;amp;amp;amp;amp;tag=whaithiabo-21&amp;linkCode=ur2&amp;amp;camp=1634&amp;creative=6738"&gt;Polar Bear Book&lt;/a&gt;. Hidden amongst all this lies the mysterious field of &lt;a href="http://en.wikipedia.org/wiki/Topic_maps"&gt;Topic Maps&lt;/a&gt;. From my initial skimming of the available resources and documentation on the subject, it sounds as if these may be exactly what I’m after.&lt;br /&gt;&lt;br /&gt;I describe Topic Maps as being mysterious for two reasons: Firstly, after an initial flurry of activity in the area at the turn of the century, it appears as if things have now gone a bit quiet. The Topic Maps standard, &lt;a href="http://en.wikipedia.org/wiki/Topic_maps"&gt;ISO/IEC 13250&lt;/a&gt; and the related XML Topic Maps (&lt;a href="http://topicmaps.org/xtm/"&gt;XTM&lt;/a&gt;), were last published in 2002 and 2001 respectively. The only book I could find on the subject, &lt;a href="http://www.amazon.co.uk/gp/redirect.html?ie=UTF8&amp;amp;location=http%3A%2F%2Fwww.amazon.co.uk%2FXml-Topic-Maps-Creating-Using%2Fdp%2F0201749602%3Fie%3DUTF8%26s%3Dbooks%26qid%3D1176282290%26sr%3D1-5&amp;amp;tag=whaithiabo-21&amp;linkCode=ur2&amp;amp;camp=1634&amp;creative=6738"&gt;XML Topic Maps&lt;/a&gt;, was also published in 2002. Additionally, many of the main published links on the subject no longer exist. The second reason that Topic Maps are a bit mysterious is the fact that the vast majority of the research, and companies working in the area, seems to be concentrated in Europe – America seems to be ignoring their existence; either Europe is at the cutting edge of this technology, or something equivalent must exist that’s being used in America and I haven’t discovered it yet! (&lt;a href="http://en.wikipedia.org/wiki/RDFS"&gt;RDF and OWL&lt;/a&gt; perhaps?).&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;&lt;em&gt;Topic Maps – The Basics&lt;/em&gt;&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;In Topic Maps nearly everything is represented as a standalone entity - a topic, and relationships can be created between these topics. For example, if we wished to describe a book, we could create separate topics for the name of the author, the title of the book, the publisher of the book, etc. and other topics to describe the relationships between these topics – for example, that this book was written by the author. This makes it possible to create relationships for practically anything and therefore it’s also possible to create a relational database that can be used to represent anything, which is exactly what I’m after. In addition, new topics and relationships can be added as more information is known about a subject.&lt;br /&gt;&lt;br /&gt;In the next post I’ll hopefully describe how a topic map database can be created and how a range of different subjects can be stored. For anyone who can’t wait till then, some useful Topic Map information can be found at the following links:&lt;br /&gt;&lt;br /&gt;"Metadata? Thesauri? Taxonomies? Topic Maps!" &lt;a href="http://www.ontopia.net/topicmaps/materials/tm-vs-thesauri.html"&gt;http://www.ontopia.net/topicmaps/materials/tm-vs-thesauri.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Topic Maps and Relational Databases&lt;br /&gt;&lt;a href="http://www.xml.com/pub/a/2003/03/05/tmrdb.html"&gt;http://www.xml.com/pub/a/2003/03/05/tmrdb.html&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5355607642937633928-5092771436128134413?l=waitink.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://waitink.blogspot.com/feeds/5092771436128134413/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5355607642937633928&amp;postID=5092771436128134413' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5355607642937633928/posts/default/5092771436128134413'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5355607642937633928/posts/default/5092771436128134413'/><link rel='alternate' type='text/html' href='http://waitink.blogspot.com/2007/04/information-architecture-and-topic-maps.html' title='Information Architecture and Topic Maps'/><author><name>Steve</name><uri>http://www.blogger.com/profile/11965922935328480623</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp3.blogger.com/_0uqP4s-XjUg/RjW1BDZI5cI/AAAAAAAAAAU/Yw7Z-g4efIw/s200/Picture+002.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5355607642937633928.post-7284981086635004918</id><published>2007-04-02T13:07:00.000+01:00</published><updated>2007-04-03T13:36:15.232+01:00</updated><title type='text'>In search of database flexibility</title><content type='html'>Initially, to refresh my knowledge of ASP.NET and to get up to speed with SQL and relational databases (RDBs), I built a simple web site capable of storing information book and CD information. (Mainly this was based on the examples given in this book: &lt;a href="http://www.amazon.co.uk/gp/redirect.html?ie=UTF8&amp;location=http%3A%2F%2Fwww.amazon.co.uk%2Fexec%2Fobidos%2FASIN%2F1590594681&amp;amp;amp;amp;amp;amp;amp;amp;amp;tag=whaithiabo-21&amp;linkCode=ur2&amp;amp;camp=1634&amp;amp;creative=6738"&gt;Beginning ASP.NET 2.0&lt;/a&gt;).&lt;br /&gt;&lt;br /&gt;However, even at this stage, I was beginning to realise that it was going to be difficult to expand the RDB tables to provide a generic means of storage. To solve the problem I tried applying some object orientated design, creating a base table, to contain all common information and from which all others would be derived. However, it doesn't appear that relational databases lend themselves particularly well to object orientation, and I was still left with the situation were a new table would need to be created for each new type of item to be stored.&lt;br /&gt;&lt;br /&gt;To categorize the items added to the database, and as a means of navigating, I used a three level hierarchy of Department, Section and Category. So, for example, "Eyes Open" by Snow Patrol was stored into "Entertainment - Music - Indie". This seemed to provide a fairly sensible breakdown for music and books, but seemed that it might prove a bit restrictive for other sorts of item. It forced items to always be placed into a category (i.e. items couldn't be stored into departments or sections) and categories couldn't be broken down any further to give more specific classifications.&lt;br /&gt;&lt;br /&gt;Indeed, when I came to try to store more esoteric information, I soon discovered that the rigid nature of my database made it very difficult to add anything that didn't conform to a 3-layer classification scheme. For example, I wanted to add information about buildings but, knowing nothing about architecture, I had no idea what parent category ("Department" in my classification scheme) architecture would belong to, nor what sub-categories it would contain.&lt;br /&gt;&lt;br /&gt;Now, whilst I could have gone off and studied more about architecture to know how it should be classified, this wasn't really what I wanted. Instead I wanted a database that would give me the flexibility to add items at any level, plus the ability to reclassify items and insert hierarchies as my knowledge of a subject increased. Clearly my intial database wasn't up to the job. As a result, I've now set off in search of a database structure that can give me the flexibility I require.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5355607642937633928-7284981086635004918?l=waitink.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://waitink.blogspot.com/feeds/7284981086635004918/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5355607642937633928&amp;postID=7284981086635004918' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5355607642937633928/posts/default/7284981086635004918'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5355607642937633928/posts/default/7284981086635004918'/><link rel='alternate' type='text/html' href='http://waitink.blogspot.com/2007/04/initially-to-refresh-my-knowledge-of.html' title='In search of database flexibility'/><author><name>Steve</name><uri>http://www.blogger.com/profile/11965922935328480623</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp3.blogger.com/_0uqP4s-XjUg/RjW1BDZI5cI/AAAAAAAAAAU/Yw7Z-g4efIw/s200/Picture+002.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5355607642937633928.post-1116120149314818496</id><published>2007-03-31T21:57:00.000+01:00</published><updated>2007-03-31T22:41:26.865+01:00</updated><title type='text'>Developing a heterogeneous database</title><content type='html'>This, hopefully, is the start of a blog that will describe the development of a database for anything and everything - a &lt;em&gt;heterogeneous database&lt;/em&gt;.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;What exactly is it that I'm trying to create? &lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;&lt;/strong&gt;&lt;br /&gt;Basically, as mentioned above, a database that can store and index absolutely anything - books, CDs, buildings, restaurants, baked beans, etc. I want to create something into which I can store information about anything, and be able to retrieve, relate and search those items as easily as possible.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Why's it hard to create this database?&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;Since the information I want to store can potentially be anything, the indexes for each item can also be anything. So, for example, the main indexes for a book could be author, title and publisher, whereas a building could be name, location and architect; with standard database tables it wouldn't be easy to create a structure capable of storing this information, without creating a table for each type of item to be stored.&lt;br /&gt;&lt;br /&gt;Extra problems also arise when relationships between items need to be created. For example, if a book contained information about a building, how would this association be expressed or, if categories and sub-categories existed for a subject (e.g. fiction and non-fiction for books), how could the structure of the stored data be made to represent this.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Why the blog?&lt;/strong&gt;&lt;br /&gt;&lt;p&gt;There are 3 main reasons why I've chosen to create a blog on this:&lt;br /&gt; &lt;/p&gt;&lt;p&gt;&lt;em&gt;1.&lt;/em&gt; My knowledge of some of the required subject areas is a bit limited, so hopefully there are people out there who will take the time to step in when I'm heading off in the wrong direction.&lt;br /&gt;&lt;br /&gt;&lt;em&gt;2.&lt;/em&gt; From my initial searches I haven't been able to find an easy way to create what I'm after - hopefully anything posted here will be of use to anyone following along the same path.&lt;br /&gt;&lt;br /&gt;&lt;em&gt;3.&lt;/em&gt; Finally, just documenting the steps that I take should hopefully give me a clearer view of what's been done and where I'm going. If you feel like adding anything to this journey, please do.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5355607642937633928-1116120149314818496?l=waitink.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://waitink.blogspot.com/feeds/1116120149314818496/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5355607642937633928&amp;postID=1116120149314818496' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5355607642937633928/posts/default/1116120149314818496'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5355607642937633928/posts/default/1116120149314818496'/><link rel='alternate' type='text/html' href='http://waitink.blogspot.com/2007/03/developing-heterogeneous-database.html' title='Developing a heterogeneous database'/><author><name>Steve</name><uri>http://www.blogger.com/profile/11965922935328480623</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://bp3.blogger.com/_0uqP4s-XjUg/RjW1BDZI5cI/AAAAAAAAAAU/Yw7Z-g4efIw/s200/Picture+002.jpg'/></author><thr:total>0</thr:total></entry></feed>
