Will Asrari ~ Bellingham, WA Web Development (ASP.NET, VB .NET, C#, SQL)http://blog.willasrari.comPersonal blog, code samples, tutorials, and articles about ASP.NET, C#, and SQL!Copyright (C) 2005-20065This is an XML content feed. It is intended to be viewed in a newsreader or syndicated to another site, subject to copyright and fair use.External URLs and Phone Numbers in WP7 WebBrowser ControlThe <a href="http://msdn.microsoft.com/en-us/library/ff431812%28v=vs.92%29.aspx">Windows Phone 7 WebBrowser</a> is garbage.&nbsp; F**king horrible. If you want to display basic HTML it's great.&nbsp; If you want to display HTML that users can interact with (i.e. clicking hyperlinks, mailto: links, or dial phone numbers) it's basically useless.&nbsp; Don't even get me started on opacity and background images.&nbsp; In developing a Windows Phone 7 application recently there was a need to link to a mobile-enabled website. In said website there were pages with phone numbers, email addresses, etc... A business requirement for the application was to open up the mail client, dial a phone number, or open a hyperlink when a user clicked on these links.&nbsp; No duh right?&nbsp; I thought the WebBrowser would at least be able to parse out links with href and mailto and since it's built for a PHONE it should be smart enough to detect tel.&nbsp; Fail.<br><br>At this point we had a couple of options (<a href="http://www.pcmag.com/article2/0,2817,2387131,00.asp">Mango</a> is NOT an option at this point):<br><ol><li>Recreate the external site in XAML with event handlers for the "hyperlinks" which would end up being styled textblock controls</li><li>Take a screenshot of the mobile site and place rectangles over the hyperlinks and wire those up to events</li><li>Download the HTML from the site asynchronously, parse HTML and find <code>head</code> or <code>title</code> tags, inject JavaScript to find and enumerate all <code>a</code> tags and wire up an <code>onclick</code> event to raise the <code>ScriptNotify</code> event [via <code>window.external.Notify</code>], call the WebBrowser's <code>NavigateToString</code> method and pass in this newly-constructed HTML, figure out what kind of link was clicked and then fire an appropriate task<br></li></ol>
Before I talk about which option I chose, take a minute to soak in the absurdity of the aforementioned solutions (FYI - I chose 3).
Take this simple example site here:
<br><br><img src="/blog/uploads/webbrowser-sucks-01.png" alt="simple webbrowser example 1">
<p>And here's the markup (unadulterated)</p><p><img style="width: 530px; height: 366px;" src="/blog/uploads/webbrowser-sucks-02.png" alt="simple webbrowser example 2"></p>Simple enough right? You can clearly see that the links are sporting the correct syntax. Time to start hacking.
<p>The first thing we need to do is add JavaScript to get all of our <code>a</code> tags. Once we have this we simply need to enumerate and attach an <code>onclick</code> event. I'm not a JavaScript expert by any means but think this fairly unobtrusive. This JavaScript is going to remain constant so we should use the <code>const</code> string:</p>
<p><a href="/blog/uploads/webbrowser-sucks-03.png"><img style="width: 526px; height: 143px;" src="/blog/uploads/webbrowser-sucks-03.png" alt="simple webbrowser example 3"></a></p><p>The next thing we need to do is wire up the WebBrowser control. The most important part is to enable scripting via the <code>IsScriptEnabled</code> property. This is set to <code>false</code> by default and resulted in many f-bombs being dropped until I figured this out. We will also need to wire up the <code>ScriptNotify</code> event. This is how the WebBrowser will communicate with our application.</p><p><a href="/blog/uploads/webbrowser-sucks-04.png"><img style="width: 530px; height: 258px;" src="/blog/uploads/webbrowser-sucks-04.png" alt="simple webbrowser example 4"></a></p><p>In the <code>LoadedComplete</code> method we perform an asynchronous request via <code>WebClient</code> object to get the source HTML from the server. We then create a <code>StringBuilder</code> instance and insert our JavaScript just before the <code>&lt;/title&gt;</code> tag.</p><p>Now that the <code>ScriptNotify</code> event is wired up we can set a breakpoint in our code, run the application, and determine which link was clicked when we tap the link.</p><p><img src="/blog/uploads/webbrowser-sucks-05.png" alt="simple webbrowser example 5"></p><p>In the case above, we'll want to launch the <a href="http://msdn.microsoft.com/en-us/library/microsoft.phone.tasks.webbrowsertask%28v=vs.92%29.aspx"><code>EmailComposeTask</code></a>.</p><p><img src="/blog/uploads/webbrowser-sucks-06.png" alt="simple webbrowser example 6"></p><p>Running this code in the emulator and we get the following:</p><p><img src="/blog/uploads/webbrowser-sucks-07.png" alt="simple webbrowser example 7"></p><p>I don't have a mail account setup in the emulator (is this possible?) so we see the fail message. But if I did in fact have an email account setup it would display appropriately. For other scenarios you would use the appropriate phone task.</p><p>Easy enough. This code isn't production-ready by any means. I just wanted to quickly share with others how to accomplish a task that should be a native experience (IMO). I will clean this up and add logic for things such as detecting if there is actually a <code>title</code> tag, confirming that a task is about to be shown, cleaning up the <code>ScriptNotify</code> event handler, etc... This would take about 3 seconds using <a href="http://en.wikipedia.org/wiki/Interface_Builder">Interface Builder</a> in Mac OS (iOS development). iOS developers have the luxury of checking boxes for detecting various links in text controls.</p><p>Original inspiration: <a href="http://www.ben.geek.nz/2010/07/integrated-links-and-styling-for-windows-phone-7-webbrowser-control/">Integrated Links and Styling for Windows Phone 7 WebBrowser Control</a></p>
http://www.willasrari.com/blog/external-urls-and-phone-numbers-in-wp7-webbrowser-control/000348.aspx7/12/2011 1:30:03 AMWill AsrariJson.NET and Generic HttpWebRequest Responses FTW<p>Working on a <a href="http://www.microsoft.com/windowsphone/en-us/default.aspx?WT.srch=1&amp;WT.mc_id=Search&amp;cmpid=7D846D7D-BB78-41C1-A054-CBD14AACF98D">Windows Phone 7</a> mobile app recently, I found myself writing a bunch of similar / redundant code for <code>HttpWebRequest</code> response handling. By "a bunch" I mean in the neighborhood of 3 methods.... Hello <a href="http://msdn.microsoft.com/en-us/library/ms172192.aspx">Generics</a>!!!</p><p>If I find myself writing the same handler more than once and the only difference is the type of object I am returning I ALWAYS (at least try to) write a generic method to take care of the heavy lifting.&nbsp; There are a plethora of reasons to use Generics when the opportunity presents itself and I'm not going to start listing them.&nbsp; Those of you that understand .NET Generics will get it.&nbsp; If you are a .NET developer and currently developing applications targeting version 2.0 or greater and aren't familiar with Generics, then I highly suggest you educate yourself: <a href="http://msdn.microsoft.com/en-us/library/ms172192.aspx">Generics in the .NET Framework</a>.<br><br>If you are still with me and are familiar with the <a href="http://msdn.microsoft.com/en-us/library/btdf6a7e%28v=VS.95%29.aspx"><code>System.Net</code></a> namespace and the <a href="http://msdn.microsoft.com/en-us/library/system.net.httpwebrequest%28v=vs.95%29.aspx"><code>HttpWebRequest</code></a> class (as it pertains to Silverlight and/or Windows Phone 7), I'd like to share the following response handler for dealing with Asynchronous requests:</p><p><code>private static T ProcessFamiliarRequestResponse&lt;T&gt;(IAsyncResult asyncResult)<br>{<br>&nbsp;&nbsp;&nbsp; HttpWebRequest request = (HttpWebRequest)asyncResult.AsyncState;<br>&nbsp;&nbsp;&nbsp; HttpWebResponse httpWebResponse = (HttpWebResponse)request.EndGetResponse(asyncResult);<br><br>&nbsp;&nbsp;&nbsp; using (StreamReader streamReader = new StreamReader(httpWebResponse.GetResponseStream()))<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return JsonWorker.TooEasyToDeserializeJsonObject&lt;T&gt;(streamReader.ReadToEnd());<br>&nbsp;&nbsp;&nbsp; }<br>}</code></p><p>If this doesn't make sense to you I highly suggest reading up on <a href="http://blogs.msdn.com/b/silverlight_sdk/archive/2008/04/01/using-webclient-and-httpwebrequest.aspx">WebClient</a> and <a href="http://blogs.msdn.com/b/silverlight_sdk/archive/2008/04/01/using-webclient-and-httpwebrequest.aspx">HttpWebRequest</a> usage.&nbsp; If you are familiar, I hope you can appreciate that this is one point of entry into handling an infinite number of requests (within reason).</p><p>It gets cleaner: Enter <a href="http://json.codeplex.com/">Json.NET</a>.&nbsp; Personally, I like to create clean POCO's to return data to the consumer.&nbsp; I have seen way too many examples creating objects that conform EXACTLY to the Json format returned from any given request.&nbsp; For instance:</p><p><code>public class Employee<br>{<br>&nbsp;&nbsp;&nbsp; public string employee_first_name { get; set; }<br>&nbsp;&nbsp;&nbsp; public string employee_last_name { get; set; }<br>&nbsp;&nbsp;&nbsp; public string employee_job_description { get; set; }<br>}<br></code></p><p>Gross (imo).&nbsp; .NET is so much better than this.&nbsp; I take pride in the code that I deliver and personally believe the following class is much cleaner (and not to mention, conforms to .NET naming conventions):</p><p><code>public class Employee<br>{<br>&nbsp;&nbsp;&nbsp; [JsonProperty("employee_first_name")]<br>&nbsp;&nbsp;&nbsp; public string FirstName { get; set; }<br><br>&nbsp;&nbsp;&nbsp; [JsonProperty("employee_last_name")]<br>&nbsp;&nbsp;&nbsp; public string LastName { get; set; }<br><br>&nbsp;&nbsp;&nbsp; [JsonProperty("employee_job_description")]<br>&nbsp;&nbsp;&nbsp; public string JobDescription { get; set; }<br>}<br></code></p><p>This way you can map your neatly-defined POCO properties to their disgusting origins.&nbsp; The following generic method for deserializing your Json results works fairly well (pre-supposing you decorated your POCO(s) with the <a href="http://james.newtonking.com/projects/json/help/html/T_Newtonsoft_Json_Serialization_JsonProperty.htm"><code>JsonProperty</code></a> attribute OR left it repulsive and/or primitive):<br></p><p><code>public static class JsonWorker<br>{<br>&nbsp;&nbsp;&nbsp; public static T DeserializeJsonObject&lt;T&gt;(string result)<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return JsonConvert.DeserializeObject&lt;T&gt;(result);<br>&nbsp;&nbsp;&nbsp; }<br>}</code></p><p>If you want to take it a step further, you could add the following method to your <code>JsonWorker</code> class to serialize your objects. Think storing application state in IsolatedStorage or updating your light-weight, client-side database (via <a href="http://sterling.codeplex.com/">Sterling</a> (which is AWESOME!!!)):<br></p><p><code>public static string WayEasierToSerializeObjectToJson(object randomPOCO)<br>{<br>&nbsp;&nbsp;&nbsp; return JsonConvert.SerializeObject(randomPOCO);<br>}<br></code></p><p>Easy.</p>http://www.willasrari.com/blog/jsonnet-and-generic-httpwebrequest-responses-ftw/000346.aspx5/25/2011 1:33:10 AMWill AsrariDebug a Windows Phone 7 Application After a Tombstone<p>In debugging a Windows Phone 7 issue related to application state and tombstoning recently, I found that the Visual Studio debugger stops after the application comes back from a tombstone (press the Windows putton on Windows Phone 7 emulator, then press device back button to reactivate the application).&nbsp; A quick Google search and I ran across a little <a href="http://wildermuth.com/2010/08/19/Debugging_Tombstoning_in_Windows_Phone_7">gem</a> on <a href="http://wildermuth.com">Shawn Wildermuth</a>'s blog.<br></p><p>Solution:&nbsp; Press F5 again while the emulator is displaying the "Resuming...." progress indicator.&nbsp;</p><p>Easy.</p>http://www.willasrari.com/blog/debug-a-windows-phone-7-application-after-a-tombstone/000345.aspx11/18/2010 12:59:55 AMWill AsrariSet Silverlight Startup Page<p>In sandboxing Windows Phone 7 recently I came across the need to change my startup page.&nbsp; The reasoning for this is simple: I have a core of the work completed and I want to sandbox a data call before I implement in the actual application.&nbsp; With conventional web projects this is as easy as right-clicking the file you want to and click 'Set As Start Page'. With the Windows Phone 7 SDK this luxury does not exist.</p><p>There is however a way to accomplish this with a little bit of code.&nbsp; Simply open up your projects App.xaml.cs and implement an <code>Application_Startup</code> method.</p><p><code>private void Application_Startup(object sender, StartupEventArgs e)<br>{<br>&nbsp;&nbsp;&nbsp; RootVisual = new SandboxPage();<br>}</code></p><p><code>SandboxPage</code> is the name of my XAML page in this example. Here we simply set the <code>RootVisual</code> to an instance of our new page.</p><p>The second piece to this is registering this startup method in the <code>App</code> constructor a la:</p><p><code>public App()<br>{<br>&nbsp;&nbsp;&nbsp; Startup += Application_Startup;<br>}</code></p><p>This doesn't necessarily apply to Windows Phone 7.&nbsp; General Silverlight.</p><p>Easy.<br></p>http://www.willasrari.com/blog/set-silverlight-startup-page/000343.aspx8/6/2010 3:47:11 PMWill AsrariHello Windows Phone<p>Today the Community Technology Preview release of Visual Studio 2010 Express for Windows Phone 7 was released. For those not in the know, this release provides 100% compatibility with the final version of Visual Studio 2010.</p><p>You can get it here: <a href="http://www.microsoft.com/downloads/details.aspx?displaylang=en&amp;FamilyID=cabcd5ed-7dfc-4731-9d7e-3220603cad14">Visual Studio 2010 Express for Windows Phone 7</a><br></p>
<p><img src="http://i43.tinypic.com/wrxbgi.png"></p><p>I have been interested in and writing XNA for a couple of months now and will start posting more regularly thanks to this new addition.</p><p>Stay tuned!</p>http://www.willasrari.com/blog/hello-windows-phone/000342.aspx5/6/2010 7:13:04 PMWill AsrariDynamically Insert Language ISO Code in Sitecore Url<p>In working with localizing a <a href="http://www.sitecore.net">Sitecore</a> CMS solution recently I came across an interesting requirement: analytics (SEO optimization by region).&nbsp; I was handling Sitecore localization by adding supported languages and creating localized versions of each content item.&nbsp; The wrinkle was that I needed to now add a language prefix to all the urls on the site so they could get indexed appropriately for each region.&nbsp; To make it even more complicated, I had to deal with hard-coded urls that weren't driven by the CMS.&nbsp; I thought I was going to have to create multiple sites within Sitecore for each language, duplicate content, etc...&nbsp; It turns out that it was much easier than this.</p><p>In a Sitecore web.config you'll find a <code>linkManager</code> section. This will handle much of the heavy lifting for you. There is one setting that you need to pay attention to (2 if you aren't using IIS 7).</p>
<p>The first (and most important) is the <code>languageEmbedding</code> setting. In a site that is in one language you should set to "never". A site that may have one or two localized pages here and there set to "asNeeded". In my case, a full-blown localization effort, this should be set to "always".</p><p>If you aren't using IIS 7 you will need to set the <code></code> setting for <code>addAspxExtension</code> to "true".</p><p><code>&nbsp;&nbsp;&nbsp; &lt;linkManager defaultProvider="sitecore"&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;providers&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;clear /&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;add name="sitecore" type="Sitecore.Links.LinkProvider, Sitecore.Kernel"<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; addAspxExtension="true"<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; alwaysIncludeServerUrl="false"<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; encodeNames="true"<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; languageEmbedding="always"<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; languageLocation="filePath"<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; shortenUrls="true"<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; useDisplayName="false" /&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/providers&gt;<br>&nbsp;&nbsp;&nbsp; &lt;/linkManager&gt;</code></p><p>Sitecore CMS will now take care of the url rewriting!&nbsp; Easy.</p><p>For those you like me that have pre-defined navigation requirements (i.e. not driven 100% by the CMS) there is one more step to take to accomplish url prefixing.&nbsp; Take a link such as:</p><p><code>&lt;a href="/Foo.aspx"&gt;</code></p><p>To get a url that looks like http://www.foo.com/de-DE/foo.aspx you simply need to write a little bit of "yellow code".<br></p><p><code>&lt;a href="/&lt;%= Sitecore.Context.Language %&gt;/foo.aspx"&gt;</code></p><p>Easy.</p>http://www.willasrari.com/blog/dynamically-insert-language-iso-code-in-sitecore-url/000341.aspx4/29/2010 11:55:39 AMWill AsrariProblem Deploying MVC Applications on IIS 5.1 or IIS 6?<p>I know what you are thinking, "Who uses IIS 5.1 or IIS 6 these days?"&nbsp; Believe it or not, some environments still use these and I had been pulling my hair out trying to deploy an MVC application to an IIS 5.1 server. The application works in production and wasn't working locally. Nothing had changed aside from some minor View refactoring. A couple of hours later I thought back to an Ektron project that required URL-rerouting and then it dawned on me: "IIS is checking to make sure that the file exists".</p><p>I opened up IIS, drilled down to my application, and followed these steps:</p><ol><li>Right-click application (or virtual directory)</li><li>Click 'Properties'</li><li>Click 'Home Directory' if application ('Virtual Directory' if virtual directory)</li><li>Click 'Configuration' button</li><li>Click 'Add' button</li><li>Executable: C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\aspnet_isapi.dll</li><li>Extension: .*</li><li>Check 'All Verbs' if it isn't already (it should be)</li><li>Uncheck 'Check file exists'</li><li>Click 'OK'</li><li>Click 'Apply'</li><li>Click 'OK'</li></ol>Dear Diary. Jackpot.<br>http://www.willasrari.com/blog/problem-deploying-mvc-applications-on-iis-51-or-iis-6/000340.aspx12/10/2009 3:15:26 PMWill AsrarijQuery Data Method is the Business<p>&lt;3 <a href="http://docs.jquery.com/Internals/jQuery.data">this</a> little <a href="http://www.jquery.com">jQuery</a> gem<br></p>
<code>$(document).ready(function() {<br>&nbsp;&nbsp;&nbsp; $('#button').data('Data', { Message: 'sup foo?', Email: 'asdf@asdf.com' });<br><br>&nbsp;&nbsp;&nbsp; $('#button').click(function() {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; var data = $(this).data('Data');<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; alert(data.Message + '\n' + data.Email);<br>&nbsp;&nbsp;&nbsp; });<br>});<br>
<br>
&lt;input type="button" id="button" value="clickie" /&gt;<br></code><p><img src="http://i49.tinypic.com/2pq16dz.png" alt="jQuery data() method result"></p><p>Easy.</p>http://www.willasrari.com/blog/jquery-data-method-is-the-business/000336.aspx11/5/2009 2:37:09 PMWill AsrariGeneric jQuery Function to Remove CSS Classes<P>I've been using a lot of <A href="http://jquery.com/">jQuery</A> lately in a new project and am falling in love with it!&nbsp; It is a wonder why I have never used it before but am glad I was kind of forced to learn it ;)</P>
<P>As with anything new there is a bit of a learning curve.&nbsp; The application I am working on boasts a large number of tabs for different sections of the site.&nbsp; One of the requirements is to toggle the "active" tab via CSS class.&nbsp; Easy right?&nbsp; This was easy to do in vanilla JavaScript so it should be super-easy to do with jQuery.&nbsp; It is!</P><CODE><B>
<P>$(</B></FONT><FONT color=#a31515><FONT color=#a31515>'#FooItem1'</FONT></FONT><B>).removeClass(</B></FONT><FONT color=#a31515><FONT color=#a31515>'active'</FONT></FONT><B>);<BR>$(</B></FONT><FONT color=#a31515><FONT color=#a31515>'#FooItem2'</FONT></FONT><B>).removeClass(</B></FONT><FONT color=#a31515><FONT color=#a31515>'active'</FONT></FONT><B>);<BR>$(</B></FONT><FONT color=#a31515><FONT color=#a31515>'#FooItem3'</FONT></FONT><B>).removeClass(</B></FONT><FONT color=#a31515><FONT color=#a31515>'active'</FONT></FONT><B>);<BR>$(</B></FONT><FONT color=#a31515><FONT color=#a31515>'#FooItem4'</FONT></FONT><B>).removeClass(</B></FONT><FONT color=#a31515><FONT color=#a31515>'active'</FONT></FONT><B>);<BR>$(</B></FONT><FONT color=#a31515><FONT color=#a31515>'#FooItem5'</FONT></FONT><B>).removeClass(</B></FONT><FONT color=#a31515><FONT color=#a31515>'active'</FONT></FONT><B>);</P></B></FONT></CODE>
<P>That works great but there is one caveat: adding new tabs.&nbsp; If the requirements of the UI changed and we were to have to add a new tab (or 6 more) then we would have to not only change the view (or in this case partial view ;) ) but also the JavaScript functions dealing with these tabs.&nbsp; Since all of our tabs are <CODE>UL</CODE> with stylized <CODE>LI</CODE>'s containing anchor tags I decided to create something like this:</P><CODE><FONT color=#0000ff><FONT color=#0000ff>
<P>function</FONT></FONT><B> RemoveActiveClassFromListItemControlByID(controlID) {<BR>&nbsp;&nbsp;&nbsp;$(</B></FONT><FONT color=#a31515><FONT color=#a31515>"#"</FONT></FONT><B> + controlID).children().each(</B></FONT><FONT color=#0000ff><FONT color=#0000ff>function</FONT></FONT><B>() {<BR>&nbsp;&nbsp;&nbsp;$(</B></FONT><FONT color=#0000ff><FONT color=#0000ff>this</FONT></FONT><B>).children(</B></FONT><FONT color=#a31515><FONT color=#a31515>"a"</FONT></FONT><B>).removeClass(</B></FONT><FONT color=#a31515><FONT color=#a31515>"active"</FONT></FONT><B>);});<BR>}</P></B></FONT></CODE>
<P>Now this isn't <EM>that</EM> generic since I have the "a" and "active" strings hard-coded.&nbsp; In this case it works for us since all the tabs are the same format and all we really need is the id of the control.&nbsp; This little function will enumerate the children of the control (in this case all <CODE>LI</CODE>'s and then enumerate the <CODE>A</CODE> children and remove the <CODE>active</CODE> css class.&nbsp; Simple.&nbsp; To extend this to be even more generic you could do the following:</P><CODE><FONT color=#0000ff><FONT color=#0000ff>
<P>function</FONT></FONT><B> RemoveClassNamesFromChildElementByControlID(controlID, childElement, className) {<BR>$(</B></FONT><FONT color=#a31515><FONT color=#a31515>"#"</FONT></FONT><B> + controlID).children().each(</B></FONT><FONT color=#0000ff><FONT color=#0000ff>function</FONT></FONT><B>() {<BR>&nbsp;&nbsp;&nbsp;$(</B></FONT><FONT color=#0000ff><FONT color=#0000ff>this</FONT></FONT><B>).children(childElement).removeClass(className);});<BR>}</P></B></FONT></CODE>
<P>Here's an example of how you could use the function above.&nbsp; Let's say that you want to enumerate all children in a <CODE>OL</CODE> with an id of "fooList". Each children has a <CODE>span</CODE> tag with a css class of <CODE>BAR</CODE> and you want to reset all of them when a user clicks on a hyperlink.&nbsp; This would be extremely simple:</P><CODE><FONT color=#0000ff><FONT color=#0000ff>
<P>&lt;</FONT></FONT><FONT color=#a31515><FONT color=#a31515>a</FONT></FONT><B> </B></FONT><FONT color=#ff0000><FONT color=#ff0000>href</FONT></FONT><FONT color=#0000ff><FONT color=#0000ff>="javascript:(RemoveClassNamesFromChildElementByControlID('fooList', 'span', 'BAR'));"&gt;</FONT></FONT><B>CLICK HERE</B></FONT><FONT color=#0000ff><FONT color=#0000ff>&lt;/</FONT></FONT><FONT color=#a31515><FONT color=#a31515>a</FONT></FONT><FONT color=#0000ff><FONT color=#0000ff>&gt;</P></FONT></FONT></CODE>
<P>Easy.&nbsp; I'm really starting to love this jQuery business.</P>
<P>jQuery + MVC = love</P>http://www.willasrari.com/blog/generic-jquery-function-to-remove-css-classes/000334.aspx6/10/2009 3:10:42 PMWill AsrariSQL Server 2008 Save Not Permitted Dialog Box<P>I was creating some tables this evening in a SQL Server 2008 database this evening so that I could sandbox some MVC functionality for a current project.&nbsp; I had designed the tables according to the tutorial only to find out that this wasn't the case.&nbsp; I'll just log back in to SQL and make the necessary changes.&nbsp; Easy.</P>
<P>When I added the missing column I went ahead and reordered to match the same order of the tutorial because, well; I am a little OCD at times.&nbsp; I remember doing this in the past pre-SQL 2008 with no trouble.&nbsp; This time I was hit with this:</P>
<P><IMG src="http://i41.tinypic.com/vqtwn5.png"></P>
<P>Weird.&nbsp; Again, I had never seen this before so I was a bit surprised.</P>
<P>According to <A href="http://msdn.microsoft.com/en-us/library/bb895146.aspx">SQL Server 2008 Books Online</A> this can be caused by any of the following:</P>
<OL>
<LI>Adding a new column to the middle of the table
<LI>Dropping a column
<LI>Changing column nullability
<LI>Changing the order of the columns
<LI>Changing the data type of a column</LI></OL>
<P>Really?&nbsp; These all seem like fairly common tasks when working within a database.&nbsp; As odd as this may seem (maybe there is a good reason for this?), there is a very easy fix.</P>
<P>From the <STRONG>Tools</STRONG> menu click on <STRONG>Options</STRONG>, expand <STRONG>Designers</STRONG>, click on <STRONG>Table and Database Designers</STRONG>.&nbsp; Select or clear the <STRONG>Prevent saving changes that require table re-creation</STRONG> option.</P>
<P>Much better.&nbsp; Back to work.</P>http://www.willasrari.com/blog/sql-server-2008-save-not-permitted-dialog-box/000333.aspx6/3/2009 12:49:46 AMWill AsrariSQL 2008 and The Setup Failed to Read IIsMimeMap Table<P>Decided to install SQL 2008 recently because of it being 2009 and all.&nbsp; What an adventure.&nbsp; Although not near as bad as upgrading from Vista Home Premium to Vista Ultimate, it sucked pretty bad.</P>
<P>I downloaded the 120-day trial Developer Edition as a self-extracting executable because I didn't feel like burning a DVD / using Daemon Toolz.&nbsp; The download was the smoothest part of this whole deal.</P>
<P>From the installer screen I chose the Upgrade from SQL 2000 / 2005 option because I have SQL 2005 Developer Edition installed so this made the most sense.&nbsp; Miserable fail.&nbsp; I kept erroring out when trying to install SQL Reporting Services.&nbsp; The exact error(s) escape me but I remember it having something to do with authentication and the report service.&nbsp; Naturally I thought to manually stop and start the service to see if there was any issue.&nbsp; Good thing because manually starting the service failed.&nbsp; It then dawned on me that between the time I had initially installed SQL 2005 and that very instant I had changed my Windows password.&nbsp; Right-click, 'Properties' and changed it to my current password, restart the service: SUCCESS!</P>
<P>Now let's try upgrading again: FAIL!</P>
<P>After hitting the Google fairly hard I read a couple of blog entries detailing how uninstalling SQL Server 2005 entirely from the Control Panel would remedy the situation.&nbsp; I tried this and received the following error when attempting to uninstall SQL 2005 Reporting Services:</P>
<P><IMG alt="Failed to read IIsMimeMap table 01" src="http://i43.tinypic.com/205vxx5.png"></P>
<P>Awesome.&nbsp; Have no idea what this means so I searched Google for it.&nbsp; Apparently no one else does either.&nbsp; There were tons of suggestions as to how to go about remedy'ing this so I tried a couple.&nbsp; These solutions ranged from reconfiguring Reporting Services to uninstalling and reinstalling IIS7.&nbsp; I opted to try and reconfigure Reporting Services only to find that the configuration tools no longer existed on my machine seeing as how that was successfully uninstalled before receiving the error message above.&nbsp; I then tried to uninstall again and received this error message.</P><IMG alt="Failed to read IIsMimeMap table 02" src="http://i39.tinypic.com/j82j6d.png">
<P></P>
<P>Same error, different error code. Weird.</P>
<P>The final solution was to install each component of SQL 2005 one-by-one from Control Panel.&nbsp; As crazy as that sounds it actually ended up being successful.</P>
<P>So, if you are getting these error messages try uninstalling each and every SQL 2005 component one-by-one and then do a clean install of SQL 2008.&nbsp; It worked for me.</P>http://www.willasrari.com/blog/sql-2008-and-the-setup-failed-to-read-iismimemap-table/000332.aspx1/6/2009 1:27:40 PMWill AsrariLAMP Developer Needed<P>Checked an e-mail account that has apparently been exluded from my main Send/Receive group in Outlook today and found this e-mail in the Junk E-mail folder.</P>
<P>Maybe I should use this to setup a rule...</P>
<P>;)</P>
<P><IMG alt="LAMP Developer Needed" src="http://i36.tinypic.com/35asttu.png"></P>
<P>I have learned a bunch of exciting things over the past couple of months but unfortunately it's proprietary and I can't blog about it! </P>
<P>I was never one to blog about where I work or what projects I have been working or else I'd have a ton of new entries.</P>http://www.willasrari.com/blog/lamp-developer-needed/000331.aspx12/11/2008 9:14:08 PMWill AsrariMicrosoft Office Interop Outlook & C# For Outlook Searches<P>I had a need yesterday to query a bunch of Outlook e-mails: 44,743 to be exact.&nbsp; This was the result of a clients mailing list account being setup incorrectly and we just found out about it!&nbsp; An e-mail account was setup strictly for the mailing list and it was never properly setup as an Outlook account locally.&nbsp; No big deal.&nbsp; When the hosting provider contacted us to clean it up I noticed that there were a BUNCH of bad e-mail addresses (Return to sender, bad account, etc...).&nbsp; At first I started to click on individual e-mails, copy the bad e-mail address to a .txt file, then search that folder for the same e-mail address and delete the results.&nbsp; That takes FOOOOORRREEEEVVVVEEEEERRRRRRR.&nbsp; Then I realized I could dork around with Outlook via a C# console application and harvest the e-mails and output them in a sorted Excel spreadsheet.</P>
<P>Enter <CODE>Microsoft.Office.Core</CODE> and <CODE>Microsoft.Office.Interop.Outlook</CODE> namespaces.&nbsp;I decided&nbsp;it would be best to create a little&nbsp;C# console application utilizing these namespaces to search the e-mail, write a&nbsp;little regular expression&nbsp;pattern (by write I mean copy &amp; paste&nbsp;one from the interwebs)&nbsp;to parse out e-mail addresses, and add e-mail addresses that didn't have the host name or the reply e-mail account in it to a <CODE>List&lt;string&gt;</CODE> (if it didn't already contain it!).&nbsp; It was pretty easy.</P>
<P>First:</P><CODE><FONT color=#0000ff>
<P>using</FONT> Outlook = Microsoft.Office.Interop.Outlook;<BR></FONT><FONT color=#0000ff>using</FONT> Microsoft.Office.Interop.Outlook;</P></FONT></CODE>
<P>I'm not going to bore you with the entire application unless you really want it.&nbsp; I'll just get you to the point where you can start to do <EM>stuff</EM> with your e-mails.</P>
<P>Now you need to instantiate your Outlook object.</P><CODE>
<P>Outlook.</FONT><FONT color=#2b91af>Application</FONT> application = </FONT><FONT color=#0000ff>new</FONT> </FONT><FONT color=#2b91af>Application</FONT>();<BR>Outlook.</FONT><FONT color=#2b91af>NameSpace</FONT> nameSpace = application.GetNamespace(</FONT><FONT color=#a31515>"MAPI"</FONT>);<BR>Outlook.</FONT><FONT color=#2b91af>MAPIFolder</FONT> mapiFolder = nameSpace.GetDefaultFolder(</FONT><FONT color=#2b91af>OlDefaultFolders</FONT>.olFolderJunk);</P></FONT></CODE>
<P>It might be worth mentioning the olFolderJunk business you see there.&nbsp; In the interest of time I didn't want to mess around with trying to navigate to the folder that I actually stored these e-mails in since I have a bunch of subfolders in Outlook due to using multiple accounts and a handful of rules and what-not.&nbsp; So in the interest of time I moved all the e-mails to the junk folder since I could easily access it.&nbsp; I think the correct syntax would be something like:</P>
<P><CODE>nameSpace.Folders[<FONT color=#a52a2a>"FOLDER"</FONT>].Folders[<FONT color=#a52a2a>"SUB"</FONT>].Folders[<FONT color=#a52a2a>"YOU_GET_IT"</FONT>];</CODE></P>
<P>Moving on.&nbsp; Once you finally get access to your designated folder you need to start being able to do stuff with the items in that folder.&nbsp; It's as easy as enumerating the, you guessed it; <CODE>MailItem</CODE> objects a la:</P><CODE><FONT color=#0000ff>
<P>foreach</FONT> (</FONT><FONT color=#2b91af>MailItem</FONT> mailItem </FONT><FONT color=#0000ff>in</FONT> mapiFolder.Items)<BR>{<BR>&nbsp;&nbsp;&nbsp;<FONT color=#008000>// do stuff</FONT><BR></FONT>}</P></FONT></CODE>
<P>Easy.&nbsp; The properties are fairly braindead as well.&nbsp; <A href="http://msdn.microsoft.com/en-us/library/bb176688.aspx">MailItem Object Members</A></P>
<P>Have fun.&nbsp; I'll probably use this in the future as well.</P>http://www.willasrari.com/blog/microsoft-office-interop-outlook--c-for-outlook-searches/000330.aspx10/21/2008 1:32:06 PMWill AsrariDilbert & Agile Programming<p>Just saw this cartoon this morning. Late pass I'm sure ;)</p>
<P><IMG style="WIDTH: 494px; HEIGHT: 203px" height=182 alt="Dilbert &amp; Agile Programming" src="http://i37.tinypic.com/2wrn985.gif" width=460></P>http://www.willasrari.com/blog/dilbert--agile-programming/000329.aspx10/8/2008 2:50:00 PMWill AsrariSilverlight ObservableCollection Bug Will Be the Death of Me<P mce_keep="true"><STRONG>BUG:</STRONG> Items are sorted correctly sometimes, other times not so much.</P>
<P mce_keep="true"><STRONG>FREQUENCY: </STRONG>Intermittent, never when debugging and stepping through everything, always seems to happen when I'm not.</P>
<P mce_keep="true"><STRONG>RATING:</STRONG> Probably the most painful bug I've worked on in some time.</P>
<P mce_keep="true">So I've got an ItemsControl in a custom XAML user control.&nbsp; All this does is display an IEnumerable&lt;T&gt; of video items.&nbsp; Simple.&nbsp; To provide a better user experience we implemented an ObservableCollection&lt;T&gt; as the source of the ItemsControl with a Collection_Changed event so we can add one item at a time to the collection so as to not wait for the entire collection to populate before displaying to the user.&nbsp; Now we're able&nbsp;to display the first 2 items and the scrollbar height shrinks as items are being added.&nbsp; It's a nice user-experience.</P>
<P mce_keep="true">Anyway, so for the implementation.&nbsp; When the VideoRetrieveComplete event fires (after making a web service request for the data) we call the UpdateVideoCollection method.</P><CODE><FONT color=#2b91af>
<P>UIThread</FONT>.Run(</FONT><FONT color=#0000ff>delegate<BR></FONT>{<BR>&nbsp;&nbsp;&nbsp;videoListControl.UpdateVideos(args.VideoItems);<BR>&nbsp;&nbsp;&nbsp;videoListControl.itemsControlVideoListing.DataContext = </FONT><FONT color=#0000ff>new</FONT> </FONT><FONT color=#2b91af>VideoItem</FONT>();<BR>}</FONT></P></FONT></CODE>
<P>Notice that we're doing this in the UI Thread.&nbsp; The code above is located in our Controller class.&nbsp; The args.VideoItems is an IEnumerable&lt;VideoItem&gt; and they are sorted in the order they need to be in.&nbsp; I have verified this time and time again with painful debugging.</P>
<P>Now time for VideoList controls properties, objects, and methods:</P><CODE><FONT color=#0000ff>
<P>public</FONT> </FONT><FONT color=#0000ff>int</FONT> CurrentPageIndex { </FONT><FONT color=#0000ff>get</FONT>; </FONT><FONT color=#0000ff>set</FONT>; }<BR></FONT><FONT color=#0000ff>public</FONT> </FONT><FONT color=#2b91af>ObservableCollection</FONT>&lt;</FONT><FONT color=#2b91af>VideoItem</FONT>&gt; ObservableCollection { </FONT><FONT color=#0000ff>get</FONT>; </FONT><FONT color=#0000ff>set</FONT>; }<BR></FONT><FONT color=#0000ff>private</FONT> </FONT><FONT color=#2b91af>List</FONT>&lt;</FONT><FONT color=#2b91af>VideoItem</FONT>&gt; VideoItems = </FONT><FONT color=#0000ff>new</FONT> </FONT><FONT color=#2b91af>List</FONT>&lt;</FONT><FONT color=#2b91af>VideoItem</FONT>&gt;();</P></FONT></CODE>
<P>Constructor where everything is initialized.&nbsp; Probably important to include this.</P><CODE><FONT color=#0000ff>
<P>public</FONT> VideoList()<BR>{<BR>&nbsp;&nbsp;&nbsp;CurrentPageIndex = 0;<BR>&nbsp;&nbsp;&nbsp;InitializeComponent();<BR>&nbsp;&nbsp;&nbsp;ObservableCollection = </FONT><FONT color=#0000ff>new</FONT> </FONT><FONT color=#2b91af>ObservableCollection</FONT>&lt;</FONT><FONT color=#2b91af>VideoItem</FONT>&gt;();<BR>&nbsp;&nbsp;&nbsp;itemsControlVideoListing.ItemsSource = ObservableCollection;<BR>&nbsp;&nbsp;&nbsp;ObservableCollection.CollectionChanged += CollectionChanged;<BR>}</P></FONT></CODE><CODE><FONT color=#0000ff>
<P>public</FONT> </FONT><FONT color=#0000ff>void</FONT> UpdateVideos(</FONT><FONT color=#2b91af>List</FONT>&lt;</FONT><FONT color=#2b91af>VideoItem</FONT>&gt; videoItems)<BR>{<BR>&nbsp;&nbsp;&nbsp;</FONT><FONT color=#2b91af>UIThread</FONT>.Run(</FONT><FONT color=#0000ff>delegate<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</FONT>&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;VideoItems.AddRange(videoItems);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ObservableCollection.Clear();</P>
<P></FONT><FONT color=#0000ff>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if</FONT> (VideoItems != </FONT><FONT color=#0000ff>null</FONT> &amp;&amp; VideoItems.Count &gt; 0)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</FONT><FONT color=#2b91af>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;VideoItem</FONT> videoItem = VideoItems[0];<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;VideoItems.RemoveAt(0);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ObservableCollection.Add(videoItem);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;});<BR>}</P></FONT></CODE><CODE><FONT color=#0000ff>
<P>void</FONT> CollectionChanged(</FONT><FONT color=#0000ff>object</FONT> sender, </FONT><FONT color=#2b91af>NotifyCollectionChangedEventArgs</FONT> e)<BR>{<BR>&nbsp;&nbsp;&nbsp;</FONT><FONT color=#0000ff>if</FONT> (VideoItems.Count &gt; 0)<BR></FONT><FONT color=#2b91af>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;UIThread</FONT>.Run(</FONT><FONT color=#0000ff>delegate<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</FONT>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</FONT><FONT color=#2b91af>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;VideoItem</FONT> videoItem = VideoItems[0];<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;VideoItems.RemoveAt(0);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ObservableCollection.Add(videoItem);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;});<BR>}</P></FONT></CODE>
<P>The reason for removing an item, and then re-adding it is that this is the only way we can get our Converters to fire off, otherwise the collection hasn't changed and UI elements don't update.&nbsp; For example, switching between tabs the user can add videos to their playlist.&nbsp; Each time the tabs are selected and the VideoListing populates the VideoItems within that listing needs to show either an ADD / DELETE FROM PLAYLIST button depending on whether or not the item is in the playlist.&nbsp; If there's another way to get those Converters to fire off I'm all ears.</P>
<P>So the problem is that more often than not the videos, which come in sorted correctly, are not always displayed that way.&nbsp; For example, if I have&nbsp;5 videos with dates 10/1/2008, 10/1/2008, 9/30/2008, 9/29/2008, 9/28/2008 sometimes the sort will be:</P>
<P>10/1/2008<BR>9/30/2008<BR>9/29/2008<BR>9/28/2008<BR>10/1/2008</P>
<P>or:</P>
<P>9/30/2008<BR>9/29/2008<BR>10/1/2008<BR>9/28/2008<BR>10/1/2008</P>
<P>You get the idea.&nbsp; Could it be that we are not implementing this correctly?&nbsp; Do we need to rebind the ItemsControl or is this correct?</P>
<P>I've been working on this bug for a day and a half now and have nothing.&nbsp; I'm sure it's probably something stupid.</P>
<P>I'm all ears if you have anything. ANYTHING!</P>
<P>Oh, should probably add that if I page to the next listing of videos and then back it'll remedy itself!</P>http://www.willasrari.com/blog/silverlight-observablecollection-bug-will-be-the-death-of-me/000328.aspx10/2/2008 5:37:11 PMWill AsrariWhat's Wrong With This Picture?<P>Tried to debug a new Silverlight application today.&nbsp; By new I mean it was hosted in a different web project then the one I had been previously working on due to the fact that I needed to test some stuff locally.&nbsp; I was trying for about half an hour to get this thing to debug.&nbsp; The application would start to load up and then just hang on the loading animation.&nbsp; A co-worker told me to make sure I had the Silverlight debugger checkbox checked.&nbsp; I then go into the appropriate property tab and am greeted with this:</P>
<P><IMG alt="what's wrong with this picture? (image)" src="http://i37.tinypic.com/2ibndrc.png"></P>
<P>I remember this debugger option used to be located in the appropriate Debuggers group box.&nbsp; Apparently when I performed my Visual Studio 2008 and .NET Framework updates my Visual Studio 2008 UI ended up getting mutated.</P>
<P>Very strange.</P>http://www.willasrari.com/blog/whats-wrong-with-this-picture/000327.aspx10/1/2008 5:42:23 PMWill AsrariWay to Go Vista File Transfers!<P>Better grab a lunch, or 9.</P>
<P><img src="http://i35.tinypic.com/2vbv502.png" /></P>http://www.willasrari.com/blog/way-to-go-vista-file-transfers/000326.aspx9/18/2008 5:54:28 PMWill AsrariThe Zune Update Totally Sucks<P>Updated the Zune application software this morning at about 7:00am.&nbsp; Since I had no choice in the matter, I went ahead and did it ;)</P>
<P>Wow.&nbsp; Talk about a change... for the worst.&nbsp; The application seems to lag a lot even when I have nothing else open.&nbsp; If I try to listen to it with Visual Studio 2008, SQL Management Studio, and Outlook forget about it.&nbsp; Too bad because those are all the things I use on a daily basis for work.&nbsp; That's also when I listen to the most of my music.</P>
<P>Luckily I've got 4 stereos in the house wired up to my Zune player so depending on where in the house I'm working (laptop) I can listen to my music.&nbsp; I've also got 2 30GB zunes for this and am thinking of buying another when the new line is released (if it hasn't been already).</P>
<P>Like any Microsoft product there will be a patch released for the Zune software if enough people are experiencing these symptoms and at the end of the day I'm still glad I don't use any Apple products.</P>
<P>Does anyone else find that the Zune software responds a lot like a poorly-written RIA (rich internet application)?&nbsp; To me it responds like Silverlight applications do when they are first written; before any story board animations / overlays are added to let the user know that SOMETHING is actually happening.&nbsp; Just a thought....</P>
<P>If anyone from Zune reads this you might want to update the Zune Card widget (see left navigation column) to utilize Silverlight instead of Flash.&nbsp; It would probably be a good look since, you know; you're Microsoft and you have this new technology you want to promote.</P>
<P>Looks like I'll try this again later.&nbsp; Maybe rebooting (again) will help.</P>
<P><STRONG>UPDATE</STRONG><BR>Unresponsiveness of the application aside, the hardware update seems to be pretty sweet! Now I can play games while listening to tasty licks by The Chameleons.&nbsp; The wireless feature is pretty sweet. I wonder if I <EM>have</EM>&nbsp;to be at one of 9,800 McDonald's restaurants to be able to download?&nbsp; I'd guess not...</P>http://www.willasrari.com/blog/the-zune-update-totally-sucks/000325.aspx9/18/2008 12:42:02 PMWill AsrariNo Generic List FindAll Method in Silverlight 2 Beta 2<P>Came across a need this morning to use the <A href="http://msdn.microsoft.com/en-us/library/fh1w7y8z.aspx">FindAll</A> method. To my dismay it wasn't there.&nbsp; I know that Silverlight uses a subset of the .NET Framework but the System.Collections.Generic namespace is definitely there.</P>
<P><IMG alt="System.Collections.Generic namespace in Silverlight 2 Beta 2" src="http://i36.tinypic.com/20fbvpk.png"></P>
<P>You can clearly see that I'm using the namespace in the above image.</P>
<P><IMG alt="ReSharper List.FindAll Error Silverlight 2 Beta 2" src="http://i34.tinypic.com/35bcnxv.png"></P>
<P>Here you can see that ReSharper's background compiling caught it right away. For a second there I thought: "You know, maybe ReSharper is full of shit. This can't be right."&nbsp;I tried to compile to make sure (which was the case with the version 4 nightly builds).</P>
<P>
<BLOCKQUOTE><CODE>'System.Collections.Generic.List<STRING>' does not contain a definition for 'FindAll' and no extension method 'FindAll' accepting a first argument of type 'System.Collections.Generic.List<STRING>' could be found (are you missing a using directive or an assembly reference?)</CODE></BLOCKQUOTE>
<P></P>
<P>Weird.</P>http://www.willasrari.com/blog/no-generic-list-findall-method-in-silverlight-2-beta-2/000324.aspx9/4/2008 11:38:25 AMWill AsrariHacking Silverlight, ObservableCollections, & Scarface<P>In working with Silverlight lately I've found that there's not a lot of documentation, especially for more complex functionality.&nbsp; More times than not I find myself sort of scratching my head and wondering if the solution provided is really the best way to accomplish a certain task.</P>
<P>Let's say you're creating an application that serves up articles (i.e. for a library search application).&nbsp; You have an ItemsControl that uses a article item control as it's DataTemplate. The ItemsSource of this ItemsControl is an <A href="http://msdn.microsoft.com/en-us/library/ms668613.aspx">ObservableCollection</A>&lt;T&gt; of type, I don't know; SearchResult.&nbsp; The DataContext for your ItemsControl is, you guessed it; SearchResult.</P>
<P>Now say you have, above your search results, a little panel that provides filtering.&nbsp; The filters are List&lt;T&gt; -bound that expand&nbsp;when clicked (and roll up when done).&nbsp;In keeping with our library search application let's pretend the filters are by year (Last Week, Last Month, Last Year, Last 2 Years, etc....) and by topic (Sociology, Psychology, Political Science, Computer Science, etc..).&nbsp; The year filter allows you to select only one (the selection of a listitem triggers the list to hide and the listing of articles below to refresh).&nbsp; The user can select any number of topics.&nbsp; Each listitem in the topic filter has an overlay that provides button functionality such as "SELECT / DESELECT, CLEAR ALL, DONE".&nbsp; When you select an item, it highlights that row.&nbsp; DESELECT unhighlights the row.&nbsp; DONE means you are done selecting and rolls (hides) the list back up.&nbsp; CLEAR ALL&nbsp;is the problem child.&nbsp; Behind the scenes we are storing the id for the listitem in a List&lt;T&gt;.&nbsp; We have easy access to these on MouseLeftButtonUp due to our DataContext being set earlier.&nbsp; Clicking done will trigger the enumeration of this list to build our query and then that is sent to a web service.&nbsp; There is a subscription to the ArticleRefresh trigger and the ItemsControl listing is updated. Easy.</P>
<P>The issue is the unhighlighting of all the listitems&nbsp;in the topic list upon clicking CLEAR ALL.&nbsp; That sounds really easy (and it may very well be!) but I haven't seemed to figure out an efficient way to do this.</P>
<P>In ASP.NET it was extremely easy to enumerate all the controls from within, let's say a Repeater.&nbsp; You have in your ItemTemplate a control that you want to repeat.&nbsp; You could write a little bit of code to enumerate every RepeaterItem and alter the display of certain text and controls within that Repeater.&nbsp; It's extremely easy.</P>
<P>In Silverlight you don't have that luxury.&nbsp; Well, you're supposed to have an easier way of doing business but I haven't yet found it.&nbsp; By the way, I'm talking about Silverlight 2 Beta 2.&nbsp; </P>
<P>My first attempt at this was to create a Converter that sets the IsSelected property based on the presence of the topic's id in the List&lt;T&gt; it is bound to.&nbsp; I get a BAD_PROPERTY_VALUE error when that is attempted.</P>
<P>The next attempt was creating an event handler for the Loaded event of my topic filter control that will cast the sender to the filter object, check to see if the id of the objects DataContext is contained in the List&lt;T&gt;.&nbsp; If it is, highlight, else, no highlight.&nbsp; This works the first time the application is loaded but not on subsequent list views.&nbsp; Reason being the use of the ObservableCollection&lt;T&gt;.&nbsp; The collection itself hasn't changed, so no rebinding needs to occur.&nbsp; This is probably a good thing.&nbsp; What if the collection had 100's, 1000's of items?&nbsp; Makes for quick UI responsiveness.</P>
<P>The only way I have found to accomplish this is instantiating an IEnumerable object, setting its collection to that of the ObservableCollection&lt;T&gt; that the filter list is bound to (public property), then setting said public property&nbsp;to this IEnumerable object that is, in a sense, the same exact thing.&nbsp; This way the collection has changed (sort of), and the <A href="http://msdn.microsoft.com/en-us/library/ms653375.aspx">CollectionChanged</A>&nbsp;event now gets fired.&nbsp; The list is re-bound and we start from scratch with no highlighted rows.</P>
<P>That seems like kind of a hack to me.&nbsp; Anyone else care to chime in?</P>
<P>I'll try to get a code sample but this is one of those things that I had to voice out first.&nbsp; I hope it's not too hard to follow.&nbsp;&nbsp; For some reason today I had Paul Engemann's "Push it to the Limit" in my head while trying out all sorts of different ways of accomplishing this task.&nbsp; I kind of laughed to myself at the idea of a programming montage set to this song (kind of like in the South Park episode with the skiing contest. And, of course, <A href="http://en.wikipedia.org/wiki/Scarface_(1983_film)">Scarface</A>).</P>
<P>For the first time EVER on this blog, musical accompaniment:</P>
<P><EMBED src=http://www.youtube.com/v/hs510bgQa2I&amp;hl=en&amp;fs=1 width=425 height=344 type=application/x-shockwave-flash allowfullscreen="true"></P>http://www.willasrari.com/blog/hacking-silverlight-observablecollections--scarface/000323.aspx8/21/2008 10:18:26 PMWill Asrari