<?xml version="1.0" encoding="iso-8859-1"?>
<rss version="2.0">
  <channel>
    <title>Tsvetomir Tsonev's blog</title>
    <description>Tsvetomir Tsonev's blog</description>
    <link>http://blogs.telerik.com/TsvetomirTsonev/Posts.aspx</link>
    <docs>http://backend.userland.com/rss</docs>
    <item>
      <title>RadScheduler for ASP.NET AJAX - Q3 Beta</title>
      <description>&lt;p&gt;The days are getting longer here, at Telerik Central, as we are working hard to bring you the next top-notch release.&lt;/p&gt;
&lt;p&gt;Much attention is directed at RadScheduler and we have some good stuff coming down the pipeline. The beta is due today, so we have decided that it is about time to spill the beans.&lt;/p&gt;
&lt;p&gt;Looks count, really. That is why we have decided to add a touch of class to RadScheduler and make it a stylish part of your even more stylish applications.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.telerik.com/Libraries/MetaBlog/WindowsLiveWriter-d817ff2e5710_7FF5-ss-1_2.sflb"&gt;&lt;img height="373" width="610" border="0" src="http://blogs.telerik.com/Libraries/MetaBlog/WindowsLiveWriter-d817ff2e5710_7FF5-ss-1_thumb.sflb" alt="ss-1" style="border-width: 0px;" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;The changes are more than skin deep. The markup and the CSS were simplified and reduced in size for better performance.&lt;/p&gt;
&lt;p&gt;A total of three skins will be available in the beta, namely Default, Hay and Office2007.&amp;nbsp; The rest will be ready to shine in time for the full release.&lt;/p&gt;
&lt;p&gt;Currently, grouped views can easily get crammed up. But this is no longer the case, as horizontal scrolling will also make its debut in this release. Just set &lt;strong&gt;ColumnWidth&lt;/strong&gt; to the desired value and RadScheduler will do the rest:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.telerik.com/Libraries/MetaBlog/WindowsLiveWriter-d817ff2e5710_7FF5-ss-2_2.sflb"&gt;&lt;img height="373" width="610" border="0" src="http://blogs.telerik.com/Libraries/MetaBlog/WindowsLiveWriter-d817ff2e5710_7FF5-ss-2_thumb.sflb" alt="ss-2" style="border-width: 0px;" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;The inline template has received some attention too. It is now rendered on the client in order to reduce the number of requests to the server. It can be resized and its not constrained to the cell that contains it.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.telerik.com/Libraries/MetaBlog/WindowsLiveWriter-d817ff2e5710_7FF5-ss-3_2.sflb"&gt;&lt;img height="373" width="610" border="0" src="http://blogs.telerik.com/Libraries/MetaBlog/WindowsLiveWriter-d817ff2e5710_7FF5-ss-3_thumb.sflb" alt="ss-3" style="border-width: 0px;" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;The advanced template has also undergone some improvements. The inputs are now validated and the client script has been vastly improved. The refreshed design and the addition of animations add to a better user experience. We also provide VB version of the templates.&lt;/p&gt;
&lt;p&gt;Last, but not least, we are very happy to announce that we have adopted &lt;a target="_blank" href="http://jquery.com/"&gt;jQuery&lt;/a&gt; and it is starting to make its way into our products, including RadScheduler. It is such a delight to work with and results in compact and maintainable code. It will also make implementing client-side features much faster. And we have the proof coming...&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Regards,&lt;/p&gt;
&lt;p&gt;The RadScheduler crew.&lt;/p&gt;
</description>
      <link>http://blogs.telerik.com/TsvetomirTsonev/Posts/08-10-17/RadScheduler_for_ASP_NET_AJAX_-_Q3_Beta.aspx</link>
      <author>Tsvetomir Tsonev</author>
      <comments>http://blogs.telerik.com/TsvetomirTsonev/Posts/08-10-17/RadScheduler_for_ASP_NET_AJAX_-_Q3_Beta.aspx</comments>
      <guid isPermaLink="false">a043e63f-8bcd-450e-be88-a4ea5484031c</guid>
      <pubDate>Fri, 17 Oct 2008 01:15:05 GMT</pubDate>
    </item>
    <item>
      <title>Working with RadScheduler recurring appointments on SQL server*</title>
      <description>&lt;p&gt;You might have noticed that RadScheduler uses very cryptic strings to describe repeating appointments. We have decided not to reinvent the wheel and in fact this format is closely based on the iCalendar (&lt;a href="http://www.ietf.org/rfc/rfc2445.txt" target="_blank"&gt;RFC2445&lt;/a&gt;) standard. Here is an example:&lt;/p&gt;
&lt;p&gt;DTSTART:20080218T000000Z    &lt;br /&gt;
DTEND:20080219T000000Z     &lt;br /&gt;
RRULE:FREQ=MONTHLY;INTERVAL=12;BYDAY=-2MO;COUNT=3; &lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;This rule says: "The event starts at midnight on 18th of February 2008, lasts one day and repeats each year, for 3 years, on the second to last Monday of February". Now say this three times fast.&lt;/p&gt;
&lt;p&gt;As much as standards-based those strings are, they are useless if you want to process your appointments on the database server itself. There are many reasons for you to want to do this. You might want to check for conflicting appointments. Or you might need to prepare some statistics for a report.&lt;/p&gt;
&lt;p&gt;From version 2005 and up, SQL Server supports Managed Stored Procedures and User-Defined Functions (UDF). This exciting feature lets you plug in your own managed code into SQL Server and use it inside your queries. This is exactly what we need.&lt;/p&gt;
&lt;p&gt;The solution we are presenting comes in the form of a managed UDF. This function uses the same recurrence engine as RadScheduler to do the heavy lifting required to evaluate the rules.&lt;/p&gt;
&lt;p&gt;The attached file contains a setup script that enables CLR integration, registers the two assemblies (recurrence engine, UDF) and creates the function itself. Full source code of the UDF is included. Be sure to read the &lt;a href="http://msdn.microsoft.com/en-us/library/ms254506(VS.80).aspx" target="_blank"&gt;section on CLR integration&lt;/a&gt; on MSDN. There are good reasons that it is not enabled by default.&lt;/p&gt;
&lt;p&gt;Let's see how all this comes together. A common scenario is to request all appointments in a given time range. Here is how we can do this with our function:&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;/em&gt;&lt;/p&gt;
&lt;style type="text/css"&gt;
    .csharpcode, .csharpcode pre
    {
    font-size: small;
    color: black;
    font-family: consolas, "Courier New", courier, monospace;
    /*white-space: pre;*/
    }
    .csharpcode pre { margin: 0em; }
    .csharpcode .rem { color: #008000; }
    .csharpcode .kwrd { color: #0000ff; }
    .csharpcode .str { color: #006080; }
    .csharpcode .op { color: #0000c0; }
    .csharpcode .preproc { color: #cc6633; }
    .csharpcode .asp { background-color: #ffff00; }
    .csharpcode .html { color: #800000; }
    .csharpcode .attr { color: #ff0000; }
    .csharpcode .alt
    {
    background-color: #f4f4f4;
    width: 100%;
    margin: 0em;
    }
    .csharpcode .lnum { color: #606060; }
&lt;/style&gt;
&lt;!-- code formatted by http://manoli.net/csharpformat/ --&gt;
&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;DECLARE&lt;/span&gt; @@RangeStart &lt;span class="kwrd"&gt;as&lt;/span&gt; DATETIME&lt;br /&gt;&lt;span class="kwrd"&gt;SET&lt;/span&gt; @@RangeStart = &lt;span class="kwrd"&gt;CAST&lt;/span&gt;(&lt;span class="str"&gt;'2007-03-31'&lt;/span&gt; &lt;span class="kwrd"&gt;AS&lt;/span&gt; DATETIME)&lt;br /&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;DECLARE&lt;/span&gt; @@RangeEnd &lt;span class="kwrd"&gt;as&lt;/span&gt; DATETIME&lt;br /&gt;&lt;span class="kwrd"&gt;SET&lt;/span&gt; @@RangeEnd = &lt;span class="kwrd"&gt;CAST&lt;/span&gt;(&lt;span class="str"&gt;'2007-04-05'&lt;/span&gt; &lt;span class="kwrd"&gt;AS&lt;/span&gt; DATETIME)&lt;br /&gt;&lt;br /&gt;&lt;span class="rem"&gt;-- Will list all appointments (recurring or not) in the given range&lt;/span&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;SELECT&lt;/span&gt;      a.ID,&lt;br /&gt;            a.Subject,&lt;br /&gt;            ISNULL(o.StartDate, a.&lt;span class="kwrd"&gt;Start&lt;/span&gt;) &lt;span class="kwrd"&gt;as&lt;/span&gt; &lt;span class="kwrd"&gt;Start&lt;/span&gt;,&lt;br /&gt;            ISNULL(o.EndDate, a.[&lt;span class="kwrd"&gt;End&lt;/span&gt;]) &lt;span class="kwrd"&gt;as&lt;/span&gt; [&lt;span class="kwrd"&gt;End&lt;/span&gt;]&lt;br /&gt;&lt;span class="kwrd"&gt;FROM&lt;/span&gt;  Appointments a&lt;br /&gt;            &lt;span class="kwrd"&gt;OUTER&lt;/span&gt; APPLY dbo.ExpandRecurrence(a.RecurrenceRule, @@RangeStart, @@RangeEnd) &lt;span class="kwrd"&gt;AS&lt;/span&gt; o&lt;br /&gt;&lt;span class="kwrd"&gt;WHERE&lt;/span&gt; &lt;span class="rem"&gt;-- Include non-recurring appointments in the range&lt;/span&gt;&lt;br /&gt;            (a.RecurrenceRule &lt;span class="kwrd"&gt;IS&lt;/span&gt; &lt;span class="kwrd"&gt;NULL&lt;/span&gt; &lt;span class="kwrd"&gt;AND&lt;/span&gt; a.&lt;span class="kwrd"&gt;Start&lt;/span&gt; &amp;lt; @@RangeEnd &lt;span class="kwrd"&gt;AND&lt;/span&gt; a.[&lt;span class="kwrd"&gt;End&lt;/span&gt;] &amp;gt; @@RangeStart) &lt;span class="kwrd"&gt;OR&lt;/span&gt;&lt;br /&gt;            &lt;span class="rem"&gt;-- And recurring appointments in range.&lt;/span&gt;&lt;br /&gt;            (a.RecurrenceRule &lt;span class="kwrd"&gt;IS&lt;/span&gt; &lt;span class="kwrd"&gt;NOT&lt;/span&gt; &lt;span class="kwrd"&gt;NULL&lt;/span&gt; &lt;span class="kwrd"&gt;AND&lt;/span&gt; o.StartDate &amp;lt; @@RangeEnd &lt;span class="kwrd"&gt;AND&lt;/span&gt; o.EndDate &amp;gt; @@RangeStart)&lt;br /&gt;&lt;span class="kwrd"&gt;ORDER BY&lt;/span&gt; Start&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;This yields the following results:&lt;/p&gt;
&lt;table width="500" cellspacing="0" cellpadding="2" border="0"&gt;
    &lt;tbody&gt;
        &lt;tr&gt;
            &lt;td width="67" valign="top"&gt;ID&lt;/td&gt;
            &lt;td width="131" valign="top"&gt;Subject&lt;/td&gt;
            &lt;td width="140" valign="top"&gt;Start&lt;/td&gt;
            &lt;td width="155" valign="top"&gt;End&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td width="68" valign="top"&gt;24&lt;/td&gt;
            &lt;td width="132" valign="top"&gt;Meeting with Alex&lt;/td&gt;
            &lt;td width="140" valign="top"&gt;2007-03-31 06:00:00&lt;/td&gt;
            &lt;td width="155" valign="top"&gt;2007-03-31 07:00:00&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td width="69" valign="top"&gt;30&lt;/td&gt;
            &lt;td width="133" valign="top"&gt;Test Appointment&lt;/td&gt;
            &lt;td width="140" valign="top"&gt;2007-03-31 07:30:00&lt;/td&gt;
            &lt;td width="155" valign="top"&gt;2007-03-31 08:30:00&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td width="70" valign="top"&gt;15&lt;/td&gt;
            &lt;td width="133" valign="top"&gt;Technical meeting&lt;/td&gt;
            &lt;td width="140" valign="top"&gt;2007-04-02 06:30:00&lt;/td&gt;
            &lt;td width="155" valign="top"&gt;2007-04-02 07:30:00&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td width="71" valign="top"&gt;15&lt;/td&gt;
            &lt;td width="133" valign="top"&gt;Technical meeting&lt;/td&gt;
            &lt;td width="140" valign="top"&gt;2007-04-03 06:30:00&lt;/td&gt;
            &lt;td width="155" valign="top"&gt;2007-04-03 07:30:00&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td width="71" valign="top"&gt;15&lt;/td&gt;
            &lt;td width="133" valign="top"&gt;Technical meeting&lt;/td&gt;
            &lt;td width="140" valign="top"&gt;2007-04-04 06:30:00&lt;/td&gt;
            &lt;td width="155" valign="top"&gt;2007-04-04 07:30:00&lt;/td&gt;
        &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;You can see how "Technical meeting" has been expanded into several appointments, according to it's recurrence rule.&lt;/p&gt;
&lt;p&gt;Additional resources:&lt;/p&gt;
&lt;ul&gt;
    &lt;li&gt;&lt;a href="http://blogs.msdn.com/stuartpa/archive/2005/07/21/441468.aspx"&gt;Table Valued Function magic in SQL Server 2005 using the new SQL/CLR integration&lt;/a&gt; &lt;/li&gt;
    &lt;li&gt;&lt;a href="http://www32.brinkster.com/srisamp/sqlArticles/article_46.htm"&gt;SQLCLR Streaming Table Valued Functions (TVFs)&lt;/a&gt; &lt;/li&gt;
    &lt;li&gt;&lt;a href="http://http://www.sqlteam.com/article/returning-complex-data-from-user-defined-functions-with-cross-apply"&gt;Returning Complex Data from User-Defined Functions with CROSS APPLY&lt;/a&gt; &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Have fun!&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;* Applicable to SQL Server 2005 and up&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;Attached:&amp;nbsp;&lt;a href="http://blogs.telerik.com/Libraries/Tsvetomir%20Tsonev/ExpandRecurrence_UDF.sflb?download=true"&gt;ExpandRecurrence_UDF.zip&lt;/a&gt;&lt;a href="http://blogs.telerik.com/Libraries/Tsvetomir%20Tsonev/ExpandRecurrence.sflb"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;/em&gt;&lt;/p&gt;
</description>
      <link>http://blogs.telerik.com/TsvetomirTsonev/Posts/08-08-04/Working_with_RadScheduler_recurring_appointments_on_SQL_server.aspx</link>
      <author>Tsvetomir Tsonev</author>
      <comments>http://blogs.telerik.com/TsvetomirTsonev/Posts/08-08-04/Working_with_RadScheduler_recurring_appointments_on_SQL_server.aspx</comments>
      <guid isPermaLink="false">25e7c8ad-61f0-4470-a2ea-cc6ac2f262a9</guid>
      <pubDate>Mon, 04 Aug 2008 11:24:03 GMT</pubDate>
    </item>
    <item>
      <title>Upcoming features in RadScheduler Q1</title>
      <description>I am very excited to announce that the Q1 release of &lt;a href="http://www.telerik.com/products/aspnet-prometheus/overview.aspx"&gt;RadControls "Prometheus"&lt;/a&gt; will include major improvements of &lt;a href="http://www.telerik.com/demos/aspnet/prometheus/Scheduler/Examples/Overview/DefaultCS.aspx"&gt;RadScheduler&lt;/a&gt;. &lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;&lt;/h3&gt;
&lt;h3&gt;Flexible grouping&lt;/h3&gt;
You probably are familiar with the "&lt;a href="http://www.telerik.com/demos/aspnet/prometheus/Scheduler/Examples/ResourceGrouping/DefaultCS.aspx"&gt;group by resource day view&lt;/a&gt;". We referred to it as "Resource View". We now extend this concept further and you will be able to enable resource grouping in every view type - day, week and month. Here is how the week view looks when it is grouped by resource:&lt;br /&gt;
&lt;br /&gt;
&lt;img src="http://blogs.telerik.com/Photos/Storage/tsonev/Week_Res_H_s.png" /&gt;&lt;br /&gt;
&lt;br /&gt;
In addition, you will be able to specify the grouping direction. The screenshot above demonstrates the default value - horizontal. Here is how RadScheduler looks when using vertical direction:&lt;br /&gt;
&lt;br /&gt;
&lt;img src="http://blogs.telerik.com/Photos/Storage/tsonev/Week_Res_V_s.png" /&gt;&lt;br /&gt;
&lt;br /&gt;
The new view options require some visual polishing, but we will take care of this in the following weeks.&lt;br /&gt;
&lt;br /&gt;
We are also working on a new view type - a timeline. It will show a time scale on the horizontal axis and the appointments will be optionally grouped by resource.&lt;br /&gt;
&lt;br /&gt;
&lt;img src="http://blogs.telerik.com/Photos/Storage/tsonev/TimeLine_s.png" /&gt;&lt;br /&gt;
&lt;br /&gt;
We plan to extend the grouping further, so stay tuned for more details.&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;Advanced Form customization&lt;/h3&gt;
So far we only gave you two choices when it comes to customizing the advanced form. You either had to start from scratch or you had the option to do minor adjustments to the control tree on the fly. These two options cover only the two extremes - minor modifications and total rewrite. We were unable to provide assistance if you wanted to retain most of the functionality, like recurrence editing, and add your own on top of it.&lt;br /&gt;
&lt;br /&gt;
We hope that this will no longer be the case. With the Q1 release we will supply a set of user controls that replicate the functionality of the integrated templates. They are completely self-contained and are logically organized into components. We will help you get started by providing an example and documentation.&lt;br /&gt;
The user controls will be included in the upcoming Futures release. It is due next week.&lt;br /&gt;
&lt;br /&gt;
Have fun!&lt;br /&gt;
</description>
      <link>http://blogs.telerik.com/TsvetomirTsonev/Posts/08-03-18/Upcoming_features_in_RadScheduler_Q1.aspx</link>
      <author>Tsvetomir Tsonev</author>
      <comments>http://blogs.telerik.com/TsvetomirTsonev/Posts/08-03-18/Upcoming_features_in_RadScheduler_Q1.aspx</comments>
      <guid isPermaLink="false">dfef5644-f32d-4182-9be5-02dfb1fc0811</guid>
      <pubDate>Tue, 18 Mar 2008 10:38:48 GMT</pubDate>
    </item>
    <item>
      <title>Integrated support for Load-On-Demand from Web Services in RadControls "Prometheus"</title>
      <description>As you may already know, the "Prometheus" counter-parts of RadComboBox, RadTreeView and RadMenu made their official appearance in the Q3 2007 release. The migration to the new code base was an opportunity for us to take a fresh look at the controls and identify the weak spots that needed improvement.&lt;br /&gt;
&lt;br /&gt;
One area that received great attention was the Client-side API. We wanted our customers to be able to create smart and responsive applications and this meant rich client-side functionality. Nothing that can be done on the client should require a trip to the server.&lt;br /&gt;
&lt;br /&gt;
The result is a flexible and powerful API that features:&lt;br /&gt;
&lt;ul&gt;
    &lt;li&gt;Ability to add, modify and remove items on the client.  &lt;/li&gt;
    &lt;li&gt;Persistence of changes done on the client to the server.  &lt;/li&gt;
    &lt;li&gt;Rich event model. &lt;/li&gt;
&lt;/ul&gt;
&lt;p &gt;&lt;br /&gt;
The new API allowed us to introduce an additional, lightweight load-on-demand mechanism that uses web services to populate the controls. We have tried to achieve maximum flexibility without compromising the ease of use. Let me demonstrate how this is done for RadMenu. The other controls follow the same pattern. &lt;span style="FONT-SIZE: 9pt; COLOR: #0000ff; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;&lt;/span&gt;&lt;span style="FONT-SIZE: 9pt; COLOR: #a31515; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;telerik&lt;/span&gt;&lt;span style="FONT-SIZE: 9pt; COLOR: #0000ff; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;:&lt;/span&gt;&lt;span style="FONT-SIZE: 9pt; COLOR: #a31515; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;RadMenu&lt;/span&gt;&lt;span style="FONT-SIZE: 9pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;span style="mso-tab-count: 1"&gt;     &lt;/span&gt;&lt;span style="COLOR: #ff0000"&gt;ID&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;="RadMenu1"&lt;/span&gt; &lt;span style="COLOR: #ff0000"&gt;runat&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;="server"&amp;gt;&lt;br /&gt;
    &lt;/span&gt;&lt;/span&gt;&lt;b style="mso-bidi-font-weight: normal"&gt;&lt;span style="FONT-SIZE: 9pt; COLOR: #0000ff; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&amp;lt;&lt;/span&gt;&lt;/b&gt;&lt;b style="mso-bidi-font-weight: normal"&gt;&lt;span style="FONT-SIZE: 9pt; COLOR: #a31515; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;WebServiceSettings&lt;/span&gt;&lt;/b&gt;&lt;b style="mso-bidi-font-weight: normal"&gt;&lt;span style="FONT-SIZE: 9pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt; &lt;span style="COLOR: #ff0000"&gt;Path&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;="ProductCategories.asmx"&lt;/span&gt; &lt;span style="COLOR: #ff0000"&gt;Method&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;="GetMenuCategories"&lt;/span&gt; &lt;span style="COLOR: #0000ff"&gt;/&amp;gt;&lt;br /&gt;
        &lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;span style="FONT-SIZE: 9pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;Items&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;gt;&lt;br /&gt;
            &lt;/span&gt;&lt;/span&gt;&lt;span style="FONT-SIZE: 9pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;telerik&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;:&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;RadMenuItem&lt;/span&gt; &lt;span style="COLOR: #ff0000"&gt;Text&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;="Products"&lt;/span&gt; &lt;span style="COLOR: #ff0000"&gt;Value&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;="1"&lt;/span&gt; &lt;b style="mso-bidi-font-weight: normal"&gt;&lt;span style="COLOR: #ff0000"&gt;ExpandMode&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;="WebService"&lt;/span&gt;&lt;/b&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;gt;&lt;br /&gt;
            &lt;/span&gt;&lt;/span&gt;&lt;span style="FONT-SIZE: 9pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;telerik&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;:&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;RadMenuItem&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;gt;&lt;br /&gt;
            &lt;/span&gt;&lt;/span&gt;&lt;span style="FONT-SIZE: 9pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;telerik&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;:&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;RadMenuItem&lt;/span&gt; &lt;span style="COLOR: #ff0000"&gt;Text&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;="Purchase"&lt;/span&gt; &lt;span style="COLOR: #ff0000"&gt;Value&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;="132"&lt;/span&gt; &lt;b style="mso-bidi-font-weight: normal"&gt;&lt;span style="COLOR: #ff0000"&gt;ExpandMode&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;="WebService"&lt;/span&gt;&lt;/b&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;gt;    &lt;br /&gt;
            &lt;/span&gt;&lt;/span&gt;&lt;span style="FONT-SIZE: 9pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;telerik&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;:&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;RadMenuItem&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;gt;&lt;br /&gt;
        &lt;/span&gt;&lt;/span&gt;&lt;span style="FONT-SIZE: 9pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;Items&lt;/span&gt;&lt;span style="COLOR: #0000ff"&gt;&amp;gt;    &lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="FONT-SIZE: 9pt; COLOR: #0000ff; LINE-HEIGHT: 115%; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="FONT-SIZE: 9pt; COLOR: #a31515; LINE-HEIGHT: 115%; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;telerik&lt;/span&gt;&lt;span style="FONT-SIZE: 9pt; COLOR: #0000ff; LINE-HEIGHT: 115%; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;:&lt;/span&gt;&lt;span style="FONT-SIZE: 9pt; COLOR: #a31515; LINE-HEIGHT: 115%; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;RadMenu&lt;/span&gt;&lt;span style="FONT-SIZE: 9pt; COLOR: #0000ff; LINE-HEIGHT: 115%; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;You only have to configure the path to the web service and specify the method name. Afterwards, the items with ExpandMode="WebService" will be populated through the web service.&lt;br /&gt;
&lt;br /&gt;
The web service has a simple signature. It receives a RadMenuItemData object with basic information about the initiating item and a context dictionary. It has to return an array of RadMenuItemData objects.&lt;/p&gt;
&lt;p class="MsoNormal" style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;&lt;span style="FONT-SIZE: 9pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;[ScriptService]&lt;br /&gt;
&lt;/span&gt;&lt;span style="FONT-SIZE: 9pt; COLOR: #0000ff; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;public&lt;/span&gt;&lt;span style="FONT-SIZE: 9pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt; &lt;span style="COLOR: #0000ff"&gt;class&lt;/span&gt; ProductCategories : WebService&lt;br /&gt;
&lt;/span&gt;&lt;span style="FONT-SIZE: 9pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;{&lt;br /&gt;
    &lt;/span&gt;&lt;span style="FONT-SIZE: 9pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;[WebMethod]&lt;br /&gt;
    &lt;/span&gt;&lt;span style="FONT-SIZE: 9pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;span style="COLOR: #0000ff"&gt;public&lt;/span&gt; RadMenuItemData[] GetMenuCategories(&lt;span style="mso-tab-count: 1"&gt; &lt;/span&gt;RadMenuItemData item,&lt;br /&gt;
                                                    &lt;/span&gt;&lt;span style="FONT-SIZE: 9pt; COLOR: #2b91af; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;IDictionary&lt;/span&gt;&lt;span style="FONT-SIZE: 9pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&amp;lt;&lt;span style="COLOR: #0000ff"&gt;string&lt;/span&gt;, &lt;span style="COLOR: #0000ff"&gt;object&lt;/span&gt;&amp;gt; context)    &lt;br /&gt;
&lt;/span&gt;&lt;span style="FONT-SIZE: 9pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;    {    &lt;br /&gt;
&lt;/span&gt;&lt;span style="FONT-SIZE: 9pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;        DataTable productCategories = GetProductCategories(item.Value);&lt;br /&gt;
        &lt;/span&gt;&lt;span style="FONT-SIZE: 9pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;span style="COLOR: #2b91af"&gt;List&lt;/span&gt;&amp;lt;RadMenuItemData&amp;gt; result = &lt;span style="COLOR: #0000ff"&gt;new&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;List&lt;/span&gt;&amp;lt;RadMenuItemData&amp;gt;();&lt;br /&gt;
        &lt;/span&gt;&lt;span style="FONT-SIZE: 9pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;span style="COLOR: #0000ff"&gt;foreach&lt;/span&gt; (DataRow row &lt;span style="COLOR: #0000ff"&gt;in&lt;/span&gt; productCategories.Rows)&lt;br /&gt;
        {    &lt;br /&gt;
&lt;/span&gt;&lt;span style="FONT-SIZE: 9pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;            RadMenuItemData itemData = &lt;span style="COLOR: #0000ff"&gt;new&lt;/span&gt; RadMenuItemData();    &lt;br /&gt;
&lt;/span&gt;&lt;span style="FONT-SIZE: 9pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;            itemData.Text = row[&lt;span style="COLOR: #a31515"&gt;"Title"&lt;/span&gt;].ToString();&lt;br /&gt;
            &lt;/span&gt;&lt;span style="FONT-SIZE: 9pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;itemData.Value = row[&lt;span style="COLOR: #a31515"&gt;"CategoryId"&lt;/span&gt;].ToString();    &lt;br /&gt;
            &lt;br /&gt;
            &lt;/span&gt;&lt;span style="FONT-SIZE: 9pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;span style="COLOR: #0000ff"&gt;if&lt;/span&gt; (&lt;span style="COLOR: #2b91af"&gt;Convert&lt;/span&gt;.ToInt32(row[&lt;span style="COLOR: #a31515"&gt;"ChildrenCount"&lt;/span&gt;]) &amp;gt; 0)&lt;br /&gt;
            &lt;/span&gt;&lt;span style="FONT-SIZE: 9pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;{&lt;br /&gt;
                &lt;/span&gt;&lt;span style="FONT-SIZE: 9pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;itemData.ExpandMode = MenuItemExpandMode.WebService;&lt;br /&gt;
            &lt;/span&gt;&lt;span style="FONT-SIZE: 9pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;}&lt;br /&gt;
            &lt;/span&gt;&lt;span style="FONT-SIZE: 9pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;result.Add(itemData);&lt;br /&gt;
          &lt;/span&gt;&lt;span style="FONT-SIZE: 9pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;}&lt;br /&gt;
          &lt;/span&gt;&lt;span style="FONT-SIZE: 9pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;span style="COLOR: #0000ff"&gt;return&lt;/span&gt; result.ToArray();&lt;br /&gt;
      &lt;/span&gt;&lt;span style="FONT-SIZE: 9pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;}&lt;br /&gt;
&lt;/span&gt;&lt;span style="FONT-SIZE: 9pt; LINE-HEIGHT: 115%; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;We are using the item's value to denote the category ID in this example. You can pass arbitrary information to the web service using the context dictionary.&lt;br /&gt;
&lt;br /&gt;
You can see just how easy it is to implement load on demand with the new "Prometheus" controls. And this is just a basic example. You can use the client-side events to further customize the data sent to the web service or to react to communication errors.&lt;br /&gt;
&lt;br /&gt;
The full version of the example is available &lt;a href="http://www.telerik.com/demos/aspnet/prometheus/Menu/Examples/Programming/WebService/DefaultCS.aspx" target="_blank"&gt;here&lt;/a&gt;.&lt;/p&gt;
</description>
      <link>http://blogs.telerik.com/TsvetomirTsonev/Posts/08-01-31/Integrated_support_for_Load-On-Demand_from_Web_Services_in_RadControls_Prometheus_.aspx</link>
      <author>Tsvetomir Tsonev</author>
      <comments>http://blogs.telerik.com/TsvetomirTsonev/Posts/08-01-31/Integrated_support_for_Load-On-Demand_from_Web_Services_in_RadControls_Prometheus_.aspx</comments>
      <guid isPermaLink="false">ffc8053b-8193-4a70-8d08-1f9d72719c88</guid>
      <pubDate>Thu, 31 Jan 2008 00:00:00 GMT</pubDate>
    </item>
    <item>
      <title>Team Foundation Server and the missing file sharing (Part 2)</title>
      <description>&lt;span&gt;&lt;div&gt;&lt;p&gt;In &lt;a name="x.35" /&gt;&lt;a href="http://blogs.telerik.com/blogs/tsvetomir_tsonev/archive/2007/11/05/4615.aspx"&gt;part
1&lt;/a&gt; I have outlined the process we
have designed to emulate shared files in the TFS. In this post I will explain
in detail each step and the tools it requires.&lt;br /&gt;
&lt;br /&gt;
You can download the bits, including complete source code. You can study them
or adapt them for your own needs. The usual "no warranties"
disclaimer applies.&lt;br /&gt;
&lt;br /&gt;
We have chosen to keep things simple and create a number of tools with
well-defined tasks, instead of creating a monolithic solution. We wanted to be
able to inspect the intermediate results on each step and to keep the coupling
to a minimum.&lt;/p&gt;

&lt;h3&gt;Finding the shared
files&lt;/h3&gt;

&lt;p&gt;If we are going to do anything about shared files, then we
need to know how to find them. A map with their locations would be useful, so we
will create one. The first tool should be able to interface with Visual Source
Safe, find the shared files and output results in an XML file for further
processing. We can name this tool "VSSLinks". Not a very creative
name, I admit, but it will have to do.&lt;br /&gt;
&lt;br /&gt;
The implementation is relatively straightforward. We have to walk the desired
locations recursively and record the links (shared locations) for each of the files.
What we do not need are pinned files (those are shared files frozen at a given
revision) and deleted files.&lt;br /&gt;
&lt;br /&gt;
We can also try to determine which is the "original" (or parent) file
of each given group of shared files. This information can help us create more
consistent branching structure in the TFS repository. For example, if a folder
is shared at multiple locations, this information can help us ensure that each
location consists only of "children" or "parents", instead
of a random mix of both. Unfortunately, the implementation of file sharing in
VSS makes this information hard or impossible to get. So it's an educated guess
at best.&lt;br /&gt;
&lt;br /&gt;
The tool expects some basic configuration defined in VSSLinks.exe.config file -
repository location, credentials, output file and locations file (a simple XML
document listing the paths to scan for shared files).&lt;br /&gt;
&lt;br /&gt;
Here is a sample configuration file:&lt;/p&gt;

&lt;/div&gt;

&lt;img src="http://blogs.telerik.com/photos/storage/tsonev/VSSLinks_Config.gif" /&gt;&lt;br /&gt;&lt;span&gt;The
following locations file specifies that the whole repository should be scanned:&lt;br /&gt;
&lt;/span&gt;&lt;span&gt;&lt;div&gt;&lt;br /&gt;&lt;img src="http://blogs.telerik.com/photos/storage/tsonev/VSSLinks_Locations.gif" /&gt;&lt;/div&gt;

&lt;br /&gt;


&lt;div&gt;

&lt;p&gt;Depending on
the repository size, the process can take from minutes to a couple of hours. It
is fastest when run locally on the VSS server. When it's done, the output file
will look like this:&lt;br /&gt;
&lt;br /&gt;

 
 
 &lt;/p&gt;

&lt;/div&gt;

&lt;img src="http://blogs.telerik.com/photos/storage/tsonev/VSSLinks_Map.gif" /&gt;&lt;br /&gt;


&lt;div&gt;

&lt;p&gt;This map will go a long way, so it pays off to inspect it carefully at
this step.&lt;/p&gt;

&lt;h3&gt;Branching and
labeling of the files in the TFS&lt;/h3&gt;

&lt;p&gt;The cornerstone of our file sharing scheme is a carefully arranged
branching structure. In order to create it we need to execute the following
steps:&lt;/p&gt;

&lt;p&gt;1. Label the parents from the map (created by
VSSLinks) with "SHARE". &lt;/p&gt;

&lt;p&gt;2. Delete the children (after the migration,
they are simply copies). &lt;/p&gt;

&lt;p&gt;3. Branch each parent to the locations of its
children. &lt;/p&gt;

&lt;p&gt;4. Label the children "SHARE-TARGET" to avoid
confusion with normal branches. &lt;/p&gt;

&lt;p&gt;&lt;br /&gt;
The tool for this task should use the provided map and prepare a file with
commands to be fed to tf.exe (the command-line interface to TFS). This approach
leverages the available (and hopefully bug-free) tools and shields us from the
complexity of performing these operations through the TFS API. We will call it
"AutoBranch". I think I am getting better at naming the tools.&lt;br /&gt;
&lt;br /&gt;
AutoBranch will need some basic data to generate the commands. It includes
input and output file, label names, server and project name. We will also
prefix our check-in comments with some keyword that will signal our automatic
synchronization (explained below) to ignore them. The ignore comment will
ensure that if we add shared files after the deployment of the system, they
will not be processed by the aforementioned synchronization system.&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;p&gt;
 
 
&lt;img src="http://blogs.telerik.com/photos/storage/tsonev/AutoBranch_Config.gif" /&gt;&lt;br /&gt; &lt;/p&gt;

&lt;/div&gt;




&lt;div&gt;

&lt;p&gt;All the other data we need is in the map file. The tool
sorts the links from the map and outputs the different commands in the
appropriate order. It groups the operations by type, so the whole process can
be completed with only two check-ins, regardless of the number of shared files.
Very clean and simple.&lt;br /&gt;
&lt;br /&gt;
The output file contains the generated commands:&lt;/p&gt;

&lt;/div&gt;




&lt;div&gt;

&lt;/div&gt;

&lt;img src="http://blogs.telerik.com/photos/storage/tsonev/AutoBranch_Output.gif" /&gt;&lt;br /&gt;


&lt;p&gt;&lt;br /&gt;
At this point we can start the command sequence by executing "tf
@AutoBranch.tfc". Note that you have to be running the command from the
local folder that the project has been mapped to. Alternatively, you can set
UseTemporaryWorkspace to true. In this case, you should run the command from a
folder that has not been mapped to a TFS project.&lt;/p&gt;

&lt;h3&gt;Automatic
synchronization&lt;/h3&gt;

&lt;p&gt;Skipping right to the fun part? I cannot blame you, really. We
need some mechanism to inform us that a certain file has changed, so we can
keep our shared files in sync. The thing that suits our needs perfectly is TFS notifications.
We can easily setup a web service endpoint and subscribe it to check-in event notifications.&lt;br /&gt;
&lt;br /&gt;
We will create an ASP.NET web-site that will host the service endpoint. In the
zip file, the tool is called "TFSMergeWS". The web site will also
host a bare-bones log viewer, so we can easily track its activity. The
application should run in an application pool under an identity that has
permissions to check-in into the targeted team projects.&lt;br /&gt;
&lt;br /&gt;
First, we need to subscribe to check-in event notification. We can either use
the command-line BisSubscribe utility or the TFS Event Subscription Tool (&lt;a name="bi3_" /&gt;&lt;a href="http://www.codeplex.com/tfseventsubscription"&gt;project's
home at CodePlex&lt;/a&gt;). Example
usage:&lt;/p&gt;

&lt;p&gt;BisSubscribe /eventType CheckinEvent /address
http://server/path/CheckInEndpoint.asmx /deliveryType Soap /server
http://tfsserver:port&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;
So far, so good. Now we have to parse the incoming notifications. I have used
the excellent project template from this &lt;a name="ja.t" /&gt;&lt;a href="http://blogs.conchango.com/howardvanrooijen/archive/2006/04/29/3894.aspx"&gt;blog
post&lt;/a&gt; by Howard van Rooijen to get me started with this task. The template
makes easy task of deserializing the XML message into classes.&lt;br /&gt;
&lt;br /&gt;
After the notification is received we have to do some basic filtering. Every
check-in that is not part of our project watch list is discarded. So are
check-ins prefixed with the keyword "NO-SHARE". The project watch
list is located in the Projects.xml file in the App_Data folder. All other
settings like the ignore keyword reside in web.config.&lt;br /&gt;
&lt;br /&gt;
The last important piece of information from the check-in notification message
is the list of affected files. Once we obtain it, we are ready to do the actual
merging. We do it on per-file basis. If the file happens to be a child, we
first merge it with its parent and then merge the parent with all its children.
In case it's a parent, we skip directly to updating the children.&lt;br /&gt;
&lt;br /&gt;
Simple enough in theory, but the implementation has quite a few obstacles to
overcome. For instance, finding the parent of a branched file is not a trivial
task. &lt;br /&gt;
&lt;br /&gt;
Here is how the operation log looks like after a shared file has been checked
in:&lt;/p&gt;

&lt;p&gt;12/03/2007
15:16:52: [123844] Processing checkin for project RadControls by user
TELERIK\user1 committed on 12/3/2007 3:16:51 PM.&lt;br /&gt;
12/03/2007 15:16:52: [123844] Loaded 10473 files labeled SHARE from the cache.&lt;br /&gt;
12/03/2007 15:16:52: [123844] Loaded 24352 files labeled SHARE-TARGET from the
cache.&lt;br /&gt;
12/03/2007 15:16:52: [123844] Loaded 8284 files labeled PINNED from the cache.&lt;br /&gt;
12/03/2007 15:16:52: [123844] Changeset contains 1 file(s).&lt;br /&gt;
12/03/2007 15:16:52: [123844] Merging child to trunk:&lt;br /&gt;
12/03/2007 15:17:13: [123844] Successfully merged $/Product1/Build/Copyright.txt
with $/Common/Copyright.txt. Checking in.&lt;br /&gt;
12/03/2007 15:17:14: [123844] Merging trunk to children (3 total):&lt;br /&gt;
12/03/2007 15:17:29: [123844] No action needed for
$/Product1/Build/Copyright.txt.&lt;br /&gt;
12/03/2007 15:17:37: [123844] Successfully merged $/Common/Copyright.txt with
$/Product2/Build/Copyright.txt. Checking in.&lt;br /&gt;
12/03/2007 15:17:45: [123844] Successfully merged $/Common/Copyright.txt with
$/Product3/Build/Copyright.txt. Checking in.&lt;br /&gt;
12/03/2007 15:17:45: [123844] ---- Done. ----&lt;/p&gt;

&lt;p&gt;We can see how the check-in of $/Product1/Build/Copyright.txt
triggered an update to its parent ($/Common/Copyright.txt). Then all of its
siblings have been updated with the same changes.&lt;/p&gt;

&lt;h3&gt;The illusion of free
lunch&lt;/h3&gt;

&lt;p&gt;Most careful readers have probably noticed something by
now. The more shares you add to file, the more merge operations it will take to
synchronize them. In other words it is an operation with linear complexity and
having more shared files will deteriorate the merge time. &lt;/p&gt;

&lt;p&gt;&lt;br /&gt;
Using branches has another drawback. It fails to provide a good abstraction for
the purposes of file sharing. The users have to be aware of the synchronization
mechanism. They should edit only one file from a shared group at a time in
order to avoid synchronization problems. The users should also keep in mind
that the synchronization is not instant. In a perfect case they should not have
to do any of this.&lt;br /&gt;
&lt;br /&gt;
But given its transitional role, I think that it serves its purpose well. I
hope that it will be of use to you too. At least by inspiring you to come up
with your own clever automation tools to utilize the features of TFS.&lt;/p&gt;&lt;p&gt;Attachment: &lt;a href="http://blogs.telerik.com/files/TFS_FileSharing.zip"&gt;TFS_FileSharing.zip&lt;/a&gt;&lt;/p&gt;&lt;/span&gt;&lt;/span&gt;                </description>
      <link>http://blogs.telerik.com/TsvetomirTsonev/Posts/07-12-21/Team_Foundation_Server_and_the_missing_file_sharing_Part_2.aspx</link>
      <author>Tsvetomir Tsonev</author>
      <comments>http://blogs.telerik.com/TsvetomirTsonev/Posts/07-12-21/Team_Foundation_Server_and_the_missing_file_sharing_Part_2.aspx</comments>
      <guid isPermaLink="false">b75bfa7e-7bf7-4cdb-b397-0b1ebac7a609</guid>
      <pubDate>Fri, 21 Dec 2007 00:00:00 GMT</pubDate>
    </item>
    <item>
      <title>Team Foundation Server and the missing file sharing (Part 1)</title>
      <description>&lt;span&gt;&lt;font class="" color="#000000"&gt;Hello, everyone. First, let me introduce myself - my name is Tsvetomir Tsonev and I work as a developer, here at Telerik. I have spent the last couple of months working on RadScheduler with the great team I am part of.&lt;br&gt;&lt;br&gt;Another thing that I have been busy with, together with my colleagues, is the migration from Visual Source Safe to Team Foundation Server. I would like to share our experience with you as the process was very challenging in some respects.&lt;br&gt;&lt;br&gt;Like many Microsoft shops we have been using Visual Source Safe as our primary source control system for a long time. We have long outgrown this solution, but we have delayed the migration to the TFS, as it lacks a killer feature to push the process along. In fact, it misses one particular feature that has wide-spread use in our existing repository, namely file sharing. It is a cheap replacement for proper project structure and for historical reasons our classic RadControls heavily rely on it. For instance, there is shared code between the .NET 1.1 and .NET 2.0 control versions, shared skins and so on.&lt;br&gt;&lt;br&gt;Microsoft insists that using it is a bad practice and we could not agree more. But a total overhaul is not an option when faced with the migration of quite a huge code repository. To make this practical we needed to find out a way to emulate this missing feature with what is available on the TFS.&lt;br&gt;&lt;br&gt;After considering all options, we have decided to use a special branching structure as a replacement to file sharing.&lt;br&gt;&lt;br&gt;The standard migration process makes copies of the shared file to all listed locations. The idea is to pick one of those locations and branch it to the other, replacing the copies. We will also label these branches with marker labels, so we do not confuse them with the regular branches. With this done, all we need to do is to keep the branches synchronized.&lt;br&gt;&lt;br&gt;The process needs to be automated and require minimum support once the migration is complete. We have divided it in a number of steps and created the necessary tools to get us through them. Let me illustrate it with a diagram.&lt;br&gt;&lt;br&gt;
&lt;p align="center"&gt;&lt;img src="/photos/storage/tsonev/TFS_Migration_Part_1.gif"&gt;&lt;br&gt;&lt;/p&gt;
&lt;p class="" align="left"&gt;&lt;span&gt;&lt;font color="#000000"&gt;The most exciting part is the automated synchronization. This is where the TFS begins to shine as its extensibility is unlimited for all practical purposes. The thing that suits our needs perfectly for the occasion is notifications. We can wire our branch synchronization logic to the Check-In event and that is about everything we need.&lt;br&gt;&lt;br&gt;Stay tuned for Part 2 where I will walk you in detail through the process and the tools we have created for the various tasks.&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;/font&gt;&lt;/span&gt;</description>
      <link>http://blogs.telerik.com/TsvetomirTsonev/Posts/07-11-04/Team_Foundation_Server_and_the_missing_file_sharing_Part_1.aspx</link>
      <author>Tsvetomir Tsonev</author>
      <comments>http://blogs.telerik.com/TsvetomirTsonev/Posts/07-11-04/Team_Foundation_Server_and_the_missing_file_sharing_Part_1.aspx</comments>
      <guid isPermaLink="false">97dd6fe7-7769-46df-8b11-6662dd5e5b8f</guid>
      <pubDate>Sun, 04 Nov 2007 19:16:00 GMT</pubDate>
    </item>
  </channel>
</rss>