<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Jake Ginnivan - Blog</title>
	<atom:link href="http://jake.ginnivan.net/feed/" rel="self" type="application/rss+xml" />
	<link>http://jake.ginnivan.net</link>
	<description></description>
	<lastBuildDate>Fri, 29 Jan 2010 07:03:35 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Quake style Powershell console</title>
		<link>http://jake.ginnivan.net/2010/01/quake-style-powershell-console/</link>
		<comments>http://jake.ginnivan.net/2010/01/quake-style-powershell-console/#comments</comments>
		<pubDate>Fri, 29 Jan 2010 06:57:42 +0000</pubDate>
		<dc:creator>Jake Ginnivan</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Console]]></category>
		<category><![CDATA[Powershell]]></category>
		<category><![CDATA[Quake]]></category>

		<guid isPermaLink="false">http://jake.ginnivan.net/?p=55</guid>
		<description><![CDATA[I decided today that I wanted a quake style powershell console (with the classic win+` to activate or hide), and here is the end result:

I used http://www.instructables.com/id/&#8221;Drop-Down&#8221;,-Quake-style-command-prompt-for-Window/ as a template to get it all working, but wanted to use Console2 instead of v1.5 like this article uses.
What you need:
Download AutoHotKey
Download Console2
Instructions:
1. Extract the Console2\bin\release folder <a href="http://jake.ginnivan.net/2010/01/quake-style-powershell-console/" class="more-link">More &#62;</a>]]></description>
			<content:encoded><![CDATA[<p>I decided today that I wanted a quake style powershell console (with the classic win+` to activate or hide), and here is the end result:</p>
<p><a href="http://jake.ginnivan.net/Images/QuakestylePowershellconsole_D216/Capture.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="Capture" src="http://jake.ginnivan.net/Images/QuakestylePowershellconsole_D216/Capture_thumb.png" border="0" alt="Capture" width="605" height="336" /></a></p>
<p>I used <a href="http://www.instructables.com/id/%22Drop-Down%22,-Quake-style-command-prompt-for-Window/">http://www.instructables.com/id/&#8221;Drop-Down&#8221;,-Quake-style-command-prompt-for-Window/</a> as a template to get it all working, but wanted to use Console2 instead of v1.5 like this article uses.</p>
<h2>What you need:</h2>
<p>Download <a href="http://www.autohotkey.com/download/" target="_blank">AutoHotKey</a><br />
Download <a href="http://sourceforge.net/projects/console/" target="_blank">Console2</a></p>
<h2>Instructions:</h2>
<p>1. Extract the Console2\bin\release folder somewhere.<br />
2. Add the directory to your %path% (<a href="http://support.microsoft.com/kb/310519">http://support.microsoft.com/kb/310519</a>) or create a shortcut to Console.exe and place it in your windows directory.<br />
3. Download <a href="http://jake.ginnivan.net/Images/QuakestylePowershellconsole_D216/console.xml" target="_blank">console.xml</a> and <a href="http://jake.ginnivan.net/Images/QuakestylePowershellconsole_D216/QuakeMode.ahk" target="_blank">QuakeMode.ahk</a> and overwrite the original console.xml. Then edit console.xml and set the startup directory.</p>
<p>4. Right click on QuakeMode.ahk and run the script.</p>
<p>Now you can press win+` to open the console, esc or win+` to close again. Also right click on the console to access the settings to modify things like colour, window size etc etc.</p>
]]></content:encoded>
			<wfw:commentRss>http://jake.ginnivan.net/2010/01/quake-style-powershell-console/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Generic ClickOnce updates (With VSTO Support)</title>
		<link>http://jake.ginnivan.net/2010/01/generic-clickonce-updates-with-vsto-support/</link>
		<comments>http://jake.ginnivan.net/2010/01/generic-clickonce-updates-with-vsto-support/#comments</comments>
		<pubDate>Thu, 21 Jan 2010 03:16:13 +0000</pubDate>
		<dc:creator>Jake Ginnivan</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[ClickOnce]]></category>
		<category><![CDATA[VSTO]]></category>

		<guid isPermaLink="false">http://jake.ginnivan.net/?p=50</guid>
		<description><![CDATA[I use ClickOnce to publish all my applications I write internally, some of which are VSTO Outlook add-ins. The issue with the inbuilt ClickOnce updates is you have no control over it and it can slow start up time of your app.
So I wanted a generic class that I could put in my common library <a href="http://jake.ginnivan.net/2010/01/generic-clickonce-updates-with-vsto-support/" class="more-link">More &#62;</a>]]></description>
			<content:encoded><![CDATA[<p>I use ClickOnce to publish all my applications I write internally, some of which are VSTO Outlook add-ins. The issue with the inbuilt ClickOnce updates is you have no control over it and it can slow start up time of your app.</p>
<p>So I wanted a generic class that I could put in my common library and use in any of my applications, VSTO or normal. This is what I came up with:</p>
<p><a href="http://jake.ginnivan.net/wp-content/uploads/2010/01/image.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" src="http://jake.ginnivan.net/wp-content/uploads/2010/01/image_thumb.png" border="0" alt="image" width="424" height="324" /></a></p>
<p>This is the public interface, under the covers most of the functionality is declared as protected virtual so functionality can be changed (which I use to create my VSTODeploy class).</p>
<p>Usage:</p>
<pre class="brush: csharp;">var deployment = new Deploy();
deployment.CheckForUpdateAsync(result =&gt;     {      if (result.Updated)      {      MessageBox.Show(result.Message, "Application Updated",
                        MessageBoxButton.OK,
                        MessageBoxImage.Information);      }     });</pre>
<p>The base class is pretty simple and is just a nice wrapper for the ApplicationDeployment class. Where it gets tricky is updating VSTO applications, as the ApplicationDeployment.Update() method can corrupt your VSTO applications installation <img src='http://jake.ginnivan.net/wp-includes/images/smilies/icon_sad.gif' alt=':(' class='wp-smiley' />  Also because VSTO and .Net use a different security model, you will get exceptions as soon as you try to access the ApplicationDeployment information.</p>
<p>Kristopher Makey has a good solution to this problem and I used his solution and created my VSTODeploy class, which hides all the nasty implementation details, you can view his solution here: <a href="http://blogs.msdn.com/krimakey/archive/2008/04/18/click-once-forced-updates-in-vsto-ii-a-fuller-solution.aspx">http://blogs.msdn.com/krimakey/archive/2008/04/18/click-once-forced-updates-in-vsto-ii-a-fuller-solution.aspx</a></p>
<p>There are two main points that he covers, fixing the Trust and make sure you use VSTOInstaller.exe to install your update otherwise you can break everything.</p>
<p>Here is my VSTODeploy class, I welcome feedback, I also have included an Extensions.cs class in the zip file below which you will need to compile this code.</p>
<p>The main extension method to note is StartProcess, it wraps Process.Start nicely making it easy to capture output from the exe as well as the return code.</p>
<pre class="brush: csharp;">public class VSTODeploy: Deploy
{
    protected override UpdateResult UpdateApplication(ApplicationDeployment currentDeployment)
    {
        FixTrust(currentDeployment);
        return base.UpdateApplication(currentDeployment);
    }

    protected override bool UpdateCurrentDeployment(ApplicationDeployment deployment, ref string message)
    {
        //Call VSTOInstaller Explicitely in "Silent Mode"
        var installerArgs = string.Format(" /S /I {0}", deployment.UpdateLocation.AbsoluteUri);
        var installerPath = Directory.Exists(@"C:\Program Files (x86)")
                                ?
                                    @"C:\Program Files (x86)\Common Files\microsoft shared\VSTO\9.0\VSTOInstaller.exe"
                                :
                                    @"C:\Program Files\Common Files\microsoft shared\VSTO\9.0\VSTOInstaller.exe";

        var vstoInstallerOutput = new StringBuilder();

        var vstoStartInfo = new ProcessStartInfo(installerPath, installerArgs);
        var returnCode = vstoStartInfo.StartProcess((sender, e) =&gt; vstoInstallerOutput.Append(e.Data));

        message = vstoInstallerOutput.ToString();
        return returnCode == 0;
    }

    private static void FixTrust(ApplicationDeployment currentDeployment)
    {
        //Create the appropriate Trust settings so the Application can do
        //Click-Once Related updating
        var deploymentFullName = currentDeployment.UpdatedApplicationFullName;
        var appID = new ApplicationIdentity(deploymentFullName);
        var everything = new PermissionSet(PermissionState.Unrestricted);

        var trust = new ApplicationTrust(appID)
                        {
                            DefaultGrantSet = new PolicyStatement(everything),
                            IsApplicationTrustedToRun = true,
                            Persist = true
                        };

        ApplicationSecurityManager.UserApplicationTrusts.Add(trust);
    }
}</pre>
<div id="scid:fb3a1972-4489-4e52-abe7-25a00bb07fdf:a6f31d73-0486-4056-8c5c-61a03d86bc7d" class="wlWriterEditableSmartContent" style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px">
<p><a href="http://jake.ginnivan.net/wp-content/uploads/2010/01/DeploymentDemo.zip" target="_blank">Download demo project with source code</a></div>
]]></content:encoded>
			<wfw:commentRss>http://jake.ginnivan.net/2010/01/generic-clickonce-updates-with-vsto-support/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>WPF SQL Connection User Control</title>
		<link>http://jake.ginnivan.net/2009/09/wpf-sql-connection-user-control/</link>
		<comments>http://jake.ginnivan.net/2009/09/wpf-sql-connection-user-control/#comments</comments>
		<pubDate>Tue, 29 Sep 2009 12:25:01 +0000</pubDate>
		<dc:creator>Jake Ginnivan</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Connection String Builder]]></category>
		<category><![CDATA[MVVM]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[User Control]]></category>
		<category><![CDATA[WPF]]></category>

		<guid isPermaLink="false">http://jake.ginnivan.net/?p=25</guid>
		<description><![CDATA[Many of the apps I have written need to target multiple databases or I want the connection to be configurable by the user. I have a user control in my common library that I use all the time to let the user connect to a database.
You will need the Sql Management Objects from http://www.microsoft.com/Downloads/details.aspx?familyid=B33D2C78-1059-4CE2-B80D-2343C099BCB4&#38;displaylang=en to <a href="http://jake.ginnivan.net/2009/09/wpf-sql-connection-user-control/" class="more-link">More &#62;</a>]]></description>
			<content:encoded><![CDATA[<p><span style="background-color: #ffffff">Many of the apps I have written need to target multiple databases or I want the connection to be configurable by the user. I have a user control in my common library that I use all the time to let the user connect to a database.</span></p>
<p>You will need the Sql Management Objects from <a href="http://www.microsoft.com/Downloads/details.aspx?familyid=B33D2C78-1059-4CE2-B80D-2343C099BCB4&amp;displaylang=en" target="_blank">http://www.microsoft.com/Downloads/details.aspx?familyid=B33D2C78-1059-4CE2-B80D-2343C099BCB4&amp;displaylang=en</a> to compile the demo project.</p>
<p>I also make use of <a href="http://umbrella.codeplex.com/" target="_blank">http://umbrella.codeplex.com/</a> and <a href="http://www.codeplex.com/clinq" target="_blank">http://www.codeplex.com/clinq</a> in my common libraries, it should be quite simple to remove the dependencies on these two libraries if you wanted to. The first library adds a heap of really useful extension methods, like AddRange to collections that do not have it implemented. The second is all about reactive linq queries, if the underlying ObservableCollection changes any linq queries are automatically re-evaluated.</p>
<p>Features:</p>
<ul>
<li>Finds database instances on your Lan, these are stored statically so will only be loaded once during the application lifetime. </li>
<li>Will populate the databases on that SQL server. </li>
<li>Is easily extendable, you can expose other options within the control if you want. </li>
<li>Has a cool little loading circle I built included <img src='http://jake.ginnivan.net/wp-includes/images/smilies/icon_razz.gif' alt=':P' class='wp-smiley' />  </li>
<li>It uses a SqlConnectionString object which is much nicer than dealing with a SqlConnectionStringBuilder or a string. SqlConnectionString is also implicitly converts to a string so you can pass it directly to your SqlConnection constructor without .ToString() or casting. </li>
</ul>
<p>All in all, for small apps I think this makes connecting to a SQL database really easy!</p>
<p>Here are some examples of the control in use.</p>
<p><a href="http://jake.ginnivan.net/Images/WPFSQLConnectionUserControl_1251E/image.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://jake.ginnivan.net/Images/WPFSQLConnectionUserControl_1251E/image_thumb.png" width="303" height="303" /></a> <a href="http://jake.ginnivan.net/Images/WPFSQLConnectionUserControl_1251E/image_3.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://jake.ginnivan.net/Images/WPFSQLConnectionUserControl_1251E/image_thumb_3.png" width="303" height="304" /></a> <a href="http://jake.ginnivan.net/Images/WPFSQLConnectionUserControl_1251E/image_4.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://jake.ginnivan.net/Images/WPFSQLConnectionUserControl_1251E/image_thumb_4.png" width="304" height="304" /></a> <a href="http://jake.ginnivan.net/Images/WPFSQLConnectionUserControl_1251E/image_5.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://jake.ginnivan.net/Images/WPFSQLConnectionUserControl_1251E/image_thumb_5.png" width="568" height="309" /></a></p>
<p>And to show off the ability to add child content to the control:</p>
<pre class="brush:xml"><sqlconnectiondemo:sqlconnectionbuilder>
  <stackpanel>
      <checkbox margin="5" ischecked="{Binding ConnectionString.Pooling}" content="Enable connection Pooling" />
      <textblock margin="5"><hyperlink click="Hyperlink_Click">Test Connection</hyperlink></textblock>
  </stackpanel>
</sqlconnectiondemo:sqlconnectionbuilder></pre>
<p><a href="http://jake.ginnivan.net/Images/WPFSQLConnectionUserControl_1251E/image_6.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://jake.ginnivan.net/Images/WPFSQLConnectionUserControl_1251E/image_thumb_6.png" width="254" height="263" /></a> <a href="http://jake.ginnivan.net/Images/WPFSQLConnectionUserControl_1251E/image_7.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://jake.ginnivan.net/Images/WPFSQLConnectionUserControl_1251E/image_thumb_7.png" width="254" height="263" /></a></p>
<p>To add any options you want just inherit from or edit SqlConnectionBuilderViewModel.cs to add your own custom properties then bind to them.</p>
<h1>Adding child content</h1>
<p>It took me a little while to figure out how to force the content to be positioned in a certain place so I will quickly cover that.</p>
<p>I started off by creating a Footer DependencyProperty on the UserControl (I felt this was more a UI thing, so it is not in the ViewModel):</p>
<pre class="brush:csharp">public static readonly DependencyProperty FooterProperty =
    DependencyProperty.Register(&quot;Footer&quot;,
                                typeof(FrameworkElement),
                                typeof(SqlConnectionBuilder));

public FrameworkElement Footer
{
    get
    {
        return (FrameworkElement)GetValue(FooterProperty);
    }
    set
    {
        SetValue(FooterProperty, value);
    }
}</pre>
<p>And decorated the user control class with:</p>
<pre class="brush:csharp">[ContentProperty(&quot;Footer&quot;)]</pre>
<p>This means that if you set the content on the SqlConnectionBuilder then it will be assigned to the Footer property rather than replacing the content of our control =)</p>
<p>Then to top it off we just add a content presenter to our user control bound to the Footer property of our user control (you have to add x:Name=”_this” to the user control itself):</p>
<pre class="brush:xml">&lt;ContentPresenter Grid.Column=&quot;0&quot; Grid.Row=&quot;3&quot; Grid.ColumnSpan=&quot;3&quot; Content=&quot;{Binding ElementName=_this, Path=Footer}&quot; /&gt;</pre>
<h1>Download and licence</h1>
<p>I have added an extension method in for testing the database connection to the sample project. This is all released under the MIT licence so feel free to use it and give me feedback if you want. <img src='http://jake.ginnivan.net/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Just grab the code directly out of the demo project.</p>
<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:fb3a1972-4489-4e52-abe7-25a00bb07fdf:5fa83846-12ff-4ce8-8568-7a071f012995" class="wlWriterEditableSmartContent">
<p> <a href="http://jake.ginnivan.net/Images/WPFSQLConnectionUserControl_1251E/SqlConnectionDemo.rar" target="_blank">Download Demo Project</a></p>
</div>
]]></content:encoded>
			<wfw:commentRss>http://jake.ginnivan.net/2009/09/wpf-sql-connection-user-control/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Binding to WPF ListBox.SelectedItems</title>
		<link>http://jake.ginnivan.net/2009/09/binding-to-wpf-listbox-selecteditems/</link>
		<comments>http://jake.ginnivan.net/2009/09/binding-to-wpf-listbox-selecteditems/#comments</comments>
		<pubDate>Thu, 17 Sep 2009 06:33:42 +0000</pubDate>
		<dc:creator>Jake Ginnivan</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Data Binding]]></category>
		<category><![CDATA[WPF]]></category>

		<guid isPermaLink="false">http://jake.ginnivan.net/2009/09/binding-to-wpf-listbox-selecteditems/</guid>
		<description><![CDATA[I wanted to do this for one of my projects, the ability to bind a selecteditems collection on my view model to my view.
http://blog.functionalfun.net/2009/02/how-to-databind-to-selecteditems.html
It did the trick for me, simply use the attached property to bind the selected items to an ObservableCollection.
]]></description>
			<content:encoded><![CDATA[<p>I wanted to do this for one of my projects, the ability to bind a selecteditems collection on my view model to my view.</p>
<p><a href="http://blog.functionalfun.net/2009/02/how-to-databind-to-selecteditems.html" target="_blank">http://blog.functionalfun.net/2009/02/how-to-databind-to-selecteditems.html</a></p>
<p>It did the trick for me, simply use the attached property to bind the selected items to an ObservableCollection.</p>
]]></content:encoded>
			<wfw:commentRss>http://jake.ginnivan.net/2009/09/binding-to-wpf-listbox-selecteditems/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>ClickOnce Deployment in TeamCity</title>
		<link>http://jake.ginnivan.net/2009/08/clickonce-deployment-in-teamcity/</link>
		<comments>http://jake.ginnivan.net/2009/08/clickonce-deployment-in-teamcity/#comments</comments>
		<pubDate>Mon, 31 Aug 2009 07:24:58 +0000</pubDate>
		<dc:creator>Jake Ginnivan</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://jake.ginnivan.net/2009/08/clickonce-deployment-in-teamcity/</guid>
		<description><![CDATA[I have been trying to get a ClickOnce VSTO add-in publishing automatically during a build and do not want visual studio on my build server. 
This blog post was very useful for getting the initial build working http://abdullin.com/journal/2009/2/17/building-vsto-solutions-without-visual-studio.html it also mentions how to fix the error MSB3147: Could not find required file &#8217;setup.bin&#8217; in &#8216;ProjectFolder\Engine&#8217; <a href="http://jake.ginnivan.net/2009/08/clickonce-deployment-in-teamcity/" class="more-link">More &#62;</a>]]></description>
			<content:encoded><![CDATA[<p>I have been trying to get a ClickOnce VSTO add-in publishing automatically during a build and do not want visual studio on my build server. </p>
<p>This blog post was very useful for getting the initial build working <a href="http://abdullin.com/journal/2009/2/17/building-vsto-solutions-without-visual-studio.html">http://abdullin.com/journal/2009/2/17/building-vsto-solutions-without-visual-studio.html</a> it also mentions how to fix the error MSB3147: Could not find required file &#8217;setup.bin&#8217; in &#8216;ProjectFolder\Engine&#8217; error I was getting.</p>
<p>According to the post we just have to copy the Generic Bootstrapper across to our build machine and create a registry key to let .net know where to find it. </p>
<p>What all the resources (I have seen the same fix posted in a lot of places) fail to mention is the registry key that you need to modify if you are running a x64 system is HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\GenericBootstrapper\3.5.</p>
<p>This Wow6432Node key has got me a few times before…</p>
]]></content:encoded>
			<wfw:commentRss>http://jake.ginnivan.net/2009/08/clickonce-deployment-in-teamcity/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Using Windows Presentation Foundation and Line-of-Business Data in Microsoft Clients (Beth Massi)</title>
		<link>http://jake.ginnivan.net/2009/08/using-windows-presentation-foundation-and-line-of-business-data-in-microsoft-clients-beth-massi/</link>
		<comments>http://jake.ginnivan.net/2009/08/using-windows-presentation-foundation-and-line-of-business-data-in-microsoft-clients-beth-massi/#comments</comments>
		<pubDate>Wed, 12 Aug 2009 06:42:24 +0000</pubDate>
		<dc:creator>Jake Ginnivan</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Line-of-Business]]></category>
		<category><![CDATA[VSTO]]></category>
		<category><![CDATA[WPF]]></category>

		<guid isPermaLink="false">http://jake.ginnivan.net/2009/08/using-windows-presentation-foundation-and-line-of-business-data-in-microsoft-clients-beth-massi/</guid>
		<description><![CDATA[Beth Massi’s articles she wrote for SDN Magazine “Women in Technology” issue 101 has been put online. There are 5 parts and she is thinking about doing a 6th part on deployment.
Check out Beth’s post at http://blogs.msdn.com/bethmassi/archive/2009/08/10/using-windows-presentation-foundation-in-office-clients.aspx
You can also find the complete Demo application at http://code.msdn.microsoft.com/OBANorthwind. I am sure I will pick up a few <a href="http://jake.ginnivan.net/2009/08/using-windows-presentation-foundation-and-line-of-business-data-in-microsoft-clients-beth-massi/" class="more-link">More &#62;</a>]]></description>
			<content:encoded><![CDATA[<p>Beth Massi’s articles she wrote for SDN Magazine “Women in Technology” issue 101 has been put online. There are 5 parts and she is thinking about doing a 6th part on deployment.</p>
<p>Check out Beth’s post at <a href="http://blogs.msdn.com/bethmassi/archive/2009/08/10/using-windows-presentation-foundation-in-office-clients.aspx" target="_blank">http://blogs.msdn.com/bethmassi/archive/2009/08/10/using-windows-presentation-foundation-in-office-clients.aspx</a></p>
<p>You can also find the complete Demo application at <a href="http://code.msdn.microsoft.com/OBANorthwind" target="_blank">http://code.msdn.microsoft.com/OBANorthwind</a>. I am sure I will pick up a few neat tricks from this.</p>
]]></content:encoded>
			<wfw:commentRss>http://jake.ginnivan.net/2009/08/using-windows-presentation-foundation-and-line-of-business-data-in-microsoft-clients-beth-massi/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Remembering WPF Windows Position</title>
		<link>http://jake.ginnivan.net/2009/08/remembering-wpf-windows-position/</link>
		<comments>http://jake.ginnivan.net/2009/08/remembering-wpf-windows-position/#comments</comments>
		<pubDate>Thu, 06 Aug 2009 04:23:27 +0000</pubDate>
		<dc:creator>Jake Ginnivan</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Win32]]></category>
		<category><![CDATA[WPF]]></category>

		<guid isPermaLink="false">http://jake.ginnivan.net/2009/08/remembering-wpf-windows-position/</guid>
		<description><![CDATA[A few of my apps require opening the same window for a lot of different items and I wanted each WPF window to remember its size, position and state all the time. Nothing annoys me more than closing a window, opening the same window and its back on my second monitor.
So I went in search <a href="http://jake.ginnivan.net/2009/08/remembering-wpf-windows-position/" class="more-link">More &#62;</a>]]></description>
			<content:encoded><![CDATA[<p>A few of my apps require opening the same window for a lot of different items and I wanted each WPF window to remember its size, position and state all the time. Nothing annoys me more than closing a window, opening the same window and its back on my second monitor.</p>
<p>So I went in search of a solution that someone else had written first, I found a example on the <a href="http://msdn.microsoft.com/en-us/library/aa972163.aspx" target="_blank">MSDN website</a>.What makes this sample good is it makes use of the Win32 API’s, specifically GetWindowPlacement and SetWindowPlacement in User32.dll. Because of this our code doesn&#8217;t have to worry about missing second monitors, reduced resolution and other edge cases that can cause the normal headaches.</p>
<p>The <a href="http://bloggingabout.net/blogs/erwyn/archive/2007/02/01/remembering-window-positions-in-wpf.aspx" target="_blank">second example</a> I found has the idea of using attached properties, which I liked a lot.</p>
<p>The problem with the MSDN sample is you need to set up each window manually by overriding some of the Windows methods, the second solution did not cater for the edge cases. </p>
<p>Second example:   <br /><a href="http://jake.ginnivan.net/Images/RememberingWPFWindowsPosition_AF2B/image.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://jake.ginnivan.net/Images/RememberingWPFWindowsPosition_AF2B/image_thumb.png" width="607" height="143" /></a> </p>
</p>
<p>So lets get into how to put it together.</p>
<p>The first problem is persisting the data, I wanted to be able to store the position across sessions for multiple windows AND store the class in a reusable library. So I decided to create a internal ApplicationSettings class within my class to store each window, passing the Type.FullName of the window to the ApplicationSettings constructor to make sure settings names are not doubled up.</p>
</p>
<div style="padding-bottom: 5px; padding-left: 5px; width: 623px; padding-right: 5px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:10a91b3c-bb4c-4bff-bd78-87bc3075b11b" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: 300px; overflow: scroll; padding: 2px 5px; white-space: nowrap">
<p>  <span style="color:#0000ff">internal</span> <span style="color:#0000ff">class</span> <span style="color:#2b91af">WindowApplicationSettings</span> : <span style="color:#2b91af">ApplicationSettingsBase</span><br /> {<br />     <span style="color:#0000ff">public</span> WindowApplicationSettings(<span style="color:#2b91af">WindowSettings</span> windowSettings)<br />         : <span style="color:#0000ff">base</span>(windowSettings._window.GetType().FullName) <br />     {}</p>
<p>     [<span style="color:#2b91af">UserScopedSetting</span>]<br />     <span style="color:#0000ff">public</span> <span style="color:#2b91af">WINDOWPLACEMENT</span>? Placement<br />     {<br />         <span style="color:#0000ff">get</span><br />         {<br />             <span style="color:#0000ff">if</span> (<span style="color:#0000ff">this</span>[<span style="color:#a31515">"Placement"</span>] != <span style="color:#0000ff">null</span>)<br />                 <span style="color:#0000ff">return</span> ((<span style="color:#2b91af">WINDOWPLACEMENT</span>)<span style="color:#0000ff">this</span>[<span style="color:#a31515">"Placement"</span>]);<br />             <span style="color:#0000ff">return</span> <span style="color:#0000ff">null</span>;<br />         }<br />         <span style="color:#0000ff">set</span><br />         {<br />             <span style="color:#0000ff">this</span>[<span style="color:#a31515">"Placement"</span>] = <span style="color:#0000ff">value</span>;<br />         }<br />     }<br /> }  </p>
</div>
</div>
</div>
<p>Next we can create the attached property which when set to True hooks into the window it is attaching to and subscribes to the needed events.</p>
<div style="padding-bottom: 5px; padding-left: 5px; width: 623px; padding-right: 5px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:3431ce06-1487-4f59-b32c-97a2cc1c99fa" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: 300px; overflow: scroll; padding: 2px 5px; white-space: nowrap">
<p>  <span style="color:#0000ff">public</span> <span style="color:#0000ff">static</span> <span style="color:#0000ff">readonly</span> <span style="color:#2b91af">DependencyProperty</span> SaveProperty<br />    = <span style="color:#2b91af">DependencyProperty</span>.RegisterAttached(<span style="color:#a31515">&#8220;Save&#8221;</span>, <span style="color:#0000ff">typeof</span>(<span style="color:#0000ff">bool</span>), <span style="color:#0000ff">typeof</span>(<span style="color:#2b91af">WindowSettings</span>),<br />         <span style="color:#0000ff">new</span> <span style="color:#2b91af">FrameworkPropertyMetadata</span>(<span style="color:#0000ff">new</span> <span style="color:#2b91af">PropertyChangedCallback</span>(OnSaveInvalidated)));</p>
<p> <span style="color:#0000ff">private</span> <span style="color:#0000ff">static</span> <span style="color:#0000ff">void</span> OnSaveInvalidated(<span style="color:#2b91af">DependencyObject</span> dependencyObject, <span style="color:#2b91af">DependencyPropertyChangedEventArgs</span> e)<br /> {<br />     <span style="color:#0000ff">var</span> window = dependencyObject <span style="color:#0000ff">as</span> <span style="color:#2b91af">Window</span>;<br />     <span style="color:#0000ff">if</span> (window == <span style="color:#0000ff">null</span> || !((<span style="color:#0000ff">bool</span>) e.NewValue)) <span style="color:#0000ff">return</span>;<br />     <span style="color:#0000ff">var</span> settings = <span style="color:#0000ff">new</span> <span style="color:#2b91af">WindowSettings</span>(window);<br />     settings.Attach();<br /> }</p>
<p> <span style="color:#0000ff">private</span> <span style="color:#0000ff">void</span> Attach()<br /> {<br />     <span style="color:#0000ff">if</span> (_window == <span style="color:#0000ff">null</span>) <span style="color:#0000ff">return</span>;<br />     _window.Closing += WindowClosing;<br />     _window.SourceInitialized += WindowSourceInitialized;<br /> }</p>
<p> <span style="color:#0000ff">void</span> WindowSourceInitialized(<span style="color:#0000ff">object</span> sender, <span style="color:#2b91af">EventArgs</span> e)<br /> {<br />     LoadWindowState();<br /> }</p>
<p> <span style="color:#0000ff">private</span> <span style="color:#0000ff">void</span> WindowClosing(<span style="color:#0000ff">object</span> sender, <span style="color:#2b91af">CancelEventArgs</span> e)<br /> {<br />     SaveWindowState();<br />     _window.Closing -= WindowClosing;<br />     _window.SourceInitialized -= WindowSourceInitialized;<br />     _window = <span style="color:#0000ff">null</span>;<br /> }  </p>
</div>
</div>
</div>
<p>The key is the SourceInitialized event, it lets us know when the underlying Win32 Window is ready and we can make a call to SetWindowPlacement. </p>
<div style="padding-bottom: 5px; padding-left: 5px; width: 623px; padding-right: 5px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:87f9ab34-02c1-416b-ac9b-89b479b3cbc1" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: 300px; overflow: scroll; padding: 2px 5px; white-space: nowrap">
<p>  <span style="color:#0000ff">protected</span> <span style="color:#0000ff">virtual</span> <span style="color:#0000ff">void</span> LoadWindowState()<br /> {<br />     Settings.Reload();</p>
<p>     <span style="color:#0000ff">if</span> (Settings.Placement == <span style="color:#0000ff">null</span>) <span style="color:#0000ff">return</span>;<br />     <span style="color:#0000ff">try</span><br />     {<br />         <span style="color:#0000ff">var</span> wp = Settings.Placement.Value;</p>
<p>         wp.length = <span style="color:#2b91af">Marshal</span>.SizeOf(<span style="color:#0000ff">typeof</span> (<span style="color:#2b91af">WINDOWPLACEMENT</span>));<br />         wp.flags = 0;<br />         wp.showCmd = (wp.showCmd == SW_SHOWMINIMIZED ? SW_SHOWNORMAL : wp.showCmd);<br />         <span style="color:#0000ff">var</span> hwnd = <span style="color:#0000ff">new</span> <span style="color:#2b91af">WindowInteropHelper</span>(_window).Handle;<br />         SetWindowPlacement(hwnd, <span style="color:#0000ff">ref</span> wp);<br />     }<br />     <span style="color:#0000ff">catch</span> (<span style="color:#2b91af">Exception</span> ex)<br />     {<br />         <span style="color:#2b91af">Debug</span>.WriteLine(<span style="color:#0000ff">string</span>.Format(<span style="color:#a31515">&#8220;Failed to load window state:&#92;r&#92;n{0}&#8221;</span>, ex));<br />     }<br /> }</p>
<p> <span style="color:#0000ff">protected</span> <span style="color:#0000ff">virtual</span> <span style="color:#0000ff">void</span> SaveWindowState()<br /> {<br />     <span style="color:#2b91af">WINDOWPLACEMENT</span> wp;<br />     <span style="color:#0000ff">var</span> hwnd = <span style="color:#0000ff">new</span> <span style="color:#2b91af">WindowInteropHelper</span>(_window).Handle;<br />     GetWindowPlacement(hwnd, <span style="color:#0000ff">out</span> wp);<br />     Settings.Placement = wp;<br />     Settings.Save();<br /> }  </p>
</div>
</div>
</div>
<p> After we close the window we get this in our user.config file.  <br /> 
<div style="padding-bottom: 5px; padding-left: 5px; width: 623px; padding-right: 5px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:723a8d64-c935-4885-9fe0-ce5cfc28dbf6" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: 300px; overflow: scroll; padding: 2px 5px; white-space: nowrap">
<p>  <span style="color:#0000ff">&lt;</span><span style="color:#a31515">userSettings</span><span style="color:#0000ff">&gt;<br />         &lt;</span><span style="color:#a31515">ioWpf.WindowSettings_x002B_WindowApplicationSettings.ParameterPopulator.Views.MainView</span><span style="color:#0000ff">&gt;<br />             &lt;</span><span style="color:#a31515">setting</span><span style="color:#0000ff"> </span><span style="color:#ff0000">name</span><span style="color:#0000ff">=</span>&#8220;<span style="color:#0000ff">Placement</span>&#8220;<span style="color:#0000ff"> </span><span style="color:#ff0000">serializeAs</span><span style="color:#0000ff">=</span>&#8220;<span style="color:#0000ff">Xml</span>&#8220;<span style="color:#0000ff">&gt;<br />                 &lt;</span><span style="color:#a31515">value</span><span style="color:#0000ff">&gt;<br />                     &lt;</span><span style="color:#a31515">WINDOWPLACEMENT</span><span style="color:#0000ff"> </span><span style="color:#ff0000">xmlns:xsi</span><span style="color:#0000ff">=</span>&#8220;<span style="color:#0000ff">http://www.w3.org/2001/XMLSchema-instance</span>&#8220;<br /> <span style="color:#0000ff">                        </span><span style="color:#ff0000">xmlns:xsd</span><span style="color:#0000ff">=</span>&#8220;<span style="color:#0000ff">http://www.w3.org/2001/XMLSchema</span>&#8220;<span style="color:#0000ff">&gt;<br />                         &lt;</span><span style="color:#a31515">length</span><span style="color:#0000ff">&gt;</span>44<span style="color:#0000ff">&lt;/</span><span style="color:#a31515">length</span><span style="color:#0000ff">&gt;<br />                         &lt;</span><span style="color:#a31515">flags</span><span style="color:#0000ff">&gt;</span>0<span style="color:#0000ff">&lt;/</span><span style="color:#a31515">flags</span><span style="color:#0000ff">&gt;<br />                         &lt;</span><span style="color:#a31515">showCmd</span><span style="color:#0000ff">&gt;</span>1<span style="color:#0000ff">&lt;/</span><span style="color:#a31515">showCmd</span><span style="color:#0000ff">&gt;<br />                         &lt;</span><span style="color:#a31515">minPosition</span><span style="color:#0000ff">&gt;<br />                             &lt;</span><span style="color:#a31515">X</span><span style="color:#0000ff">&gt;</span>-1<span style="color:#0000ff">&lt;/</span><span style="color:#a31515">X</span><span style="color:#0000ff">&gt;<br />                             &lt;</span><span style="color:#a31515">Y</span><span style="color:#0000ff">&gt;</span>-1<span style="color:#0000ff">&lt;/</span><span style="color:#a31515">Y</span><span style="color:#0000ff">&gt;<br />                         &lt;/</span><span style="color:#a31515">minPosition</span><span style="color:#0000ff">&gt;<br />                         &lt;</span><span style="color:#a31515">maxPosition</span><span style="color:#0000ff">&gt;<br />                             &lt;</span><span style="color:#a31515">X</span><span style="color:#0000ff">&gt;</span>-1<span style="color:#0000ff">&lt;/</span><span style="color:#a31515">X</span><span style="color:#0000ff">&gt;<br />                             &lt;</span><span style="color:#a31515">Y</span><span style="color:#0000ff">&gt;</span>-1<span style="color:#0000ff">&lt;/</span><span style="color:#a31515">Y</span><span style="color:#0000ff">&gt;<br />                         &lt;/</span><span style="color:#a31515">maxPosition</span><span style="color:#0000ff">&gt;<br />                         &lt;</span><span style="color:#a31515">normalPosition</span><span style="color:#0000ff">&gt;<br />                             &lt;</span><span style="color:#a31515">Left</span><span style="color:#0000ff">&gt;</span>93<span style="color:#0000ff">&lt;/</span><span style="color:#a31515">Left</span><span style="color:#0000ff">&gt;<br />                             &lt;</span><span style="color:#a31515">Top</span><span style="color:#0000ff">&gt;</span>371<span style="color:#0000ff">&lt;/</span><span style="color:#a31515">Top</span><span style="color:#0000ff">&gt;<br />                             &lt;</span><span style="color:#a31515">Right</span><span style="color:#0000ff">&gt;</span>893<span style="color:#0000ff">&lt;/</span><span style="color:#a31515">Right</span><span style="color:#0000ff">&gt;<br />                             &lt;</span><span style="color:#a31515">Bottom</span><span style="color:#0000ff">&gt;</span>771<span style="color:#0000ff">&lt;/</span><span style="color:#a31515">Bottom</span><span style="color:#0000ff">&gt;<br />                         &lt;/</span><span style="color:#a31515">normalPosition</span><span style="color:#0000ff">&gt;<br />                     &lt;/</span><span style="color:#a31515">WINDOWPLACEMENT</span><span style="color:#0000ff">&gt;<br />                 &lt;/</span><span style="color:#a31515">value</span><span style="color:#0000ff">&gt;<br />             &lt;/</span><span style="color:#a31515">setting</span><span style="color:#0000ff">&gt;<br />         &lt;/</span><span style="color:#a31515">ioWpf.WindowSettings_x002B_WindowApplicationSettings.ParameterPopulator.Views.MainView</span><span style="color:#0000ff">&gt;<br />     &lt;/</span><span style="color:#a31515">userSettings</span><span style="color:#0000ff">&gt;</span>
</p>
</div>
</div>
</div>
<p>There you have it, both a simple and very robust way to remember WPF windows positions.</p>
<h1>Complete Source</h1>
<div style="padding-bottom: 5px; padding-left: 5px; width: 623px; padding-right: 5px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:5bf5b097-7162-40f0-b451-fd7f79a46487" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: 500px; overflow: scroll; padding: 2px 5px; white-space: nowrap">
<p>  <span style="color:#0000ff">using</span> System;<br /> <span style="color:#0000ff">using</span> System.ComponentModel;<br /> <span style="color:#0000ff">using</span> System.Configuration;<br /> <span style="color:#0000ff">using</span> System.Diagnostics;<br /> <span style="color:#0000ff">using</span> System.Runtime.InteropServices;<br /> <span style="color:#0000ff">using</span> System.Windows;<br /> <span style="color:#0000ff">using</span> System.Windows.Interop;</p>
<p> <span style="color:#0000ff">namespace</span> ioWpf<br /> {<br />     <span style="color:#808080">///</span><span style="color:#008000"> </span><span style="color:#808080">&lt;summary&gt;</span><br />     <span style="color:#808080">///</span><span style="color:#008000"> Persists a Window&#8217;s Size, Location and WindowState to UserScopeSettings </span><br />     <span style="color:#808080">///</span><span style="color:#008000"> </span><span style="color:#808080">&lt;/summary&gt;</span><br />     <span style="color:#0000ff">public</span> <span style="color:#0000ff">class</span> <span style="color:#2b91af">WindowSettings</span><br />     {<br />         [<span style="color:#2b91af">DllImport</span>(<span style="color:#a31515">"user32.dll"</span>)]<br />         <span style="color:#0000ff">static</span> <span style="color:#0000ff">extern</span> <span style="color:#0000ff">bool</span> SetWindowPlacement(<span style="color:#2b91af">IntPtr</span> hWnd, [<span style="color:#2b91af">In</span>] <span style="color:#0000ff">ref</span> <span style="color:#2b91af">WINDOWPLACEMENT</span> lpwndpl);</p>
<p>         [<span style="color:#2b91af">DllImport</span>(<span style="color:#a31515">"user32.dll"</span>)]<br />         <span style="color:#0000ff">static</span> <span style="color:#0000ff">extern</span> <span style="color:#0000ff">bool</span> GetWindowPlacement(<span style="color:#2b91af">IntPtr</span> hWnd, <span style="color:#0000ff">out</span> <span style="color:#2b91af">WINDOWPLACEMENT</span> lpwndpl);</p>
<p>         <span style="color:#008000">// ReSharper disable InconsistentNaming</span><br />         <span style="color:#0000ff">const</span> <span style="color:#0000ff">int</span> SW_SHOWNORMAL = 1;<br />         <span style="color:#0000ff">const</span> <span style="color:#0000ff">int</span> SW_SHOWMINIMIZED = 2;<br />         <span style="color:#008000">// ReSharper restore InconsistentNaming</span></p>
<p>         <span style="color:#0000ff">internal</span> <span style="color:#0000ff">class</span> <span style="color:#2b91af">WindowApplicationSettings</span> : <span style="color:#2b91af">ApplicationSettingsBase</span><br />         {<br />             <span style="color:#0000ff">public</span> WindowApplicationSettings(<span style="color:#2b91af">WindowSettings</span> windowSettings)<br />                 : <span style="color:#0000ff">base</span>(windowSettings._window.GetType().FullName) <br />             {}</p>
<p>             [<span style="color:#2b91af">UserScopedSetting</span>]<br />             <span style="color:#0000ff">public</span> <span style="color:#2b91af">WINDOWPLACEMENT</span>? Placement<br />             {<br />                 <span style="color:#0000ff">get</span><br />                 {<br />                     <span style="color:#0000ff">if</span> (<span style="color:#0000ff">this</span>[<span style="color:#a31515">"Placement"</span>] != <span style="color:#0000ff">null</span>)<br />                         <span style="color:#0000ff">return</span> ((<span style="color:#2b91af">WINDOWPLACEMENT</span>)<span style="color:#0000ff">this</span>[<span style="color:#a31515">"Placement"</span>]);<br />                     <span style="color:#0000ff">return</span> <span style="color:#0000ff">null</span>;<br />                 }<br />                 <span style="color:#0000ff">set</span><br />                 {<br />                     <span style="color:#0000ff">this</span>[<span style="color:#a31515">"Placement"</span>] = <span style="color:#0000ff">value</span>;<br />                 }<br />             }<br />         }<br />         <span style="color:#0000ff">private</span> <span style="color:#2b91af">Window</span> _window;</p>
<p>         <span style="color:#0000ff">public</span> WindowSettings(<span style="color:#2b91af">Window</span> window)<br />         {<br />             _window = window;<br />         }</p>
<p>         <span style="color:#0000ff">public</span> <span style="color:#0000ff">static</span> <span style="color:#0000ff">readonly</span> <span style="color:#2b91af">DependencyProperty</span> SaveProperty<br />            = <span style="color:#2b91af">DependencyProperty</span>.RegisterAttached(<span style="color:#a31515">&#8220;Save&#8221;</span>, <span style="color:#0000ff">typeof</span>(<span style="color:#0000ff">bool</span>), <span style="color:#0000ff">typeof</span>(<span style="color:#2b91af">WindowSettings</span>),<br />                 <span style="color:#0000ff">new</span> <span style="color:#2b91af">FrameworkPropertyMetadata</span>(<span style="color:#0000ff">new</span> <span style="color:#2b91af">PropertyChangedCallback</span>(OnSaveInvalidated)));</p>
<p>         <span style="color:#0000ff">private</span> <span style="color:#0000ff">static</span> <span style="color:#0000ff">void</span> OnSaveInvalidated(<span style="color:#2b91af">DependencyObject</span> dependencyObject, <span style="color:#2b91af">DependencyPropertyChangedEventArgs</span> e)<br />         {<br />             <span style="color:#0000ff">var</span> window = dependencyObject <span style="color:#0000ff">as</span> <span style="color:#2b91af">Window</span>;<br />             <span style="color:#0000ff">if</span> (window == <span style="color:#0000ff">null</span> || !((<span style="color:#0000ff">bool</span>) e.NewValue)) <span style="color:#0000ff">return</span>;<br />             <span style="color:#0000ff">var</span> settings = <span style="color:#0000ff">new</span> <span style="color:#2b91af">WindowSettings</span>(window);<br />             settings.Attach();<br />         }</p>
<p>         <span style="color:#0000ff">private</span> <span style="color:#0000ff">void</span> Attach()<br />         {<br />             <span style="color:#0000ff">if</span> (_window == <span style="color:#0000ff">null</span>) <span style="color:#0000ff">return</span>;<br />             _window.Closing += WindowClosing;<br />             _window.SourceInitialized += WindowSourceInitialized;<br />         }</p>
<p>         <span style="color:#0000ff">void</span> WindowSourceInitialized(<span style="color:#0000ff">object</span> sender, <span style="color:#2b91af">EventArgs</span> e)<br />         {<br />             LoadWindowState();<br />         }</p>
<p>         <span style="color:#0000ff">private</span> <span style="color:#0000ff">void</span> WindowClosing(<span style="color:#0000ff">object</span> sender, <span style="color:#2b91af">CancelEventArgs</span> e)<br />         {<br />             SaveWindowState();<br />             _window.Closing -= WindowClosing;<br />             _window.SourceInitialized -= WindowSourceInitialized;<br />             _window = <span style="color:#0000ff">null</span>;<br />         }</p>
<p>         <span style="color:#0000ff">protected</span> <span style="color:#0000ff">virtual</span> <span style="color:#0000ff">void</span> LoadWindowState()<br />         {<br />             Settings.Reload();</p>
<p>             <span style="color:#0000ff">if</span> (Settings.Placement == <span style="color:#0000ff">null</span>) <span style="color:#0000ff">return</span>;<br />             <span style="color:#0000ff">try</span><br />             {<br />                 <span style="color:#0000ff">var</span> wp = Settings.Placement.Value;</p>
<p>                 wp.length = <span style="color:#2b91af">Marshal</span>.SizeOf(<span style="color:#0000ff">typeof</span> (<span style="color:#2b91af">WINDOWPLACEMENT</span>));<br />                 wp.flags = 0;<br />                 wp.showCmd = (wp.showCmd == SW_SHOWMINIMIZED ? SW_SHOWNORMAL : wp.showCmd);<br />                 <span style="color:#0000ff">var</span> hwnd = <span style="color:#0000ff">new</span> <span style="color:#2b91af">WindowInteropHelper</span>(_window).Handle;<br />                 SetWindowPlacement(hwnd, <span style="color:#0000ff">ref</span> wp);<br />             }<br />             <span style="color:#0000ff">catch</span> (<span style="color:#2b91af">Exception</span> ex)<br />             {<br />                 <span style="color:#2b91af">Debug</span>.WriteLine(<span style="color:#0000ff">string</span>.Format(<span style="color:#a31515">&#8220;Failed to load window state:&#92;r&#92;n{0}&#8221;</span>, ex));<br />             }<br />         }</p>
<p>         <span style="color:#0000ff">protected</span> <span style="color:#0000ff">virtual</span> <span style="color:#0000ff">void</span> SaveWindowState()<br />         {<br />             <span style="color:#2b91af">WINDOWPLACEMENT</span> wp;<br />             <span style="color:#0000ff">var</span> hwnd = <span style="color:#0000ff">new</span> <span style="color:#2b91af">WindowInteropHelper</span>(_window).Handle;<br />             GetWindowPlacement(hwnd, <span style="color:#0000ff">out</span> wp);<br />             Settings.Placement = wp;<br />             Settings.Save();<br />         }</p>
<p>         <span style="color:#0000ff">private</span> <span style="color:#2b91af">WindowApplicationSettings</span> _windowApplicationSettings;</p>
<p>         <span style="color:#0000ff">internal</span> <span style="color:#0000ff">virtual</span> <span style="color:#2b91af">WindowApplicationSettings</span> CreateWindowApplicationSettingsInstance()<br />         {<br />             <span style="color:#0000ff">return</span> <span style="color:#0000ff">new</span> <span style="color:#2b91af">WindowApplicationSettings</span>(<span style="color:#0000ff">this</span>);<br />         }</p>
<p>         [<span style="color:#2b91af">Browsable</span>(<span style="color:#0000ff">false</span>)]<br />         <span style="color:#0000ff">internal</span> <span style="color:#2b91af">WindowApplicationSettings</span> Settings<br />         {<br />             <span style="color:#0000ff">get</span><br />             {<br />                 <span style="color:#0000ff">if</span> (_windowApplicationSettings == <span style="color:#0000ff">null</span>)<br />                 {<br />                     _windowApplicationSettings = CreateWindowApplicationSettingsInstance();<br />                 }<br />                 <span style="color:#0000ff">return</span> _windowApplicationSettings;<br />             }<br />         }<br />     }</p>
<p>     <span style="color:#008000">// ReSharper disable InconsistentNaming</span><br />     <span style="color:#008000">// RECT structure required by WINDOWPLACEMENT structure</span><br />     [<span style="color:#2b91af">Serializable</span>]<br />     [<span style="color:#2b91af">StructLayout</span>(<span style="color:#2b91af">LayoutKind</span>.Sequential)]<br />     <span style="color:#0000ff">public</span> <span style="color:#0000ff">struct</span> <span style="color:#2b91af">RECT</span><br />     {<br />         <span style="color:#0000ff">private</span> <span style="color:#0000ff">int</span> _left;<br />         <span style="color:#0000ff">private</span> <span style="color:#0000ff">int</span> _top;<br />         <span style="color:#0000ff">private</span> <span style="color:#0000ff">int</span> _right;<br />         <span style="color:#0000ff">private</span> <span style="color:#0000ff">int</span> _bottom;</p>
<p>         <span style="color:#0000ff">public</span> RECT(<span style="color:#0000ff">int</span> left, <span style="color:#0000ff">int</span> top, <span style="color:#0000ff">int</span> right, <span style="color:#0000ff">int</span> bottom)<br />         {<br />             _left = left;<br />             _top = top;<br />             _right = right;<br />             _bottom = bottom;<br />         }</p>
<p>         <span style="color:#0000ff">public</span> <span style="color:#0000ff">override</span> <span style="color:#0000ff">bool</span> Equals(<span style="color:#0000ff">object</span> obj)<br />         {<br />             <span style="color:#0000ff">if</span> (obj <span style="color:#0000ff">is</span> <span style="color:#2b91af">RECT</span>)<br />             {<br />                 <span style="color:#0000ff">var</span> rect = (<span style="color:#2b91af">RECT</span>)obj;</p>
<p>                 <span style="color:#0000ff">return</span> rect._bottom == _bottom &amp;&amp;<br />                        rect._left == _left &amp;&amp;<br />                        rect._right == _right &amp;&amp;<br />                        rect._top == _top;<br />             }<br />             <span style="color:#0000ff">return</span> <span style="color:#0000ff">base</span>.Equals(obj);<br />         }</p>
<p>         <span style="color:#0000ff">public</span> <span style="color:#0000ff">override</span> <span style="color:#0000ff">int</span> GetHashCode()<br />         {<br />             <span style="color:#0000ff">return</span> _bottom.GetHashCode() ^<br />                    _left.GetHashCode() ^<br />                    _right.GetHashCode() ^<br />                    _top.GetHashCode();<br />         }</p>
<p>         <span style="color:#0000ff">public</span> <span style="color:#0000ff">static</span> <span style="color:#0000ff">bool</span> <span style="color:#0000ff">operator</span> ==(<span style="color:#2b91af">RECT</span> a, <span style="color:#2b91af">RECT</span> b)<br />         {<br />             <span style="color:#0000ff">return</span> a._bottom == b._bottom &amp;&amp;<br />                    a._left == b._left &amp;&amp;<br />                    a._right == b._right &amp;&amp;<br />                    a._top == b._top;<br />         }</p>
<p>         <span style="color:#0000ff">public</span> <span style="color:#0000ff">static</span> <span style="color:#0000ff">bool</span> <span style="color:#0000ff">operator</span> !=(<span style="color:#2b91af">RECT</span> a, <span style="color:#2b91af">RECT</span> b)<br />         {<br />             <span style="color:#0000ff">return</span> !(a == b);<br />         }</p>
<p>         <span style="color:#0000ff">public</span> <span style="color:#0000ff">int</span> Left<br />         {<br />             <span style="color:#0000ff">get</span> { <span style="color:#0000ff">return</span> _left; }<br />             <span style="color:#0000ff">set</span> { _left = <span style="color:#0000ff">value</span>; }<br />         }</p>
<p>         <span style="color:#0000ff">public</span> <span style="color:#0000ff">int</span> Top<br />         {<br />             <span style="color:#0000ff">get</span> { <span style="color:#0000ff">return</span> _top; }<br />             <span style="color:#0000ff">set</span> { _top = <span style="color:#0000ff">value</span>; }<br />         }</p>
<p>         <span style="color:#0000ff">public</span> <span style="color:#0000ff">int</span> Right<br />         {<br />             <span style="color:#0000ff">get</span> { <span style="color:#0000ff">return</span> _right; }<br />             <span style="color:#0000ff">set</span> { _right = <span style="color:#0000ff">value</span>; }<br />         }</p>
<p>         <span style="color:#0000ff">public</span> <span style="color:#0000ff">int</span> Bottom<br />         {<br />             <span style="color:#0000ff">get</span> { <span style="color:#0000ff">return</span> _bottom; }<br />             <span style="color:#0000ff">set</span> { _bottom = <span style="color:#0000ff">value</span>; }<br />         }<br />     }</p>
<p>     <span style="color:#008000">// POINT structure required by WINDOWPLACEMENT structure</span><br />     [<span style="color:#2b91af">Serializable</span>]<br />     [<span style="color:#2b91af">StructLayout</span>(<span style="color:#2b91af">LayoutKind</span>.Sequential)]<br />     <span style="color:#0000ff">public</span> <span style="color:#0000ff">struct</span> <span style="color:#2b91af">POINT</span><br />     {<br />         <span style="color:#0000ff">private</span> <span style="color:#0000ff">int</span> _x;<br />         <span style="color:#0000ff">private</span> <span style="color:#0000ff">int</span> _y;</p>
<p>         <span style="color:#0000ff">public</span> POINT(<span style="color:#0000ff">int</span> x, <span style="color:#0000ff">int</span> y)<br />         {<br />             _x = x;<br />             _y = y;<br />         }</p>
<p>         <span style="color:#0000ff">public</span> <span style="color:#0000ff">int</span> X<br />         {<br />             <span style="color:#0000ff">get</span> { <span style="color:#0000ff">return</span> _x; }<br />             <span style="color:#0000ff">set</span> { _x = <span style="color:#0000ff">value</span>; }<br />         }</p>
<p>         <span style="color:#0000ff">public</span> <span style="color:#0000ff">int</span> Y<br />         {<br />             <span style="color:#0000ff">get</span> { <span style="color:#0000ff">return</span> _y; }<br />             <span style="color:#0000ff">set</span> { _y = <span style="color:#0000ff">value</span>; }<br />         }</p>
<p>         <span style="color:#0000ff">public</span> <span style="color:#0000ff">override</span> <span style="color:#0000ff">bool</span> Equals(<span style="color:#0000ff">object</span> obj)<br />         {<br />             <span style="color:#0000ff">if</span> (obj <span style="color:#0000ff">is</span> <span style="color:#2b91af">POINT</span>)<br />             {<br />                 <span style="color:#0000ff">var</span> point = (<span style="color:#2b91af">POINT</span>)obj;</p>
<p>                 <span style="color:#0000ff">return</span> point._x == _x &amp;&amp; point._y == _y;<br />             }<br />             <span style="color:#0000ff">return</span> <span style="color:#0000ff">base</span>.Equals(obj);<br />         }<br />         <span style="color:#0000ff">public</span> <span style="color:#0000ff">override</span> <span style="color:#0000ff">int</span> GetHashCode()<br />         {<br />             <span style="color:#0000ff">return</span> _x.GetHashCode() ^ _y.GetHashCode();<br />         }</p>
<p>         <span style="color:#0000ff">public</span> <span style="color:#0000ff">static</span> <span style="color:#0000ff">bool</span> <span style="color:#0000ff">operator</span> ==(<span style="color:#2b91af">POINT</span> a, <span style="color:#2b91af">POINT</span> b)<br />         {<br />             <span style="color:#0000ff">return</span> a._x == b._x &amp;&amp; a._y == b._y;<br />         }</p>
<p>         <span style="color:#0000ff">public</span> <span style="color:#0000ff">static</span> <span style="color:#0000ff">bool</span> <span style="color:#0000ff">operator</span> !=(<span style="color:#2b91af">POINT</span> a, <span style="color:#2b91af">POINT</span> b)<br />         {<br />             <span style="color:#0000ff">return</span> !(a == b);<br />         }<br />     }</p>
<p>     <span style="color:#008000">// WINDOWPLACEMENT stores the position, size, and state of a window</span><br />     [<span style="color:#2b91af">Serializable</span>]<br />     [<span style="color:#2b91af">StructLayout</span>(<span style="color:#2b91af">LayoutKind</span>.Sequential)]<br />     <span style="color:#0000ff">public</span> <span style="color:#0000ff">struct</span> <span style="color:#2b91af">WINDOWPLACEMENT</span><br />     {<br />         <span style="color:#0000ff">public</span> <span style="color:#0000ff">int</span> length;<br />         <span style="color:#0000ff">public</span> <span style="color:#0000ff">int</span> flags;<br />         <span style="color:#0000ff">public</span> <span style="color:#0000ff">int</span> showCmd;<br />         <span style="color:#0000ff">public</span> <span style="color:#2b91af">POINT</span> minPosition;<br />         <span style="color:#0000ff">public</span> <span style="color:#2b91af">POINT</span> maxPosition;<br />         <span style="color:#0000ff">public</span> <span style="color:#2b91af">RECT</span> normalPosition;<br />     }<br />     <span style="color:#008000">// ReSharper restore InconsistentNaming</span><br /> }  </p>
</div>
</div>
</div>
]]></content:encoded>
			<wfw:commentRss>http://jake.ginnivan.net/2009/08/remembering-wpf-windows-position/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Writing a Facebook event synchroniser for Outlook 2007+ Part 2</title>
		<link>http://jake.ginnivan.net/2009/07/writing-a-facebook-event-synchroniser-for-outlook-2007-part-2/</link>
		<comments>http://jake.ginnivan.net/2009/07/writing-a-facebook-event-synchroniser-for-outlook-2007-part-2/#comments</comments>
		<pubDate>Mon, 27 Jul 2009 14:52:11 +0000</pubDate>
		<dc:creator>Jake Ginnivan</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[ClickOnce]]></category>
		<category><![CDATA[Facebook]]></category>
		<category><![CDATA[Office 2010]]></category>
		<category><![CDATA[VSTO]]></category>
		<category><![CDATA[WPF]]></category>

		<guid isPermaLink="false">http://jake.ginnivan.net/?p=17</guid>
		<description><![CDATA[Now for the juicy post, this will cover the nuts and bolts of putting it all together. I may make a part 3 once I have the time to clean up the code, add logging and other things. The aim of the project after this post is simply to be able to sync and change <a href="http://jake.ginnivan.net/2009/07/writing-a-facebook-event-synchroniser-for-outlook-2007-part-2/" class="more-link">More &#62;</a>]]></description>
			<content:encoded><![CDATA[<p>Now for the juicy post, this will cover the nuts and bolts of putting it all together. I may make a part 3 once I have the time to clean up the code, add logging and other things. The aim of the project after this post is simply to be able to sync and change your RSVP status of a event (if they update their API! See below. </p>
<p>(Installer/Source available at end of post)</p>
<h4></h4>
<h2>API Restrictions</h2>
<p>Facebook have decided that only an admin of a event can RSVP through the API, sorry guys this is something that cannot be done through the API! A search through the Facebook developer forum for RSVP results in many annoyed people.</p>
<p><a href="http://bugs.developers.facebook.com/show_bug.cgi?id=4462">http://bugs.developers.facebook.com/show_bug.cgi?id=4462</a></p>
<p>There are already close on 2500 votes for them to allow this feature, hopefully they remove the restrictions soon…</p>
<h2>Toolbar</h2>
<p>To start off I just want a simple toolbar which I can put a few buttons on, and it needs to remember is position so the user has a consistent experience, no one likes a toolbar that will not stay where you put it!</p>
<p><a href="http://jake.ginnivan.net/Images/WritingaFacebookeventsynchroniserforOutl_A789/image.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://jake.ginnivan.net/Images/WritingaFacebookeventsynchroniserforOutl_A789/image_thumb.png" width="538" height="173" /></a></p>
<p>When you register a toolbar in office you can register it as a temporary toolbar, so it will not persist after outlook is closed, or a permanent toolbar. The problem with the permanent one is you have to loop through all explorers and inspectors then the associated toolbars within them to find your toolbar if you ever want to remove it. I find it much easier to rebuild the toolbar on start-up, the above application settings are used simply to remember the toolbar position.</p>
<p>I have found it easier to create a static class with a Install method which creates the toolbar and registers all events etc. When creating your toolbar buttons if you want them to have a image you need to know the faceId, which is a pain. The best site I have found is: <a href="http://www.kebabshopblues.co.uk/2007/01/04/visual-studio-2005-tools-for-office-commandbarbutton-faceid-property/">http://www.kebabshopblues.co.uk/2007/01/04/visual-studio-2005-tools-for-office-commandbarbutton-faceid-property/</a></p>
<p>I have referenced this blog post many many times when creating toolbars. I have started off creating two buttons configuration and log now we have out toolbar:</p>
<p><a href="http://jake.ginnivan.net/Images/WritingaFacebookeventsynchroniserforOutl_A789/image_3.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://jake.ginnivan.net/Images/WritingaFacebookeventsynchroniserforOutl_A789/image_thumb_3.png" width="153" height="38" /></a></p>
<h2></h2>
<h2>Create the configuration dialog</h2>
<p>The first thing you will notice there is no WPF window template available for a VSTO add-in. I have not bothered to figure out how to install one, instead I just add a WPF user control then change the type to a window. Then remove the redundant inheritance from the code behind leaving just the partial class.</p>
<div style="padding-bottom: 5px; padding-left: 5px; width: 623px; padding-right: 5px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:5d52760f-b40d-4357-b63e-881be9ea4149" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: 300px; overflow: scroll; padding: 2px 5px; white-space: wrap">
<p>  <span style="color:#0000ff">&lt;</span><span style="color:#a31515">Window</span><span style="color:#ff0000"> x</span><span style="color:#0000ff">:</span><span style="color:#ff0000">Class</span><span style="color:#0000ff">=&#8221;FacebookSync.Views.ConfigurationView&#8221;</span><br />    <span style="color:#ff0000"> xmlns</span><span style="color:#0000ff">=&#8221;http://schemas.microsoft.com/winfx/2006/xaml/presentation&#8221;</span><br />    <span style="color:#ff0000"> xmlns</span><span style="color:#0000ff">:</span><span style="color:#ff0000">x</span><span style="color:#0000ff">=&#8221;http://schemas.microsoft.com/winfx/2006/xaml&#8221;</span><br />    <span style="color:#ff0000"> Height</span><span style="color:#0000ff">=&#8221;300&#8243;</span><span style="color:#ff0000"> Width</span><span style="color:#0000ff">=&#8221;300&#8243;&gt;<br /> </span><span style="color:#a31515">    </span><span style="color:#0000ff">&lt;</span><span style="color:#a31515">Grid</span><span style="color:#0000ff">&gt;<br /> </span><span style="color:#a31515">        <br />     </span><span style="color:#0000ff">&lt;/</span><span style="color:#a31515">Grid</span><span style="color:#0000ff">&gt;<br /> &lt;/</span><span style="color:#a31515">Window</span><span style="color:#0000ff">&gt;<br /> </span>
</p>
</div>
</div>
</div>
<div style="padding-bottom: 5px; padding-left: 5px; width: 623px; padding-right: 5px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:f2789f50-f256-41e0-aea3-96b25e9e61ff" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: 300px; overflow: scroll; padding: 2px 5px; white-space: nowrap">
<p>  <span style="color:#0000ff">namespace</span> FacebookSync.Views<br /> {<br />     <span style="color:#0000ff">public</span> <span style="color:#0000ff">partial</span> <span style="color:#0000ff">class</span> <span style="color:#2b91af">ConfigurationView</span><br />     {<br />         <span style="color:#0000ff">public</span> ConfigurationView()<br />         {<br />             InitializeComponent();<br />         }<br />     }<br /> }  </p>
</div>
</div>
</div>
<p>If we add some text to our window now:</p>
<div style="padding-bottom: 5px; padding-left: 5px; width: 623px; padding-right: 5px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:190ed6c7-6349-4553-8b71-ae396b50b5aa" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: 300px; overflow: scroll; padding: 2px 5px; white-space: wrap">
<p>  <span style="color:#0000ff">&lt;</span><span style="color:#a31515">TextBlock</span><span style="color:#ff0000"> Text</span><span style="color:#0000ff">=&#8221;Hello world&#8221; /&gt;</span>
</p>
</div>
</div>
</div>
<p>Now we can handle the Click event on our configuration:</p>
<div style="padding-bottom: 5px; padding-left: 5px; width: 623px; padding-right: 5px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:98d3e7ce-b253-4f44-9a84-4f6d30832d45" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: 300px; overflow: scroll; padding: 2px 5px; white-space: nowrap">
<p>  <span style="color:#0000ff">private</span> <span style="color:#0000ff">static</span> <span style="color:#0000ff">void</span> ConfigButtonClick(<span style="color:#0000ff">object</span> sender, <span style="color:#2b91af">CommandBarEventArgs</span> e)<br /> {<br />     <span style="color:#0000ff">var</span> configurationViewModel = <span style="color:#0000ff">new</span> <span style="color:#2b91af">ConfigurationViewModel</span>(<span style="color:#2b91af">Globals</span>.ThisAddIn.Settings);<br />     <span style="color:#0000ff">var</span> configurationView = <span style="color:#0000ff">new</span> <span style="color:#2b91af">ConfigurationView</span> {DataContext = configurationViewModel};<br />     configurationView.ShowDialog();<br /> }  </p>
</div>
</div>
</div>
<p>And the result we have a WPF window running inside outlook! One cool thing over Winforms is the WPF windows get the Outlook Icon <img src='http://jake.ginnivan.net/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p><a href="http://jake.ginnivan.net/Images/WritingaFacebookeventsynchroniserforOutl_A789/image_4.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://jake.ginnivan.net/Images/WritingaFacebookeventsynchroniserforOutl_A789/image_thumb_4.png" width="192" height="110" /></a></p>
<h2></h2>
<h2>Configuration View Model</h2>
<p>I have written a Settings class which creates a appointment far into the future in your outlook calendar which I can store simple settings. I wanted to store settings within outlook so it keeps your settings within exchange. Here is an example of a setting.</p>
<div style="padding-bottom: 5px; padding-left: 5px; width: 623px; padding-right: 5px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:2b38f78f-0794-4e5b-bd13-edf016deb1b2" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: 300px; overflow: scroll; padding: 2px 5px; white-space: nowrap">
<p>  <span style="color:#0000ff">public</span> <span style="color:#2b91af">SyncMode</span> SyncMode<br /> {<br />     <span style="color:#0000ff">get</span><br />     {<br />         <span style="color:#0000ff">string</span> syncModeSetting = _settings.ReadSetting(<span style="color:#a31515">&#8220;SyncMode&#8221;</span>);<br />         <span style="color:#0000ff">int</span> syncMode;</p>
<p>         <span style="color:#0000ff">if</span> (syncModeSetting == <span style="color:#0000ff">null</span> || !<span style="color:#0000ff">int</span>.TryParse(syncModeSetting, <span style="color:#0000ff">out</span> syncMode))<br />             <span style="color:#0000ff">return</span> <span style="color:#2b91af">SyncMode</span>.Manual;</p>
<p>         <span style="color:#0000ff">return</span> (<span style="color:#2b91af">SyncMode</span>)syncMode;<br />     }<br />     <span style="color:#0000ff">set</span><br />     {<br />         _settings.WriteSetting(<span style="color:#a31515">&#8220;SyncMode&#8221;</span>, ((<span style="color:#0000ff">int</span>)<span style="color:#0000ff">value</span>).ToString());<br />         OnPropertyChanged(<span style="color:#a31515">&#8220;SyncMode&#8221;</span>);<br />     }<br /> }  </p>
</div>
</div>
</div>
<h2>Retrieving events from Facebook</h2>
<p>The API does not return the Rsvp status of an a event when you get the list of events, so we have to make 4 calls to Facebook with a filter on the Rsvp status then wrap the facebookevent with our own facebookEvent class which has a Rsvp field. This all happens on a background thread so we don’t have to worry about slowing down Outlook.</p>
<div style="padding-bottom: 5px; padding-left: 5px; width: 623px; padding-right: 5px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:6a2418db-019e-4204-b923-40b5a86fbb4f" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: 300px; overflow: scroll; padding: 2px 5px; white-space: nowrap">
<p>  <span style="color:#0000ff">public</span> <span style="color:#2b91af">IList</span>&lt;<span style="color:#2b91af">UserFacebookEvent</span>&gt; GetEvents()<br /> {<br />     <span style="color:#0000ff">var</span> api = <span style="color:#0000ff">new</span> facebook.<span style="color:#2b91af">API</span><br />                   {<br />                       ApplicationKey = ApiKey,<br />                       Secret = Secret<br />                   };<br />     api.ConnectToFacebook();</p>
<p>     <span style="color:#0000ff">var</span> events = <span style="color:#0000ff">new</span> <span style="color:#2b91af">List</span>&lt;<span style="color:#2b91af">UserFacebookEvent</span>&gt; ();</p>
<p>     events.AddRange(<br />         api<br />         .events<br />         .get(<span style="color:#0000ff">null</span>, <span style="color:#0000ff">null</span>, <span style="color:#2b91af">DateTime</span>.Now, <span style="color:#0000ff">null</span>, <span style="color:#a31515">&#8220;attending&#8221;</span>)<br />         .Select(e =&gt; <span style="color:#0000ff">new</span> <span style="color:#2b91af">UserFacebookEvent</span>(e, <span style="color:#2b91af">RsvpStatus</span>.Attending)));</p>
<p>     events.AddRange(<br />         api<br />         .events<br />         .get(<span style="color:#0000ff">null</span>, <span style="color:#0000ff">null</span>, <span style="color:#2b91af">DateTime</span>.Now, <span style="color:#0000ff">null</span>, <span style="color:#a31515">&#8220;unsure&#8221;</span>)<br />         .Select(e =&gt; <span style="color:#0000ff">new</span> <span style="color:#2b91af">UserFacebookEvent</span>(e, <span style="color:#2b91af">RsvpStatus</span>.Unsure)));</p>
<p>     events.AddRange(<br />         api<br />         .events<br />         .get(<span style="color:#0000ff">null</span>, <span style="color:#0000ff">null</span>, <span style="color:#2b91af">DateTime</span>.Now, <span style="color:#0000ff">null</span>, <span style="color:#a31515">&#8220;declined&#8221;</span>)<br />         .Select(e =&gt; <span style="color:#0000ff">new</span> <span style="color:#2b91af">UserFacebookEvent</span>(e, <span style="color:#2b91af">RsvpStatus</span>.Declined)));</p>
<p>     events.AddRange(<br />         api<br />         .events<br />         .get(<span style="color:#0000ff">null</span>, <span style="color:#0000ff">null</span>, <span style="color:#2b91af">DateTime</span>.Now, <span style="color:#0000ff">null</span>, <span style="color:#a31515">&#8220;not_replied&#8221;</span>)<br />         .Select(e =&gt; <span style="color:#0000ff">new</span> <span style="color:#2b91af">UserFacebookEvent</span>(e, <span style="color:#2b91af">RsvpStatus</span>.NotReplied)));</p>
<p>     <span style="color:#0000ff">return</span> events;<br /> }  </p>
</div>
</div>
</div>
<p>I think I really need some better class names, but I will do that in part 3 when i clean it all up and add the missing bits.</p>
<h1></h1>
<h2>Dealing with event Start and End Time</h2>
<p>After a few hours of getting very frustrated with not being able to convert the time property you find out that the API gives the start and end time in Epoch time BUT not UTC or GMT they give it to you in Pacific Standard Time…</p>
<p><a href="http://forum.developers.facebook.com/viewtopic.php?id=18409">http://forum.developers.facebook.com/viewtopic.php?id=18409</a></p>
<p>This thread has a simple way to get around it.</p>
<div style="padding-bottom: 5px; padding-left: 5px; width: 623px; padding-right: 5px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:248eb593-dc71-4a70-80dc-cbd3bb1e714f" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: 300px; overflow: scroll; padding: 2px 5px; white-space: nowrap">
<p>  <span style="color:#0000ff">var</span> facebookTimeZoneInfo = <span style="color:#2b91af">TimeZoneInfo</span>.FindSystemTimeZoneById(<span style="color:#a31515">&#8220;Pacific Standard Time&#8221;</span>);</p>
<p> <span style="color:#0000ff">var</span> startTime = <span style="color:#2b91af">TimeZoneInfo</span>.ConvertTime(<span style="color:#0000ff">new</span> <span style="color:#2b91af">DateTime</span>(1970, 1, 1).AddSeconds(facebookEvent.start_time),<br />     <span style="color:#2b91af">TimeZoneInfo</span>.Utc,<br />     facebookTimeZoneInfo);</p>
<p> <span style="color:#0000ff">var</span> endTime = <span style="color:#2b91af">TimeZoneInfo</span>.ConvertTime(<span style="color:#0000ff">new</span> <span style="color:#2b91af">DateTime</span>(1970, 1, 1).AddSeconds(facebookEvent.end_time),<br />     <span style="color:#2b91af">TimeZoneInfo</span>.Utc,<br />     facebookTimeZoneInfo); </p>
</div>
</div>
</div>
<h2>RSVP Panel in Appointments</h2>
<p>I have a few more adapters and wrappers for different things to make my life easier when I start adding features and turning this into a decent add-in! The FacebookEventSynchroniser class is the other main class, it uses a singleton pattern and funnily enough is in control of synchronising events. I have attached the solution for anyone to play around with, feedback would be great.</p>
<p>Out first step is to create a Winforms user control AND a WPF user control, unlike the windows you still need a windows forms control to host in a outlook form region. I am not going to cover the RsvpPanel as it is pretty simple XAML.</p>
<p><a href="http://jake.ginnivan.net/Images/WritingaFacebookeventsynchroniserforOutl_A789/image_5.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://jake.ginnivan.net/Images/WritingaFacebookeventsynchroniserforOutl_A789/image_thumb_5.png" width="165" height="40" /></a></p>
<p>One problem I have had with the ElementHost Winforms control is controls sometimes fail to paint, so you have a empty pane staring at you. I have found a really good way to get around this problem.</p>
<div style="padding-bottom: 5px; padding-left: 5px; width: 623px; padding-right: 5px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:07b87b20-ece4-4b1c-9f09-b647ee6120bb" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: 300px; overflow: scroll; padding: 2px 5px; white-space: nowrap">
<p>  <span style="color:#0000ff">public</span> <span style="color:#2b91af">UIElement</span> Child<br /> {<br />     <span style="color:#0000ff">get</span><br />     {<br />         <span style="color:#0000ff">return</span> elementHost1.Child;<br />     }<br />     <span style="color:#0000ff">set</span><br />     {<br />         elementHost1.Child = <span style="color:#0000ff">value</span>;<br />         elementHost1.Width++;<br />         elementHost1.Dock = <span style="color:#2b91af">DockStyle</span>.Fill;<br />     }<br /> }  </p>
</div>
</div>
</div>
<p>The key is the elementHost1.Width++; calling Invalidate() or Refresh() did not do it, the only thing that caused the control to repaint was to resize it. Really odd, but this fixes it every time!</p>
<p>Now there are a few ways I have found to create Task Panes, the first has a nice tutorial and it is good if you want a taskpane for every outlook inspector (Inspector is generally the forms you see when you open a outlook item). The tutorial is available here: <a href="http://msdn.microsoft.com/en-us/library/bb296010.aspx">http://msdn.microsoft.com/en-us/library/bb296010.aspx</a></p>
<p>Because I only want my pane to appear for AppointmentItem’s only, so I will create a new Ribbon.</p>
<p><a href="http://jake.ginnivan.net/Images/WritingaFacebookeventsynchroniserforOutl_10D8B/image.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://jake.ginnivan.net/Images/WritingaFacebookeventsynchroniserforOutl_10D8B/image_thumb.png" width="630" height="345" /></a></p>
<p>On your new Ribbon set the RibbonType property to Microsoft.Outlook.Appointment, then select group1, rename it to something better, set the Visible property to false and set the Position to “AfterOfficeId GroupShow”.    <br />After that select the tab, and change the OfficeId to TabAppointment so your group appears on the appointment tab!</p>
<p>So lets then setup all the code behind on the Ribbon:</p>
<div style="padding-bottom: 5px; padding-left: 5px; width: 623px; padding-right: 5px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:16aca2f3-f4b9-4536-94ff-2bd46b8b5c5d" class="wlWriterSmartContent">
<div style="border-bottom: #000080 1px solid; border-left: #000080 1px solid; font-family: &#39;Courier New&#39;, courier, monospace; font-size: 10pt; border-top: #000080 1px solid; border-right: #000080 1px solid">
<div style="padding-bottom: 2px; background-color: #ffffff; padding-left: 5px; padding-right: 5px; white-space: nowrap; max-height: 300px; overflow: scroll; padding-top: 2px">
<p><span style="color: #0000ff">public</span> <span style="color: #0000ff">partial</span> <span style="color: #0000ff">class</span> <span style="color: #2b91af">FacebookRsvpPanel</span> : <span style="color: #2b91af">OfficeRibbon</span>          <br />&#160;&#160;&#160; {          <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #0000ff">private</span> <span style="color: #2b91af">AppointmentViewModel</span> _appointmentViewModel;          <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #0000ff">private</span> <span style="color: #2b91af">WpfControlHost</span> _control;          <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #0000ff">private</span> <span style="color: #2b91af">CustomTaskPane</span> _rsvpPane;          <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #0000ff">private</span> <span style="color: #2b91af">Inspector</span> _inspector;          </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #0000ff">public</span> FacebookRsvpPanel()          <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; {          <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; InitializeComponent();          <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; }          </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #0000ff">private</span> <span style="color: #0000ff">void</span> FacebookRsvpPanel_Load(<span style="color: #0000ff">object</span> sender, <span style="color: #2b91af">RibbonUIEventArgs</span> e)          <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; {          <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #008000">//Get inspector</span>          <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; _inspector = Context <span style="color: #0000ff">as</span> <span style="color: #2b91af">Inspector</span>;          <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #0000ff">if</span> (_inspector == <span style="color: #0000ff">null</span>) <span style="color: #0000ff">return</span>;          <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; ((<span style="color: #2b91af">InspectorEvents_Event</span>)_inspector).Close += InspectorClose;          </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #008000">//Verify the item is a appointment item</span>          <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #0000ff">var</span> appointment = _inspector.CurrentItem <span style="color: #0000ff">as</span> <span style="color: #2b91af">AppointmentItem</span>;          <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #0000ff">if</span> (appointment == <span style="color: #0000ff">null</span>) <span style="color: #0000ff">return</span>;          </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #0000ff">var</span> appointmentViewModel = <span style="color: #0000ff">new</span> <span style="color: #2b91af">AppointmentViewModel</span>(appointment);          <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #0000ff">if</span> (!appointmentViewModel.IsFacebookEvent) <span style="color: #0000ff">return</span>;          </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; _appointmentViewModel = appointmentViewModel;          <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; SetupRsvpPane(_inspector);          <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; }          </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #0000ff">private</span> <span style="color: #0000ff">void</span> SetupRsvpPane(<span style="color: #2b91af">Inspector</span> inspector)          <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; {          <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #0000ff">var</span> wpfPanel = <span style="color: #0000ff">new</span> <span style="color: #2b91af">RsvpPanel</span>(_appointmentViewModel)          <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {          <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; DataContext = _appointmentViewModel          <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; };          </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; _control = <span style="color: #0000ff">new</span> <span style="color: #2b91af">WpfControlHost</span>          <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {          <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Child = wpfPanel          <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; };          </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; _rsvpPane = <span style="color: #2b91af">Globals</span>.ThisAddIn.CustomTaskPanes.Add(_control, <span style="color: #a31515">&quot;Facebook RSVP&quot;</span>, inspector);          </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; _rsvpPane.Width = Properties.<span style="color: #2b91af">Settings</span>.Default.RsvpPaneWidth;          <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; _rsvpPane.Visible = <span style="color: #0000ff">true</span>;          <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; _rsvpPane.VisibleChanged += RsvpPaneVisibleChanged;          <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; facebookGroup.Visible = <span style="color: #0000ff">true</span>;          <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; }          </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #0000ff">void</span> InspectorClose()          <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; {          <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; ((<span style="color: #2b91af">InspectorEvents_Event</span>)_inspector).Close -= InspectorClose;          <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; _inspector = <span style="color: #0000ff">null</span>;          </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #0000ff">if</span> (_rsvpPane != <span style="color: #0000ff">null</span>)          <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #2b91af">Globals</span>.ThisAddIn.CustomTaskPanes.Remove(_rsvpPane);          <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; }          </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #0000ff">void</span> RsvpPaneVisibleChanged(<span style="color: #0000ff">object</span> sender, <span style="color: #2b91af">EventArgs</span> e)          <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; {          <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; showRsvpPanel.Checked = _rsvpPane.Visible;          <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; }          </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #0000ff">private</span> <span style="color: #0000ff">void</span> showRsvpPanel_Click(<span style="color: #0000ff">object</span> sender, <span style="color: #2b91af">RibbonControlEventArgs</span> e)          <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; {          <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; _rsvpPane.Visible = ((<span style="color: #2b91af">RibbonToggleButton</span>)sender).Checked;          <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; }          <br />&#160;&#160;&#160; }</p>
</p></div>
</p></div>
</p></div>
<p>There are a few other things we hit when we start actually changing the RSVP’s, you have to ask for permission to RSVP, so we will do that as well.</p>
<p>We actually have to extend the Toolkit to include the create_rsvp enum so we can actually get the permission.    <br /><a href="http://jake.ginnivan.net/Images/WritingaFacebookeventsynchroniserforOutl_10D8B/image_4.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://jake.ginnivan.net/Images/WritingaFacebookeventsynchroniserforOutl_10D8B/image_thumb_4.png" width="601" height="484" /></a></p>
<h2>Office 2010</h2>
<p>I decided to install the Technical Preview of office 2010 on my machine, so when I try to run the add-in I get this nice error, takes me back to trying to develop office 2003 add-ins with office 2007..</p>
<p><a href="http://jake.ginnivan.net/Images/WritingaFacebookeventsynchroniserforOutl_10D8B/image_5.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://jake.ginnivan.net/Images/WritingaFacebookeventsynchroniserforOutl_10D8B/image_thumb_5.png" width="493" height="175" /></a></p>
<p>And here is a nice blog post how to work around the issue =)</p>
<p><a href="http://blogs.msdn.com/andreww/archive/2008/02/01/add-ins-for-office-14.aspx">http://blogs.msdn.com/andreww/archive/2008/02/01/add-ins-for-office-14.aspx</a></p>
<p>Short version:</p>
<ol>
<li>Set all VSTO/Outlook references to copy local. </li>
<li>Create new Solution configuration, I called it Office 2010. </li>
<li>Set the Start Action to Start external program, and point it at your Outlook.exe in the Office 14 directory. </li>
</ol>
<p><a href="http://jake.ginnivan.net/Images/WritingaFacebookeventsynchroniserforOutl_10D8B/image_6.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://jake.ginnivan.net/Images/WritingaFacebookeventsynchroniserforOutl_10D8B/image_thumb_6.png" width="633" height="373" /></a></p>
<p>And there you go, F5 now works!</p>
<h2>Finished product</h2>
<p><a href="http://jake.ginnivan.net/Images/WritingaFacebookeventsynchroniserforOutl_10D8B/image_7.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://jake.ginnivan.net/Images/WritingaFacebookeventsynchroniserforOutl_10D8B/image_thumb_7.png" width="649" height="481" /></a></p>
<p>To stop this popping up when you first start outlook log into Facebook with internet explorer and tick remember my password. Of course the first time you access the app you will have to click allow. Because this is an ActiveX control it must run on the UI thread, it will block the outlook UI.</p>
<p>Configuration window (WPF window =D)</p>
<p><a href="http://jake.ginnivan.net/Images/WritingaFacebookeventsynchroniserforOutl_10D8B/image_8.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://jake.ginnivan.net/Images/WritingaFacebookeventsynchroniserforOutl_10D8B/image_thumb_8.png" width="500" height="243" /></a></p>
<p>As I said, no RSVP support in the API yet =( If they act on <a title="http://bugs.developers.facebook.com/show_bug.cgi?id=4462" href="http://bugs.developers.facebook.com/show_bug.cgi?id=4462" target="_blank">Bug# 4462</a> then all it requires is enabling those radio buttons and the feature is completely written!</p>
<p><a href="http://jake.ginnivan.net/Images/WritingaFacebookeventsynchroniserforOutl_10D8B/image_9.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://jake.ginnivan.net/Images/WritingaFacebookeventsynchroniserforOutl_10D8B/image_thumb_9.png" width="819" height="500" /></a></p>
<p>But you can click on the view event button to open the Facebook event in your default browser.</p>
<h2>Future Updates</h2>
<p>I plan on (depending on time and motivation) cleaning up the code some more and making sure that the Facebook login window does not block the Outlook UI when you first start outlook. Also giving the option to connect to Facebook on demand (put a connect button on the toolbar).</p>
<h2>Install now</h2>
<p>If you have a better way to deal with this, please let me know!</p>
<p>I have deployed it Via click once, feel free to try it out and give me feedback. Because I don’t have a code signing cert you will have to install my temporary certificate into the Trusted Root Certification Authority store. Download the cert <a href="http://jake.ginnivan.net/FacebookSync/FacebookSync.pfx">here</a></p>
<p><a href="http://jake.ginnivan.net/Images/WritingaFacebookeventsynchroniserforOutl_A789/image_6.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://jake.ginnivan.net/Images/WritingaFacebookeventsynchroniserforOutl_A789/image_thumb_6.png" width="241" height="300" /></a>&#160; <a href="http://jake.ginnivan.net/Images/WritingaFacebookeventsynchroniserforOutl_A789/image_7.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://jake.ginnivan.net/Images/WritingaFacebookeventsynchroniserforOutl_A789/image_thumb_7.png" width="308" height="280" /></a> </p>
<p><a href="http://jake.ginnivan.net/Images/WritingaFacebookeventsynchroniserforOutl_A789/image_8.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://jake.ginnivan.net/Images/WritingaFacebookeventsynchroniserforOutl_A789/image_thumb_8.png" width="502" height="432" /></a> </p>
<p>Once you have installed the cert, just run the installer from <a href="http://jake.ginnivan.net/FacebookSync/setup.exe">here</a>.</p>
<h2>Source</h2>
<p>I have removed the facebook AppId and Secret from the code. So you will have to register as a facebook developer, create a new app and get the codes from there. Or contact me and I can email them to you.</p>
<p><a href="http://jake.ginnivan.net/FacebookSync/FacebookSync.zip">Download Source</a></p>
]]></content:encoded>
			<wfw:commentRss>http://jake.ginnivan.net/2009/07/writing-a-facebook-event-synchroniser-for-outlook-2007-part-2/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>C# Argument Parser</title>
		<link>http://jake.ginnivan.net/2009/07/c-argument-parser/</link>
		<comments>http://jake.ginnivan.net/2009/07/c-argument-parser/#comments</comments>
		<pubDate>Mon, 27 Jul 2009 03:51:06 +0000</pubDate>
		<dc:creator>Jake Ginnivan</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[C#]]></category>

		<guid isPermaLink="false">http://jake.ginnivan.net/2009/07/c-argument-parser/</guid>
		<description><![CDATA[I know this has been done to death but nothing I found did the job for me so I started with the one that fitted my needs the most then edited from there. 
Original source: http://www.codeproject.com/KB/recipes/command_line.aspx
I have a few specific requirements:

It must support lists, or the same argument specified multiple times. If an argument has <a href="http://jake.ginnivan.net/2009/07/c-argument-parser/" class="more-link">More &#62;</a>]]></description>
			<content:encoded><![CDATA[<p>I know this has been done to death but nothing I found did the job for me so I started with the one that fitted my needs the most then edited from there. </p>
<p>Original source: <a href="http://www.codeproject.com/KB/recipes/command_line.aspx">http://www.codeproject.com/KB/recipes/command_line.aspx</a></p>
<p>I have a few specific requirements:</p>
<ul>
<li>It must support lists, or the same argument specified multiple times. If an argument has comma’s in it then it will be treated as a list and split on the comma. </li>
<li>It must support paths with a trailing \ ie. –arg:”c:\Users\ginnivanj\My Path\” </li>
<li>Has support for flags. </li>
</ul>
<p><a href="http://jake.ginnivan.net/Images/CArgumentParser_E39D/image.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://jake.ginnivan.net/Images/CArgumentParser_E39D/image_thumb.png" width="355" height="309" /></a> </p>
</p>
<h2>Example Usage</h2>
<p>There are two ways you can start using this class, I have created a SplitCommandLine function which ignores escaped quotes, this is needed for path support, the trailing \ on the path causes the quote to be taken literally.</p>
<p>Using SplitCommandLine:</p>
<div style="padding-bottom: 5px; padding-left: 5px; width: 623px; padding-right: 5px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:26b8efc2-fe4b-4cbf-8057-aa93d5b9e742" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: 300px; overflow: scroll; padding: 2px 5px; white-space: nowrap">
<p>  <span style="color:#0000ff">var</span> commandLine = <span style="color:#2b91af">Environment</span>.CommandLine;<br /> <span style="color:#0000ff">var</span> splitCommandLine = <span style="color:#2b91af">Arguments</span>.SplitCommandLine(commandLine);</p>
<p> <span style="color:#0000ff">var</span> arguments = <span style="color:#0000ff">new</span> <span style="color:#2b91af">Arguments</span>(splitCommandLine);
</p>
</div>
</div>
</div>
<p>Letting windows do it:</p>
<div style="padding-bottom: 5px; padding-left: 5px; width: 623px; padding-right: 5px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:91d2b04f-ff5a-4d72-a7fc-4e5e59665e6b" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: 300px; overflow: scroll; padding: 2px 5px; white-space: nowrap">
<p>  <span style="color:#0000ff">static</span> <span style="color:#0000ff">int</span> Main(<span style="color:#0000ff">string</span>[] args)<br /> {<br />     _args = <span style="color:#0000ff">new</span> <span style="color:#2b91af">Arguments</span>(args);<br /> }  </p>
</div>
</div>
</div>
<p>&#160;</p>
<blockquote><p>Argument: –flag      <br />Usage: args.IsTrue(“flag”);       <br />Result: true       </p>
<p>Argument: –arg:MyValue      <br />Usage: args.Single(“arg”);       <br />Result: MyValue       </p>
<p>Argument: –arg “My Value”      <br />Usage: args.Single(“arg”);       <br />Result: ‘My Value’</p>
<p>Argument: /arg=Value /arg=Value2      <br />Usage: args[“arg”]       <br />Result: new string[] {“Value”, “Value2”}</p>
<p>Argument: /arg=”Value,Value2”      <br />Usage: args[“arg”]       <br />Result: new string[] {“Value”, “Value2”}       </p>
</blockquote>
</p>
<p>As you can see it is very flexible, it support [–/]arg[:=&lt;space&gt;]value and with the list support it makes it really useful and adaptable.</p>
<p>I have tried to cover as many of the different options with unit tests to make sure it is robust.</p>
<h2>Arguments Class</h2>
<div style="padding-bottom: 5px; padding-left: 5px; width: 623px; padding-right: 5px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:1d3f15c0-dde3-4d6a-aa7a-2fc94f65c62e" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: 500px; overflow: scroll; padding: 2px 5px; white-space: nowrap">
<p>  <span style="color:#0000ff">public</span> <span style="color:#0000ff">class</span> <span style="color:#2b91af">Arguments</span><br /> { <br />     <span style="color:#808080">///</span><span style="color:#008000"> </span><span style="color:#808080">&lt;summary&gt;</span><br />     <span style="color:#808080">///</span><span style="color:#008000"> Splits the command line. When main(string[] args) is used escaped quotes (ie a path &#8220;c:&#92;folder&#92;&#8221;)</span><br />     <span style="color:#808080">///</span><span style="color:#008000"> Will consume all the following command line arguments as the one argument. </span><br />     <span style="color:#808080">///</span><span style="color:#008000"> This function ignores escaped quotes making handling paths much easier.</span><br />     <span style="color:#808080">///</span><span style="color:#008000"> </span><span style="color:#808080">&lt;/summary&gt;</span><br />     <span style="color:#808080">///</span><span style="color:#008000"> </span><span style="color:#808080">&lt;param name=&#8221;commandLine&#8221;&gt;</span><span style="color:#008000">The command line.</span><span style="color:#808080">&lt;/param&gt;</span><br />     <span style="color:#808080">///</span><span style="color:#008000"> </span><span style="color:#808080">&lt;returns&gt;&lt;/returns&gt;</span><br />     <span style="color:#0000ff">public</span> <span style="color:#0000ff">static</span> <span style="color:#0000ff">string</span>[] SplitCommandLine(<span style="color:#0000ff">string</span> commandLine)<br />     {<br />         <span style="color:#0000ff">var</span> translatedArguments = <span style="color:#0000ff">new</span> <span style="color:#2b91af">StringBuilder</span>(commandLine);<br />         <span style="color:#0000ff">var</span> escaped = <span style="color:#0000ff">false</span>;<br />         <span style="color:#0000ff">for</span> (<span style="color:#0000ff">var</span> i = 0; i &lt; translatedArguments.Length; i++)<br />         {<br />             <span style="color:#0000ff">if</span> (translatedArguments[i] == <span style="color:#a31515">&#8216;&#8221;&#8216;</span>)<br />             {<br />                 escaped = !escaped;<br />             }<br />             <span style="color:#0000ff">if</span> (translatedArguments[i] == <span style="color:#a31515">&#8216; &#8216;</span> &amp;&amp; !escaped)<br />             {<br />                 translatedArguments[i] = <span style="color:#a31515">&#8216;&#92;n&#8217;</span>;<br />             }<br />         }</p>
<p>         <span style="color:#0000ff">var</span> toReturn = translatedArguments.ToString().Split(<span style="color:#0000ff">new</span>[] { <span style="color:#a31515">&#8216;&#92;n&#8217;</span> }, <span style="color:#2b91af">StringSplitOptions</span>.RemoveEmptyEntries);<br />         <span style="color:#0000ff">for</span> (<span style="color:#0000ff">var</span> i = 0; i &lt; toReturn.Length; i++)<br />         {<br />             toReturn[i] = RemoveMatchingQuotes(toReturn[i]);<br />         }<br />         <span style="color:#0000ff">return</span> toReturn;<br />     }</p>
<p>     <span style="color:#0000ff">public</span> <span style="color:#0000ff">static</span> <span style="color:#0000ff">string</span> RemoveMatchingQuotes(<span style="color:#0000ff">string</span> stringToTrim)<br />     {<br />         <span style="color:#0000ff">var</span> firstQuoteIndex = stringToTrim.IndexOf(<span style="color:#a31515">&#8216;&#8221;&#8216;</span>);<br />         <span style="color:#0000ff">var</span> lastQuoteIndex = stringToTrim.LastIndexOf(<span style="color:#a31515">&#8216;&#8221;&#8216;</span>);<br />         <span style="color:#0000ff">while</span> (firstQuoteIndex != lastQuoteIndex)<br />         {<br />             stringToTrim = stringToTrim.Remove(firstQuoteIndex, 1);<br />             stringToTrim = stringToTrim.Remove(lastQuoteIndex &#8211; 1, 1); <span style="color:#008000">//-1 because we&#8217;ve shifted the indicies left by one</span><br />             firstQuoteIndex = stringToTrim.IndexOf(<span style="color:#a31515">&#8216;&#8221;&#8216;</span>);<br />             lastQuoteIndex = stringToTrim.LastIndexOf(<span style="color:#a31515">&#8216;&#8221;&#8216;</span>);<br />         }</p>
<p>         <span style="color:#0000ff">return</span> stringToTrim;<br />     }</p>
<p>     <span style="color:#0000ff">private</span> <span style="color:#0000ff">readonly</span> <span style="color:#2b91af">Dictionary</span>&lt;<span style="color:#0000ff">string</span>, <span style="color:#2b91af">Collection</span>&lt;<span style="color:#0000ff">string</span>&gt;&gt; _parameters;<br />     <span style="color:#0000ff">private</span> <span style="color:#0000ff">string</span> _waitingParameter;</p>
<p>     <span style="color:#0000ff">public</span> Arguments(<span style="color:#2b91af">IEnumerable</span>&lt;<span style="color:#0000ff">string</span>&gt; arguments)<br />     {<br />         _parameters = <span style="color:#0000ff">new</span> <span style="color:#2b91af">Dictionary</span>&lt;<span style="color:#0000ff">string</span>, <span style="color:#2b91af">Collection</span>&lt;<span style="color:#0000ff">string</span>&gt;&gt;();</p>
<p>         <span style="color:#0000ff">string</span>[] parts;<br />         <br />         <span style="color:#008000">//Splits on beginning of arguments ( &#8211; and &#8212; and / )</span><br />         <span style="color:#008000">//And on assignment operators ( = and : )</span><br />         <span style="color:#0000ff">var</span> argumentSplitter = <span style="color:#0000ff">new</span> <span style="color:#2b91af">Regex</span>(<span style="color:#a31515">@&#8221;^-{1,2}|^/|=|:&#8221;</span>,<br />             <span style="color:#2b91af">RegexOptions</span>.IgnoreCase | <span style="color:#2b91af">RegexOptions</span>.Compiled);</p>
<p>         <span style="color:#0000ff">foreach</span> (<span style="color:#0000ff">var</span> argument <span style="color:#0000ff">in</span> arguments)<br />         {<br />             parts = argumentSplitter.Split(argument, 3);<br />             <span style="color:#0000ff">switch</span> (parts.Length)<br />             {<br />                 <span style="color:#0000ff">case</span> 1:<br />                     AddValueToWaitingArgument(parts[0]);<br />                     <span style="color:#0000ff">break</span>;<br />                 <span style="color:#0000ff">case</span> 2:<br />                     AddWaitingArgumentAsFlag();</p>
<p>                     <span style="color:#008000">//Because of the split index 0 will be a empty string</span><br />                     _waitingParameter = parts[1];<br />                     <span style="color:#0000ff">break</span>;<br />                 <span style="color:#0000ff">case</span> 3:<br />                     AddWaitingArgumentAsFlag();</p>
<p>                     <span style="color:#008000">//Because of the split index 0 will be a empty string</span><br />                     <span style="color:#0000ff">string</span> valuesWithoutQuotes = RemoveMatchingQuotes(parts[2]);</p>
<p>                     AddListValues(parts[1], valuesWithoutQuotes.Split(<span style="color:#a31515">&#8216;,&#8217;</span>));<br />                     <span style="color:#0000ff">break</span>;<br />             }<br />         }</p>
<p>         AddWaitingArgumentAsFlag();<br />     }</p>
<p>     <span style="color:#0000ff">private</span> <span style="color:#0000ff">void</span> AddListValues(<span style="color:#0000ff">string</span> argument, <span style="color:#2b91af">IEnumerable</span>&lt;<span style="color:#0000ff">string</span>&gt; values)<br />     {<br />         <span style="color:#0000ff">foreach</span> (<span style="color:#0000ff">var</span> listValue <span style="color:#0000ff">in</span> values)<br />         {<br />             Add(argument, listValue);<br />         }<br />     }</p>
<p>     <span style="color:#0000ff">private</span> <span style="color:#0000ff">void</span> AddWaitingArgumentAsFlag()<br />     {<br />         <span style="color:#0000ff">if</span> (_waitingParameter == <span style="color:#0000ff">null</span>) <span style="color:#0000ff">return</span>;</p>
<p>         AddSingle(_waitingParameter, <span style="color:#a31515">&#8220;true&#8221;</span>);<br />         _waitingParameter = <span style="color:#0000ff">null</span>;<br />     }</p>
<p>     <span style="color:#0000ff">private</span> <span style="color:#0000ff">void</span> AddValueToWaitingArgument(<span style="color:#0000ff">string</span> value)<br />     {<br />         <span style="color:#0000ff">if</span> (_waitingParameter == <span style="color:#0000ff">null</span>) <span style="color:#0000ff">return</span>;</p>
<p>         value = RemoveMatchingQuotes(value);</p>
<p>         Add(_waitingParameter, value);<br />         _waitingParameter = <span style="color:#0000ff">null</span>;<br />     }</p>
<p>     <span style="color:#808080">///</span><span style="color:#008000"> </span><span style="color:#808080">&lt;summary&gt;</span><br />     <span style="color:#808080">///</span><span style="color:#008000"> Gets the count.</span><br />     <span style="color:#808080">///</span><span style="color:#008000"> </span><span style="color:#808080">&lt;/summary&gt;</span><br />     <span style="color:#808080">///</span><span style="color:#008000"> </span><span style="color:#808080">&lt;value&gt;</span><span style="color:#008000">The count.</span><span style="color:#808080">&lt;/value&gt;</span><br />     <span style="color:#0000ff">public</span> <span style="color:#0000ff">int</span> Count<br />     {<br />         <span style="color:#0000ff">get</span><br />         {<br />             <span style="color:#0000ff">return</span> _parameters.Count;<br />         }<br />     }</p>
<p>     <span style="color:#808080">///</span><span style="color:#008000"> </span><span style="color:#808080">&lt;summary&gt;</span><br />     <span style="color:#808080">///</span><span style="color:#008000"> Adds the specified argument.</span><br />     <span style="color:#808080">///</span><span style="color:#008000"> </span><span style="color:#808080">&lt;/summary&gt;</span><br />     <span style="color:#808080">///</span><span style="color:#008000"> </span><span style="color:#808080">&lt;param name=&#8221;argument&#8221;&gt;</span><span style="color:#008000">The argument.</span><span style="color:#808080">&lt;/param&gt;</span><br />     <span style="color:#808080">///</span><span style="color:#008000"> </span><span style="color:#808080">&lt;param name=&#8221;value&#8221;&gt;</span><span style="color:#008000">The value.</span><span style="color:#808080">&lt;/param&gt;</span><br />     <span style="color:#0000ff">public</span> <span style="color:#0000ff">void</span> Add(<span style="color:#0000ff">string</span> argument, <span style="color:#0000ff">string</span> value)<br />     {<br />         <span style="color:#0000ff">if</span> (!_parameters.ContainsKey(argument))<br />             _parameters.Add(argument, <span style="color:#0000ff">new</span> <span style="color:#2b91af">Collection</span>&lt;<span style="color:#0000ff">string</span>&gt;());</p>
<p>         _parameters[argument].Add(value);<br />     }</p>
<p>     <span style="color:#0000ff">public</span> <span style="color:#0000ff">void</span> AddSingle(<span style="color:#0000ff">string</span> argument, <span style="color:#0000ff">string</span> value)<br />     {<br />         <span style="color:#0000ff">if</span> (!_parameters.ContainsKey(argument))<br />             _parameters.Add(argument, <span style="color:#0000ff">new</span> <span style="color:#2b91af">Collection</span>&lt;<span style="color:#0000ff">string</span>&gt;());<br />         <span style="color:#0000ff">else</span><br />             <span style="color:#0000ff">throw</span> <span style="color:#0000ff">new</span> <span style="color:#2b91af">ArgumentException</span>(<span style="color:#0000ff">string</span>.Format(<span style="color:#a31515">&#8220;Argument {0} has already been defined&#8221;</span>, argument));</p>
<p>         _parameters[argument].Add(value);<br />     }</p>
<p>     <span style="color:#0000ff">public</span> <span style="color:#0000ff">void</span> Remove(<span style="color:#0000ff">string</span> argument)<br />     {<br />         <span style="color:#0000ff">if</span> (_parameters.ContainsKey(argument))<br />             _parameters.Remove(argument);<br />     }</p>
<p>     <span style="color:#808080">///</span><span style="color:#008000"> </span><span style="color:#808080">&lt;summary&gt;</span><br />     <span style="color:#808080">///</span><span style="color:#008000"> Determines whether the specified argument is true.</span><br />     <span style="color:#808080">///</span><span style="color:#008000"> </span><span style="color:#808080">&lt;/summary&gt;</span><br />     <span style="color:#808080">///</span><span style="color:#008000"> </span><span style="color:#808080">&lt;param name=&#8221;argument&#8221;&gt;</span><span style="color:#008000">The argument.</span><span style="color:#808080">&lt;/param&gt;</span><br />     <span style="color:#808080">///</span><span style="color:#008000"> </span><span style="color:#808080">&lt;returns&gt;</span><br />     <span style="color:#808080">///</span><span style="color:#008000">     </span><span style="color:#808080">&lt;c&gt;</span><span style="color:#008000">true</span><span style="color:#808080">&lt;/c&gt;</span><span style="color:#008000"> if the specified argument is true; otherwise, </span><span style="color:#808080">&lt;c&gt;</span><span style="color:#008000">false</span><span style="color:#808080">&lt;/c&gt;</span><span style="color:#008000">.</span><br />     <span style="color:#808080">///</span><span style="color:#008000"> </span><span style="color:#808080">&lt;/returns&gt;</span><br />     <span style="color:#0000ff">public</span> <span style="color:#0000ff">bool</span> IsTrue(<span style="color:#0000ff">string</span> argument)<br />     {<br />         AssertSingle(argument);</p>
<p>         <span style="color:#0000ff">var</span> arg = <span style="color:#0000ff">this</span>[argument];<br />         <br />         <span style="color:#0000ff">return</span> arg != <span style="color:#0000ff">null</span> &amp;&amp; arg[0].Equals(<span style="color:#a31515">&#8220;true&#8221;</span>, <span style="color:#2b91af">StringComparison</span>.OrdinalIgnoreCase);<br />     }</p>
<p>     <span style="color:#0000ff">private</span> <span style="color:#0000ff">void</span> AssertSingle(<span style="color:#0000ff">string</span> argument)<br />     {<br />         <span style="color:#0000ff">if</span> (<span style="color:#0000ff">this</span>[argument] != <span style="color:#0000ff">null</span> &amp;&amp; <span style="color:#0000ff">this</span>[argument].Count &gt; 1)<br />             <span style="color:#0000ff">throw</span> <span style="color:#0000ff">new</span> <span style="color:#2b91af">ArgumentException</span>(<span style="color:#0000ff">string</span>.Format(<span style="color:#a31515">&#8220;{0} has been specified more than once, expecting single value&#8221;</span>, argument));<br />     }</p>
<p>     <span style="color:#0000ff">public</span> <span style="color:#0000ff">string</span> Single(<span style="color:#0000ff">string</span> argument)<br />     {<br />         AssertSingle(argument);</p>
<p>         <span style="color:#008000">//only return value if its NOT true, there is only a single item for that argument</span><br />         <span style="color:#008000">//and the argument is defined</span><br />         <span style="color:#0000ff">if</span> (<span style="color:#0000ff">this</span>[argument] != <span style="color:#0000ff">null</span> &amp;&amp; !IsTrue(argument))<br />             <span style="color:#0000ff">return</span> <span style="color:#0000ff">this</span>[argument][0];<br />         <br />         <span style="color:#0000ff">return</span> <span style="color:#0000ff">null</span>;<br />     }</p>
<p>     <span style="color:#0000ff">public</span> <span style="color:#0000ff">bool</span> Exists(<span style="color:#0000ff">string</span> argument)<br />     {<br />         <span style="color:#0000ff">return</span> (<span style="color:#0000ff">this</span>[argument] != <span style="color:#0000ff">null</span> &amp;&amp; <span style="color:#0000ff">this</span>[argument].Count &gt; 0);<br />     }</p>
<p>     <span style="color:#808080">///</span><span style="color:#008000"> </span><span style="color:#808080">&lt;summary&gt;</span><br />     <span style="color:#808080">///</span><span style="color:#008000"> Gets the </span><span style="color:#808080">&lt;see cref=&#8221;System.Collections.ObjectModel.Collection&amp;lt;T&amp;gt;&#8221;/&gt;</span><span style="color:#008000"> with the specified parameter.</span><br />     <span style="color:#808080">///</span><span style="color:#008000"> </span><span style="color:#808080">&lt;/summary&gt;</span><br />     <span style="color:#808080">///</span><span style="color:#008000"> </span><span style="color:#808080">&lt;value&gt;&lt;/value&gt;</span><br />     <span style="color:#0000ff">public</span> <span style="color:#2b91af">Collection</span>&lt;<span style="color:#0000ff">string</span>&gt; <span style="color:#0000ff">this</span>[<span style="color:#0000ff">string</span> parameter]<br />     {<br />         <span style="color:#0000ff">get</span><br />         {<br />             <span style="color:#0000ff">return</span> _parameters.ContainsKey(parameter) ? _parameters[parameter] : <span style="color:#0000ff">null</span>;<br />         }<br />     }<br /> }  </p>
</div>
</div>
</div>
<h2>Unit Tests</h2>
<p>The best way to understand how this class works is to have a look at the unit tests, if I am missing any functionality or I have missed something let me know!</p>
<div style="padding-bottom: 5px; padding-left: 5px; width: 623px; padding-right: 5px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 5px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:5a015130-9db0-4628-b14c-4a5a3fc4b71a" class="wlWriterEditableSmartContent">
<div style="border: #000080 1px solid; font-family: 'Courier New', Courier, Monospace; font-size: 10pt">
<div style="background-color: #ffffff; max-height: 500px; overflow: scroll; padding: 2px 5px; white-space: nowrap">
<p>  [<span style="color:#2b91af">TestClass</span>]<br /> <span style="color:#0000ff">public</span> <span style="color:#0000ff">class</span> <span style="color:#2b91af">ArgumentsTests</span><br /> {<br />     <span style="color:#0000ff">public</span> <span style="color:#2b91af">TestContext</span> TestContext { <span style="color:#0000ff">get</span>; <span style="color:#0000ff">set</span>; }</p>
<p>     <span style="color:#808080">///</span><span style="color:#008000"> </span><span style="color:#808080">&lt;summary&gt;</span><br />     <span style="color:#808080">///</span><span style="color:#008000">A test for Arguments Constructor</span><br />     <span style="color:#808080">///&lt;/summary&gt;</span><br />     [<span style="color:#2b91af">TestMethod</span>]<br />     <span style="color:#0000ff">public</span> <span style="color:#0000ff">void</span> ArgumentBooleanTest()<br />     {<br />         <span style="color:#2b91af">IEnumerable</span>&lt;<span style="color:#0000ff">string</span>&gt; args = <span style="color:#0000ff">new</span>[]<br />                                        {<br />                                            <span style="color:#a31515">&#8220;-testBool&#8221;</span><br />                                        };<br />         <span style="color:#0000ff">var</span> target = <span style="color:#0000ff">new</span> <span style="color:#2b91af">Arguments</span>(args);<br />         <span style="color:#2b91af">Assert</span>.IsTrue(target.IsTrue(<span style="color:#a31515">&#8220;testBool&#8221;</span>));<br />     }</p>
<p>     [<span style="color:#2b91af">TestMethod</span>]<br />     <span style="color:#0000ff">public</span> <span style="color:#0000ff">void</span> IsTrueDoesntExist()<br />     {<br />         <span style="color:#2b91af">IEnumerable</span>&lt;<span style="color:#0000ff">string</span>&gt; args = <span style="color:#0000ff">new</span> <span style="color:#0000ff">string</span>[]{};<br />         <span style="color:#0000ff">var</span> target = <span style="color:#0000ff">new</span> <span style="color:#2b91af">Arguments</span>(args);<br />         <span style="color:#2b91af">Assert</span>.IsFalse(target.IsTrue(<span style="color:#a31515">&#8220;doesntExist&#8221;</span>));<br />     }</p>
<p>     [<span style="color:#2b91af">TestMethod</span>]<br />     <span style="color:#0000ff">public</span> <span style="color:#0000ff">void</span> ArgumentDoubleDashesTest()<br />     {<br />         <span style="color:#2b91af">IEnumerable</span>&lt;<span style="color:#0000ff">string</span>&gt; args = <span style="color:#0000ff">new</span>[]<br />                                        {<br />                                            <span style="color:#a31515">&#8220;&#8211;testArg=Value&#8221;</span><br />                                        };<br />         <span style="color:#0000ff">var</span> target = <span style="color:#0000ff">new</span> <span style="color:#2b91af">Arguments</span>(args);<br />         <span style="color:#2b91af">Assert</span>.AreEqual(<span style="color:#a31515">&#8220;Value&#8221;</span>, target.Single(<span style="color:#a31515">&#8220;testArg&#8221;</span>));<br />     }</p>
<p>     [<span style="color:#2b91af">TestMethod</span>]<br />     <span style="color:#0000ff">public</span> <span style="color:#0000ff">void</span> ArgumentSingleTest()<br />     {<br />         <span style="color:#2b91af">IEnumerable</span>&lt;<span style="color:#0000ff">string</span>&gt; args = <span style="color:#0000ff">new</span>[]<br />                                        {<br />                                            <span style="color:#a31515">&#8220;-test:Value&#8221;</span><br />                                        };<br />         <span style="color:#0000ff">var</span> target = <span style="color:#0000ff">new</span> <span style="color:#2b91af">Arguments</span>(args);<br />         <span style="color:#2b91af">Assert</span>.AreEqual(1, target[<span style="color:#a31515">"test"</span>].Count);<br />         <span style="color:#2b91af">Assert</span>.AreEqual(<span style="color:#a31515">&#8220;Value&#8221;</span>, target.Single(<span style="color:#a31515">&#8220;test&#8221;</span>));<br />     }</p>
<p>     [<span style="color:#2b91af">TestMethod</span>]<br />     <span style="color:#0000ff">public</span> <span style="color:#0000ff">void</span> ArgumentWithSpaceSeparatorTest()<br />     {<br />         <span style="color:#2b91af">IEnumerable</span>&lt;<span style="color:#0000ff">string</span>&gt; args = <span style="color:#2b91af">Arguments</span>.SplitCommandLine(<span style="color:#a31515">&#8220;-test Value&#8221;</span>);</p>
<p>         <span style="color:#0000ff">var</span> target = <span style="color:#0000ff">new</span> <span style="color:#2b91af">Arguments</span>(args);<br />         <span style="color:#2b91af">Assert</span>.AreEqual(1, target[<span style="color:#a31515">"test"</span>].Count);<br />         <span style="color:#2b91af">Assert</span>.AreEqual(<span style="color:#a31515">&#8220;Value&#8221;</span>, target.Single(<span style="color:#a31515">&#8220;test&#8221;</span>));<br />     }</p>
<p>     [<span style="color:#2b91af">TestMethod</span>]<br />     <span style="color:#0000ff">public</span> <span style="color:#0000ff">void</span> ArgumentWithSpaceSeparatorAndSpaceInValueTest()<br />     {<br />         <span style="color:#2b91af">IEnumerable</span>&lt;<span style="color:#0000ff">string</span>&gt; args = <span style="color:#2b91af">Arguments</span>.SplitCommandLine(<span style="color:#a31515">&#8220;-test &#92;&#8221;Value With Space&#92;&#8221;"</span>);</p>
<p>         <span style="color:#0000ff">var</span> target = <span style="color:#0000ff">new</span> <span style="color:#2b91af">Arguments</span>(args);<br />         <span style="color:#2b91af">Assert</span>.AreEqual(1, target[<span style="color:#a31515">"test"</span>].Count);<br />         <span style="color:#2b91af">Assert</span>.AreEqual(<span style="color:#a31515">&#8220;Value With Space&#8221;</span>, target.Single(<span style="color:#a31515">&#8220;test&#8221;</span>));<br />     }</p>
<p>     [<span style="color:#2b91af">TestMethod</span>]<br />     <span style="color:#0000ff">public</span> <span style="color:#0000ff">void</span> AddWaitingAsFlagTest()<br />     {<br />         <span style="color:#2b91af">IEnumerable</span>&lt;<span style="color:#0000ff">string</span>&gt; args = <span style="color:#2b91af">Arguments</span>.SplitCommandLine(<span style="color:#a31515">&#8220;-flag -test &#92;&#8221;Value With Space&#92;&#8221;"</span>);</p>
<p>         <span style="color:#0000ff">var</span> target = <span style="color:#0000ff">new</span> <span style="color:#2b91af">Arguments</span>(args);<br />         <span style="color:#2b91af">Assert</span>.AreEqual(2, target.Count);<br />         <span style="color:#2b91af">Assert</span>.AreEqual(1, target[<span style="color:#a31515">"test"</span>].Count);<br />         <span style="color:#2b91af">Assert</span>.AreEqual(<span style="color:#a31515">&#8220;Value With Space&#8221;</span>, target.Single(<span style="color:#a31515">&#8220;test&#8221;</span>));<br />         <span style="color:#2b91af">Assert</span>.IsTrue(target.IsTrue(<span style="color:#a31515">&#8220;flag&#8221;</span>));<br />     }</p>
<p>     [<span style="color:#2b91af">TestMethod</span>]<br />     [<span style="color:#2b91af">ExpectedException</span>(<span style="color:#0000ff">typeof</span>(<span style="color:#2b91af">ArgumentException</span>))]<br />     <span style="color:#0000ff">public</span> <span style="color:#0000ff">void</span> AddSingleTwiceTest()<br />     {<br />         <span style="color:#2b91af">IEnumerable</span>&lt;<span style="color:#0000ff">string</span>&gt; args = <span style="color:#2b91af">Arguments</span>.SplitCommandLine(<span style="color:#a31515">&#8220;-flag&#8221;</span>);</p>
<p>         <span style="color:#0000ff">var</span> target = <span style="color:#0000ff">new</span> <span style="color:#2b91af">Arguments</span>(args);</p>
<p>         target.AddSingle(<span style="color:#a31515">&#8220;flag&#8221;</span>, <span style="color:#a31515">&#8220;true&#8221;</span>);<br />     }</p>
<p>     [<span style="color:#2b91af">TestMethod</span>]<br />     <span style="color:#0000ff">public</span> <span style="color:#0000ff">void</span> FlagsTest()<br />     {<br />         <span style="color:#2b91af">IEnumerable</span>&lt;<span style="color:#0000ff">string</span>&gt; args = <span style="color:#2b91af">Arguments</span>.SplitCommandLine(<span style="color:#a31515">&#8220;-flag1 -flag2&#8243;</span>);</p>
<p>         <span style="color:#0000ff">var</span> target = <span style="color:#0000ff">new</span> <span style="color:#2b91af">Arguments</span>(args);</p>
<p>         <span style="color:#2b91af">Assert</span>.IsTrue(target.IsTrue(<span style="color:#a31515">&#8220;flag1&#8243;</span>));<br />         <span style="color:#2b91af">Assert</span>.IsTrue(target.IsTrue(<span style="color:#a31515">&#8220;flag2&#8243;</span>));<br />     }</p>
<p>     [<span style="color:#2b91af">TestMethod</span>]<br />     <span style="color:#0000ff">public</span> <span style="color:#0000ff">void</span> RemoveTest()<br />     {<br />         <span style="color:#2b91af">IEnumerable</span>&lt;<span style="color:#0000ff">string</span>&gt; args = <span style="color:#2b91af">Arguments</span>.SplitCommandLine(<span style="color:#a31515">&#8220;-flag1 -flag2&#8243;</span>);</p>
<p>         <span style="color:#0000ff">var</span> target = <span style="color:#0000ff">new</span> <span style="color:#2b91af">Arguments</span>(args);</p>
<p>         <span style="color:#2b91af">Assert</span>.IsTrue(target.IsTrue(<span style="color:#a31515">&#8220;flag1&#8243;</span>));<br />         <span style="color:#2b91af">Assert</span>.IsTrue(target.IsTrue(<span style="color:#a31515">&#8220;flag2&#8243;</span>));<br />         target.Remove(<span style="color:#a31515">&#8220;flag1&#8243;</span>);<br />         <span style="color:#2b91af">Assert</span>.IsFalse(target.Exists(<span style="color:#a31515">&#8220;flag1&#8243;</span>));<br />         <span style="color:#2b91af">Assert</span>.IsTrue(target.IsTrue(<span style="color:#a31515">&#8220;flag2&#8243;</span>));<br />     }</p>
<p>     [<span style="color:#2b91af">TestMethod</span>]<br />     <span style="color:#0000ff">public</span> <span style="color:#0000ff">void</span> SingleReturnsNullIfNotDefinedTest()<br />     {</p>
<p>         <span style="color:#0000ff">var</span> target = <span style="color:#0000ff">new</span> <span style="color:#2b91af">Arguments</span>(<span style="color:#0000ff">new</span> <span style="color:#0000ff">string</span>[]{});</p>
<p>         <span style="color:#2b91af">Assert</span>.IsFalse(target.Exists(<span style="color:#a31515">&#8220;notDefined&#8221;</span>));<br />         <span style="color:#2b91af">Assert</span>.IsNull(target.Single(<span style="color:#a31515">&#8220;notDefined&#8221;</span>));<br />     }</p>
<p>     [<span style="color:#2b91af">TestMethod</span>]<br />     <span style="color:#0000ff">public</span> <span style="color:#0000ff">void</span> ExistsTest()<br />     {<br />         <span style="color:#2b91af">IEnumerable</span>&lt;<span style="color:#0000ff">string</span>&gt; args = <span style="color:#2b91af">Arguments</span>.SplitCommandLine(<span style="color:#a31515">&#8220;-flag1&#8243;</span>);</p>
<p>         <span style="color:#0000ff">var</span> target = <span style="color:#0000ff">new</span> <span style="color:#2b91af">Arguments</span>(args);</p>
<p>         <span style="color:#2b91af">Assert</span>.IsTrue(target.Exists(<span style="color:#a31515">&#8220;flag1&#8243;</span>));<br />     }</p>
<p>     [<span style="color:#2b91af">TestMethod</span>]<br />     <span style="color:#0000ff">public</span> <span style="color:#0000ff">void</span> ArgumentListTest()<br />     {<br />         <span style="color:#2b91af">IEnumerable</span>&lt;<span style="color:#0000ff">string</span>&gt; args = <span style="color:#0000ff">new</span>[]<br />                                        {<br />                                            <span style="color:#a31515">&#8220;-test:Value&#8221;</span>,<br />                                            <span style="color:#a31515">&#8220;-test:Value2&#8243;</span><br />                                        };<br />         <span style="color:#0000ff">var</span> target = <span style="color:#0000ff">new</span> <span style="color:#2b91af">Arguments</span>(args);<br />         <span style="color:#2b91af">Assert</span>.AreEqual(2, target[<span style="color:#a31515">"test"</span>].Count);<br />         <span style="color:#2b91af">Assert</span>.AreEqual(<span style="color:#a31515">&#8220;Value&#8221;</span>, target[<span style="color:#a31515">"test"</span>][0]);<br />         <span style="color:#2b91af">Assert</span>.AreEqual(<span style="color:#a31515">&#8220;Value2&#8243;</span>, target[<span style="color:#a31515">"test"</span>][1]);<br />     }</p>
<p>     [<span style="color:#2b91af">TestMethod</span>]<br />     <span style="color:#0000ff">public</span> <span style="color:#0000ff">void</span> ArgumentPathTest()<br />     {<br />         <span style="color:#2b91af">IEnumerable</span>&lt;<span style="color:#0000ff">string</span>&gt; args = <span style="color:#0000ff">new</span>[]<br />                                        {<br />                                            <span style="color:#a31515">&#8220;-test:Value&#8221;</span>,<br />                                            <span style="color:#a31515">@&#8221;-test:C:&#92;Folder&#92;&#8221;</span><br />                                        };<br />         <span style="color:#0000ff">var</span> target = <span style="color:#0000ff">new</span> <span style="color:#2b91af">Arguments</span>(args);<br />         <span style="color:#2b91af">Assert</span>.AreEqual(2, target[<span style="color:#a31515">"test"</span>].Count);<br />         <span style="color:#2b91af">Assert</span>.AreEqual(<span style="color:#a31515">&#8220;Value&#8221;</span>, target[<span style="color:#a31515">"test"</span>][0]);<br />         <span style="color:#2b91af">Assert</span>.AreEqual(<span style="color:#a31515">@&#8221;C:&#92;Folder&#92;&#8221;</span>, target[<span style="color:#a31515">"test"</span>][1]);<br />     }</p>
<p>     [<span style="color:#2b91af">TestMethod</span>]<br />     <span style="color:#0000ff">public</span> <span style="color:#0000ff">void</span> ArgumentQuotedPathTest()<br />     {<br />         <span style="color:#2b91af">IEnumerable</span>&lt;<span style="color:#0000ff">string</span>&gt; args = <span style="color:#0000ff">new</span>[]<br />                                        {<br />                                            <span style="color:#a31515">&#8220;-test:Value&#8221;</span>,<br />                                            <span style="color:#a31515">&#8220;-test:&#92;&#8221;C:&#92;&#92;Folder&#92;&#92;&#92;&#8221;"</span><br />                                        };<br />         <span style="color:#0000ff">var</span> target = <span style="color:#0000ff">new</span> <span style="color:#2b91af">Arguments</span>(args);<br />         <span style="color:#2b91af">Assert</span>.AreEqual(2, target[<span style="color:#a31515">"test"</span>].Count);<br />         <span style="color:#2b91af">Assert</span>.AreEqual(<span style="color:#a31515">&#8220;Value&#8221;</span>, target[<span style="color:#a31515">"test"</span>][0]);<br />         <span style="color:#2b91af">Assert</span>.AreEqual(<span style="color:#a31515">&#8220;C:&#92;&#92;Folder&#92;&#92;&#8221;</span>, target[<span style="color:#a31515">"test"</span>][1]);<br />     }</p>
<p>     [<span style="color:#2b91af">TestMethod</span>]<br />     <span style="color:#0000ff">public</span> <span style="color:#0000ff">void</span> ArgumentQuotedPathWithSpaceTest()<br />     {<br />         <span style="color:#2b91af">IEnumerable</span>&lt;<span style="color:#0000ff">string</span>&gt; args = <span style="color:#0000ff">new</span>[]<br />                                        {<br />                                            <span style="color:#a31515">&#8220;-test:Value&#8221;</span>,<br />                                            <span style="color:#a31515">&#8220;-test:&#92;&#8221;C:&#92;&#92;Folder Name&#92;&#92;&#92;&#8221;"</span><br />                                        };<br />         <span style="color:#0000ff">var</span> target = <span style="color:#0000ff">new</span> <span style="color:#2b91af">Arguments</span>(args);<br />         <span style="color:#2b91af">Assert</span>.AreEqual(2, target[<span style="color:#a31515">"test"</span>].Count);<br />         <span style="color:#2b91af">Assert</span>.AreEqual(<span style="color:#a31515">&#8220;Value&#8221;</span>, target[<span style="color:#a31515">"test"</span>][0]);<br />         <span style="color:#2b91af">Assert</span>.AreEqual(<span style="color:#a31515">&#8220;C:&#92;&#92;Folder Name&#92;&#92;&#8221;</span>, target[<span style="color:#a31515">"test"</span>][1]);<br />     }</p>
<p>     [<span style="color:#2b91af">TestMethod</span>]<br />     <span style="color:#0000ff">public</span> <span style="color:#0000ff">void</span> ArgumentQuotedPathWithSpaceAndFollowingArgTest()<br />     {<br />         <span style="color:#2b91af">IEnumerable</span>&lt;<span style="color:#0000ff">string</span>&gt; args = <span style="color:#0000ff">new</span>[]<br />                                        {<br />                                            <span style="color:#a31515">&#8220;-test:Value&#8221;</span>,<br />                                            <span style="color:#a31515">&#8220;-test:&#92;&#8221;C:&#92;&#92;Folder Name&#92;&#92;&#92;&#8221;"</span>,<br />                                            <span style="color:#a31515">&#8220;-testPath:&#92;&#8221;C:&#92;&#92;Folder2&#92;&#92;&#92;&#8221;"</span>,<br />                                            <span style="color:#a31515">&#8220;-boolArg&#8221;</span><br />                                        };</p>
<p>         <span style="color:#0000ff">var</span> target = <span style="color:#0000ff">new</span> <span style="color:#2b91af">Arguments</span>(args);<br />         <span style="color:#2b91af">Assert</span>.AreEqual(2, target[<span style="color:#a31515">"test"</span>].Count);<br />         <span style="color:#2b91af">Assert</span>.AreEqual(<span style="color:#a31515">@&#8221;C:&#92;Folder2&#92;&#8221;</span>, target.Single(<span style="color:#a31515">&#8220;testPath&#8221;</span>));<br />         <span style="color:#2b91af">Assert</span>.IsTrue(target.IsTrue(<span style="color:#a31515">&#8220;boolArg&#8221;</span>));</p>
<p>         <span style="color:#2b91af">Assert</span>.AreEqual(<span style="color:#a31515">&#8220;Value&#8221;</span>, target[<span style="color:#a31515">"test"</span>][0]);<br />         <span style="color:#2b91af">Assert</span>.AreEqual(<span style="color:#a31515">&#8220;C:&#92;&#92;Folder Name&#92;&#92;&#8221;</span>, target[<span style="color:#a31515">"test"</span>][1]);<br />     }</p>
<p>     [<span style="color:#2b91af">TestMethod</span>]<br />     [<span style="color:#2b91af">ExpectedException</span>(<span style="color:#0000ff">typeof</span>(<span style="color:#2b91af">ArgumentException</span>))]<br />     <span style="color:#0000ff">public</span> <span style="color:#0000ff">void</span> ArgumentListRequestSingleThrowsExceptionTest()<br />     {<br />         <span style="color:#2b91af">IEnumerable</span>&lt;<span style="color:#0000ff">string</span>&gt; args = <span style="color:#0000ff">new</span>[]<br />                                        {<br />                                            <span style="color:#a31515">&#8220;-test:Value&#8221;</span>,<br />                                            <span style="color:#a31515">&#8220;-test:Value2&#8243;</span><br />                                        };</p>
<p>         <span style="color:#0000ff">var</span> target = <span style="color:#0000ff">new</span> <span style="color:#2b91af">Arguments</span>(args);<br />         <span style="color:#008000">//Should throw Argument exception because test is defined more than once</span><br />         target.Single(<span style="color:#a31515">&#8220;test&#8221;</span>);<br />     }</p>
<p>     [<span style="color:#2b91af">TestMethod</span>]<br />     <span style="color:#0000ff">public</span> <span style="color:#0000ff">void</span> ArgumentCommaListTest()<br />     {<br />         <span style="color:#2b91af">IEnumerable</span>&lt;<span style="color:#0000ff">string</span>&gt; args = <span style="color:#0000ff">new</span>[]<br />                                        {<br />                                            <span style="color:#a31515">&#8220;-testList:Value,Value2,Value3&#8243;</span><br />                                        };</p>
<p>         <span style="color:#0000ff">var</span> target = <span style="color:#0000ff">new</span> <span style="color:#2b91af">Arguments</span>(args);<br />         <span style="color:#2b91af">Assert</span>.AreEqual(3, target[<span style="color:#a31515">"testList"</span>].Count);</p>
<p>         <span style="color:#2b91af">Assert</span>.AreEqual(<span style="color:#a31515">&#8220;Value&#8221;</span>, target[<span style="color:#a31515">"testList"</span>][0]);<br />         <span style="color:#2b91af">Assert</span>.AreEqual(<span style="color:#a31515">&#8220;Value2&#8243;</span>, target[<span style="color:#a31515">"testList"</span>][1]);<br />         <span style="color:#2b91af">Assert</span>.AreEqual(<span style="color:#a31515">&#8220;Value3&#8243;</span>, target[<span style="color:#a31515">"testList"</span>][2]);<br />     }<br /> \ </p>
</div>
</div>
</div>
]]></content:encoded>
			<wfw:commentRss>http://jake.ginnivan.net/2009/07/c-argument-parser/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>Writing a Facebook event synchroniser for Outlook 2007+ Part 1</title>
		<link>http://jake.ginnivan.net/2009/07/writing-a-facebook-event-synchroniser-for-outlook-2007-part-1/</link>
		<comments>http://jake.ginnivan.net/2009/07/writing-a-facebook-event-synchroniser-for-outlook-2007-part-1/#comments</comments>
		<pubDate>Sat, 25 Jul 2009 05:40:26 +0000</pubDate>
		<dc:creator>Jake Ginnivan</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Facebook]]></category>
		<category><![CDATA[Outlook]]></category>
		<category><![CDATA[VSTO]]></category>
		<category><![CDATA[WPF]]></category>

		<guid isPermaLink="false">http://jake.ginnivan.net/2009/07/writing-a-facebook-event-synchroniser-for-outlook-2007-part-1/</guid>
		<description><![CDATA[Rather that trying to release and explain my other apps I thought I would write a event sync for outlook that uses WPF for the UI. I will be doing my best to use the MVVM pattern as well.
Requirements:

Visual Studio 2008 SP1 
.net 3.5 SP1 
Facebook Developer Toolkit 2.1 
Continuous LINQ (I think I will <a href="http://jake.ginnivan.net/2009/07/writing-a-facebook-event-synchroniser-for-outlook-2007-part-1/" class="more-link">More &#62;</a>]]></description>
			<content:encoded><![CDATA[<p>Rather that trying to release and explain my other apps I thought I would write a event sync for outlook that uses WPF for the UI. I will be doing my best to use the MVVM pattern as well.</p>
<p><strong>Requirements:</strong></p>
<ul>
<li>Visual Studio 2008 SP1 </li>
<li>.net 3.5 SP1 </li>
<li><a href="http://facebooktoolkit.codeplex.com/" target="_blank">Facebook Developer Toolkit 2.1</a> </li>
<li><a href="http://www.codeplex.com/clinq" target="_blank">Continuous LINQ</a> (I think I will use this) </li>
<li><a href="http://umbrella.codeplex.com/" target="_blank">Umbrella Extensions</a> </li>
<li>My Outlook toolkit I have created</li>
<ul>
<li>
<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:fb3a1972-4489-4e52-abe7-25a00bb07fdf:c70038bc-38f6-493b-9ee0-f5878fa44284" class="wlWriterEditableSmartContent">
<p> <a href="http://jake.ginnivan.net/Images/WritingaFacebookeventsynchroniserforOutl_AFC7/JakeOutlookToolkit_Binary.zip">Binary</a></p>
</div>
</li>
<li>
<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:fb3a1972-4489-4e52-abe7-25a00bb07fdf:e7ef62d2-4163-4aa1-8533-0d397f94557e" class="wlWriterEditableSmartContent">
<p> <a href="http://jake.ginnivan.net/Images/WritingaFacebookeventsynchroniserforOutl_AFC7/JakeOutlookToolkit_Source_6.zip">Source</a></p>
</div>
</li>
</ul>
</ul>
<p><strong>Credits:</strong></p>
<ul>
<li><a href="http://www.microsoft.com/downloads/details.aspx?familyid=078124E9-1E88-4F51-8C98-3C1999CFE743&amp;displaylang=en" target="_blank">Microsoft Outlook/CRM integration Sample</a> </li>
<li><a href="http://adriandev.blogspot.com/2008/01/listening-to-calendar-events-with.html" target="_blank">Adrian Brown’s Calendar monitor</a>, which I have adapted into a generic folder monitor. </li>
</ul>
<p>&#160;<strong>Steps:</strong></p>
<ol>
<li>Create a new Outlook 2007 Add-in.      </li>
<li>Add the following References:      <br /><strong>PresentationCore</strong>       <br /><strong>PresentationFramework</strong>       <br /><strong>WindowsBase</strong>       <br /><strong>WindowsFormsIntegration</strong> (needed to host a WPF control in a outlook inspector)       <br /><strong>JakeOutlookToolkit</strong>       </li>
<li>Add this code to your ThisAddIn_Startup method.      <br /> 
<div>
<pre id="codeSnippet" class="csharpcode"><span class="kwrd">if</span> (System.Windows.Application.Current == <span class="kwrd">null</span>)    <span class="kwrd">new</span> System.Windows.Application { ShutdownMode = System.Windows.ShutdownMode.OnExplicitShutdown };</pre>
</p></div>
<div>&#160;</div>
<div>WPF requires the Application to be instantiated, it is a singleton so it only needs to be instantiated on load then you can reference it anywhere by using Application.Current.</div>
<div>&#160;</div>
<div>The shutdown mode was added because if I showed a WPF window, then the user closed it Outlook would crash the next time you tried to show a WPF window.</div>
</li>
</ol>
<p><strong>What&#8217;s in the toolkit</strong></p>
<p>The toolkit is a collection of classes I have put together and modified for my own use. It contains:</p>
<ul>
<li>An Outlook folder monitor (with add, modified and deleted events you can subscribe to) </li>
<li>ItemAdapter, provides a common wrapper for outlook items, AppointmentItems, MailItems etc only have a single common interface (ItemEvents_10_Event), the ItemAdapter gives you Save, Delete, Display, OnOpen, OnWrite, OnClose events and properties which reduces casting and allows us to be more generic with our outlook app. </li>
<li>Menu, CommandBar, CommandBarManager. A really nice way to work with office toolbars, it automatically subscribes to new explorers and attaches any registered command bar etc. Very handy. </li>
<li>And a few other little things that I find useful. </li>
</ul>
<p>&#160;</p>
<p>We now have the shell of our app, I will be aiming to get this app done this weekend.</p>
<p>I will attach the source of the project once I finish the next part.</p>
]]></content:encoded>
			<wfw:commentRss>http://jake.ginnivan.net/2009/07/writing-a-facebook-event-synchroniser-for-outlook-2007-part-1/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
