<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:blogger='http://schemas.google.com/blogger/2008' xmlns:georss='http://www.georss.org/georss' xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-1977783208088103440</id><updated>2026-05-04T09:17:54.026+03:00</updated><category term="Advanced"/><category term="Intermediate"/><category term="Under the Hood"/><category term="Data"/><category term="Extensions"/><category term="Extension Methods"/><category term="Beginner"/><category term="DataSources"/><category term="RIA Services"/><category term="Business Types"/><category term="Business Logic"/><category term="Designer"/><category term="Learn"/><category term="Concurrency"/><category term="CLASS Extensions"/><category term="Design Patterns"/><category term="Performance"/><title type='text'>Visual Studio LightSwitch tip of the day</title><subtitle type='html'>A ¨did you know¨ weekly updated list for Visual Studio LightSwitch.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://kostaschristodoulou.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1977783208088103440/posts/default?redirect=false'/><link rel='alternate' type='text/html' href='http://kostaschristodoulou.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/1977783208088103440/posts/default?start-index=26&amp;max-results=25&amp;redirect=false'/><author><name>Kostas Christodoulou</name><uri>http://www.blogger.com/profile/07577025344678922877</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='29' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg-vpaqKzo9_w1Z5f97Dh74HcFctRHYFDWYNgNp35Gy2_84EvKNIZl57RAMvxB8JlsIic3iTrZ2Pv7D7leYIc_15MOo4Uh8hJI-4OF2Mv1G9-GYOCsOO_k7uxsAzbLxRNQ/s220/Me2.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>33</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-1977783208088103440.post-3440199405842801402</id><published>2013-05-08T11:03:00.001+03:00</published><updated>2013-05-08T11:35:41.096+03:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Advanced"/><category scheme="http://www.blogger.com/atom/ns#" term="Business Logic"/><category scheme="http://www.blogger.com/atom/ns#" term="DataSources"/><category scheme="http://www.blogger.com/atom/ns#" term="RIA Services"/><category scheme="http://www.blogger.com/atom/ns#" term="Under the Hood"/><title type='text'>CLASS Services</title><content type='html'>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
The next version of CLASS extensions is going to be available by the end of summer with some really interesting goodies added. But, with HTML client (even before it’s official release) being in the center of interest, I feel like Silverlight extensions, are going to be soon, if not already, out of demand.&lt;br /&gt;
So, until I find the time to catch up with HTML client, I though on focusing more to stuff that are client implementation independent. That’s why, apart from the next version of CLASS Extensions for Silverlight clients, I plan on releasing a Server/Common side extension pack called CLASS Services. &lt;br /&gt;
If you are one of the blessed people &lt;img alt=&quot;Angel&quot; class=&quot;wlEmoticon wlEmoticon-angel&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjuMKmXhRDqi9lymKeV9BGg7xh4REFuaKhbHTdJkVVqa4Vu1jSNuQYs6C7_KDfRHprXMbw6S7l1Wap8OZc2QidOk4IBdujCJOEU6xNd822F9YoKLMhfJk_AUHqtbRkXQDaAr8L1dTJRHuBR//?imgmax=800&quot; style=&quot;border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none;&quot; /&gt; that purchased CLASS Extensions, you already know of File Server service included, that provides file based content access to your server.&lt;br /&gt;
Two more of the services that are going to be included in this new CLASS Services pack can be found in this &lt;a href=&quot;http://code.msdn.microsoft.com/Dependancy-Injection-and-2505edc1&quot; target=&quot;_blank&quot;&gt;sample&lt;/a&gt; I posted in MSDN. Ok, I am not crazy, I know that if I share the code no-one will buy the extensions, but these two simple (as regards to the coding effort) services, are just a part of what CLASS Services is going to include. Either way, I believe my Lightswitch community contribution, even if not as extensive and steady as other people’s, makes clear that the idea is sharing and not making money out of it.&lt;br /&gt;
Regarding the sample, I must underline that the application itself is just an example. And I want to stress this point, because some would say that, what the sample application displays is not DI. The idea of the sample was not to display DI in action but just to display how you bind the RIA services together, to do whatever you like. MEF is used as a DI framework by the RIA Service to provide the required functionality.&lt;br /&gt;
Also, I have to admit that if properly implemented, by the book, restrictions and conventions in imports and exports of MEF (or any other DI framework for that matter) would make any additional configuration (like the one my sample suggests) pointless.&lt;br /&gt;
Nevertheless, IMHO, you really have to be a DI purist, not to recognize the potential provided by these two services. An example: In Computer Life, we plan (George stop calling me names &lt;img alt=&quot;Smile with tongue out&quot; class=&quot;wlEmoticon wlEmoticon-smilewithtongueout&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjDeLsm02NXE6e3EsOzJbaTuAD_J632Ptb3xf2W9iJ1EQKAnzWA_-wjO2K-rlV73h0Qo8GfGEIK0saMFZBMQDMVjbbmHP7WbVquuzJO8SCJNBWEsJaL68FgFV3Jo1FEWsIMksoz56vTl_Kv//?imgmax=800&quot; style=&quot;border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none;&quot; /&gt;) to implement a generic (extension) way to support &lt;a href=&quot;http://en.wikipedia.org/wiki/Entity%E2%80%93attribute%E2%80%93value_model&quot; target=&quot;_blank&quot;&gt;EAV model&lt;/a&gt;&amp;nbsp;in our Lightswitch applications. It’s so obvious how useful the Domain Types RIA service will be for this implementation that I won’t even bother writing anything to prove it.&lt;br /&gt;
Anyway, I hope you find these two RIA services useful. I realize you have to go far beyond the “Coding is optional” motto to make good use of this kind of services, but I believe the Lightswitch development community, has already given the answer to that (not at all well-intentioned) “It’s the next MS-Access” hype…&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://kostaschristodoulou.blogspot.com/feeds/3440199405842801402/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kostaschristodoulou.blogspot.com/2013/05/class-services.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1977783208088103440/posts/default/3440199405842801402'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1977783208088103440/posts/default/3440199405842801402'/><link rel='alternate' type='text/html' href='http://kostaschristodoulou.blogspot.com/2013/05/class-services.html' title='CLASS Services'/><author><name>Kostas Christodoulou</name><uri>http://www.blogger.com/profile/07577025344678922877</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='29' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg-vpaqKzo9_w1Z5f97Dh74HcFctRHYFDWYNgNp35Gy2_84EvKNIZl57RAMvxB8JlsIic3iTrZ2Pv7D7leYIc_15MOo4Uh8hJI-4OF2Mv1G9-GYOCsOO_k7uxsAzbLxRNQ/s220/Me2.jpg'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjuMKmXhRDqi9lymKeV9BGg7xh4REFuaKhbHTdJkVVqa4Vu1jSNuQYs6C7_KDfRHprXMbw6S7l1Wap8OZc2QidOk4IBdujCJOEU6xNd822F9YoKLMhfJk_AUHqtbRkXQDaAr8L1dTJRHuBR/s72-c/?imgmax=800" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1977783208088103440.post-811651232058246639</id><published>2013-02-05T15:49:00.001+02:00</published><updated>2013-02-05T15:52:16.759+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Advanced"/><category scheme="http://www.blogger.com/atom/ns#" term="Business Logic"/><category scheme="http://www.blogger.com/atom/ns#" term="Data"/><category scheme="http://www.blogger.com/atom/ns#" term="Extension Methods"/><category scheme="http://www.blogger.com/atom/ns#" term="Intermediate"/><category scheme="http://www.blogger.com/atom/ns#" term="Under the Hood"/><title type='text'>Can I delete this?</title><content type='html'>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
In a &lt;a href=&quot;http://kostaschristodoulou.blogspot.gr/2012/06/simple-extension-methods-part-2.html&quot; target=&quot;_blank&quot;&gt;previous post&lt;/a&gt; I suggested a way to override default LightSwitch add/edit behavior. In this post I will suggest an override to default delete behavior.&lt;br /&gt;
It has happened many times to delete entries, only to get an error message, when trying to save, informing me about reference constraints being violated and the action cannot be completed. This is not much of problem when you try to delete one record (apart from the fact this message is ugly and not one that I would allow my end users to deal with, for that matter). But when trying to delete many records you have no clue which was the one (or more) record(s) that cannot be deleted. In this case all you can do is delete-save until you find the record that cannot be deleted. And when you find it, you have to refresh your screen or undo the changes of the current record (a future article will suggest a way to do this).&lt;br /&gt;
What I needed was a good generic way to be able to set &lt;em&gt;Delete_CanExecute &lt;/em&gt;result. This is my suggestion using (what else) extension methods, interfaces (Yann will love me for this &lt;img alt=&quot;Smile&quot; class=&quot;wlEmoticon wlEmoticon-smile&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgSg-HJ_F5kLTHBRXEopZ_ws7r5_U9OgavHn-fgPW-bKWj1qpv0vACGXC-I69RhVKEDp3OyE8ASWaS4HIrNEerewo2y-_lPN7GTT-O0kKmmtI_1tbdxLuAhMV7DK2rSHKaJAXQeZ05jqg_H//?imgmax=800&quot; style=&quot;border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none;&quot; /&gt;) and an attribute.&lt;br /&gt;
First the interface to help decide if an instance can be deleted or not:&lt;br /&gt;
&lt;pre class=&quot;csharpcode&quot;&gt;&lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;interface&lt;/span&gt; IDependencyCheck : IEntityObject
{
  &lt;span class=&quot;kwrd&quot;&gt;bool&lt;/span&gt; CanDelete { get; }
}&lt;/pre&gt;
&lt;br /&gt;
&lt;br /&gt;&lt;style type=&quot;text/css&quot;&gt;.csharpcode, .csharpcode pre&lt;br /&gt;{&lt;br /&gt;	font-size: small;&lt;br /&gt;	color: black;&lt;br /&gt;	font-family: consolas, &quot;Courier New&quot;, courier, monospace;&lt;br /&gt;	background-color: #ffffff;&lt;br /&gt;	/*white-space: pre;*/&lt;br /&gt;}&lt;br /&gt;.csharpcode pre { margin: 0em; }&lt;br /&gt;.csharpcode .rem { color: #008000; }&lt;br /&gt;.csharpcode .kwrd { color: #0000ff; }&lt;br /&gt;.csharpcode .str { color: #006080; }&lt;br /&gt;.csharpcode .op { color: #0000c0; }&lt;br /&gt;.csharpcode .preproc { color: #cc6633; }&lt;br /&gt;.csharpcode .asp { background-color: #ffff00; }&lt;br /&gt;.csharpcode .html { color: #800000; }&lt;br /&gt;.csharpcode .attr { color: #ff0000; }&lt;br /&gt;.csharpcode .alt &lt;br /&gt;{&lt;br /&gt;	background-color: #f4f4f4;&lt;br /&gt;	width: 100%;&lt;br /&gt;	margin: 0em;&lt;br /&gt;}&lt;br /&gt;.csharpcode .lnum { color: #606060; }&lt;br /&gt;&lt;/style&gt;&lt;br /&gt;Quite simple you must admit. Keep in mind interfaces you want to use in your common project have to be accessible both by Server and Client project also. If someone here thinks of &lt;em&gt;EntityName_CanDelete&lt;/em&gt;, someone forgets that it is a server side hook.&lt;br /&gt;
&lt;br /&gt;
Now an attribute to help us decide which of the dependencies an entity might have are strong ones, meaning that the referential integrity of the database or your business logic if you don’t use database constraints, would not allow an instance to be deleted.&lt;br /&gt;
&lt;pre class=&quot;csharpcode&quot;&gt;[AttributeUsage(AttributeTargets.Class)]
&lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;class&lt;/span&gt; StrongDependencyAttribute : Attribute
{
  &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; StrongDependencyAttribute(&lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt; dependencies) {
    &lt;span class=&quot;kwrd&quot;&gt;this&lt;/span&gt;.dependencies = dependencies.ToStringArray();
  }

  &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt;[] Dependencies {
    get { &lt;span class=&quot;kwrd&quot;&gt;return&lt;/span&gt; dependencies; }
  }

  &lt;span class=&quot;kwrd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;readonly&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt;[] dependencies;
}
&lt;style type=&quot;text/css&quot;&gt;.csharpcode, .csharpcode pre&lt;br /&gt;{&lt;br /&gt;	font-size: small;&lt;br /&gt;	color: black;&lt;br /&gt;	font-family: consolas, &quot;Courier New&quot;, courier, monospace;&lt;br /&gt;	background-color: #ffffff;&lt;br /&gt;	/*white-space: pre;*/&lt;br /&gt;}&lt;br /&gt;.csharpcode pre { margin: 0em; }&lt;br /&gt;.csharpcode .rem { color: #008000; }&lt;br /&gt;.csharpcode .kwrd { color: #0000ff; }&lt;br /&gt;.csharpcode .str { color: #006080; }&lt;br /&gt;.csharpcode .op { color: #0000c0; }&lt;br /&gt;.csharpcode .preproc { color: #cc6633; }&lt;br /&gt;.csharpcode .asp { background-color: #ffff00; }&lt;br /&gt;.csharpcode .html { color: #800000; }&lt;br /&gt;.csharpcode .attr { color: #ff0000; }&lt;br /&gt;.csharpcode .alt &lt;br /&gt;{&lt;br /&gt;	background-color: #f4f4f4;&lt;br /&gt;	width: 100%;&lt;br /&gt;	margin: 0em;&lt;br /&gt;}&lt;br /&gt;.csharpcode .lnum { color: #606060; }&lt;br /&gt;&lt;/style&gt;&lt;/pre&gt;
&lt;br /&gt;
This attribute takes a list of strong reference property names as comma delimited string (or whatever delimiter you like for that matter) using these simple extensions:&lt;br /&gt;
&lt;pre class=&quot;csharpcode&quot;&gt;&lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt;[] ToStringArray(&lt;span class=&quot;kwrd&quot;&gt;this&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt; strings) {
   &lt;span class=&quot;kwrd&quot;&gt;return&lt;/span&gt; strings.ToStringArray(&lt;span class=&quot;str&quot;&gt;&#39;,&#39;&lt;/span&gt;);
}

&lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt;[] ToStringArray(&lt;span class=&quot;kwrd&quot;&gt;this&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt; strings, &lt;span class=&quot;kwrd&quot;&gt;char&lt;/span&gt; delimiter) {
   &lt;span class=&quot;kwrd&quot;&gt;return&lt;/span&gt; (from &lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt; item &lt;span class=&quot;kwrd&quot;&gt;in&lt;/span&gt; strings.Split(&lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;char&lt;/span&gt;[] { delimiter }, StringSplitOptions.RemoveEmptyEntries)
               select item.Trim()).ToArray();
}&lt;/pre&gt;
&lt;br /&gt;
&lt;style type=&quot;text/css&quot;&gt;.csharpcode, .csharpcode pre&lt;br /&gt;{&lt;br /&gt;	font-size: small;&lt;br /&gt;	color: black;&lt;br /&gt;	font-family: consolas, &quot;Courier New&quot;, courier, monospace;&lt;br /&gt;	background-color: #ffffff;&lt;br /&gt;	/*white-space: pre;*/&lt;br /&gt;}&lt;br /&gt;.csharpcode pre { margin: 0em; }&lt;br /&gt;.csharpcode .rem { color: #008000; }&lt;br /&gt;.csharpcode .kwrd { color: #0000ff; }&lt;br /&gt;.csharpcode .str { color: #006080; }&lt;br /&gt;.csharpcode .op { color: #0000c0; }&lt;br /&gt;.csharpcode .preproc { color: #cc6633; }&lt;br /&gt;.csharpcode .asp { background-color: #ffff00; }&lt;br /&gt;.csharpcode .html { color: #800000; }&lt;br /&gt;.csharpcode .attr { color: #ff0000; }&lt;br /&gt;.csharpcode .alt &lt;br /&gt;{&lt;br /&gt;	background-color: #f4f4f4;&lt;br /&gt;	width: 100%;&lt;br /&gt;	margin: 0em;&lt;br /&gt;}&lt;br /&gt;.csharpcode .lnum { color: #606060; }&lt;br /&gt;&lt;/style&gt;&lt;br /&gt;
&lt;br /&gt;
If you want to use another delimiter just replace &lt;br /&gt;
&lt;pre class=&quot;csharpcode&quot;&gt;&lt;span class=&quot;kwrd&quot;&gt;this&lt;/span&gt;.dependencies = dependencies.ToStringArray();&lt;/pre&gt;
&lt;br /&gt;
&lt;style type=&quot;text/css&quot;&gt;.csharpcode, .csharpcode pre&lt;br /&gt;{&lt;br /&gt;	font-size: small;&lt;br /&gt;	color: black;&lt;br /&gt;	font-family: consolas, &quot;Courier New&quot;, courier, monospace;&lt;br /&gt;	background-color: #ffffff;&lt;br /&gt;	/*white-space: pre;*/&lt;br /&gt;}&lt;br /&gt;.csharpcode pre { margin: 0em; }&lt;br /&gt;.csharpcode .rem { color: #008000; }&lt;br /&gt;.csharpcode .kwrd { color: #0000ff; }&lt;br /&gt;.csharpcode .str { color: #006080; }&lt;br /&gt;.csharpcode .op { color: #0000c0; }&lt;br /&gt;.csharpcode .preproc { color: #cc6633; }&lt;br /&gt;.csharpcode .asp { background-color: #ffff00; }&lt;br /&gt;.csharpcode .html { color: #800000; }&lt;br /&gt;.csharpcode .attr { color: #ff0000; }&lt;br /&gt;.csharpcode .alt &lt;br /&gt;{&lt;br /&gt;	background-color: #f4f4f4;&lt;br /&gt;	width: 100%;&lt;br /&gt;	margin: 0em;&lt;br /&gt;}&lt;br /&gt;.csharpcode .lnum { color: #606060; }&lt;br /&gt;&lt;/style&gt;&lt;br /&gt;
&lt;br /&gt;
in the constructor with (for example):&lt;br /&gt;
&lt;pre class=&quot;csharpcode&quot;&gt;&lt;span class=&quot;kwrd&quot;&gt;this&lt;/span&gt;.dependencies = dependencies.ToStringArray(&lt;span class=&quot;str&quot;&gt;&#39;;&#39;&lt;/span&gt;);&lt;/pre&gt;
&lt;br /&gt;
Or if you want, you can have one instance of the attribute for each property you want to check and avoid delimited strings altogether. Plenty of choices…&lt;img alt=&quot;Smile&quot; class=&quot;wlEmoticon wlEmoticon-smile&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgSg-HJ_F5kLTHBRXEopZ_ws7r5_U9OgavHn-fgPW-bKWj1qpv0vACGXC-I69RhVKEDp3OyE8ASWaS4HIrNEerewo2y-_lPN7GTT-O0kKmmtI_1tbdxLuAhMV7DK2rSHKaJAXQeZ05jqg_H//?imgmax=800&quot; style=&quot;border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none;&quot; /&gt;.&lt;br /&gt;
&lt;br /&gt;
Keep in mind that if you declare no instance of this attribute but you implement &lt;strong&gt;IDependencyCheck&lt;/strong&gt; then ALL dependencies will be considered as strong ones and checked for integrity. &lt;br /&gt;
&lt;br /&gt;
This attribute needs to be accessible by the Common project only.&lt;br /&gt;
&lt;br /&gt;
Now, all that said, there are two extension methods that will help us do the job.&lt;br /&gt;
&lt;br /&gt;
The first one needs to be accessible by the Client project only:&lt;br /&gt;
&lt;pre class=&quot;csharpcode&quot;&gt;&lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;bool&lt;/span&gt; CanDeleteSelection(&lt;span class=&quot;kwrd&quot;&gt;this&lt;/span&gt; IScreenObject screen, &lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt; collectionName) {
   &lt;span class=&quot;kwrd&quot;&gt;if&lt;/span&gt; (!screen.HasSelection(collectionName))
     &lt;span class=&quot;kwrd&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;false&lt;/span&gt;;
   IVisualCollection collection = screen.Details.Properties[collectionName].Value &lt;span class=&quot;kwrd&quot;&gt;as&lt;/span&gt; IVisualCollection;
   &lt;span class=&quot;kwrd&quot;&gt;if&lt;/span&gt; (collection.SelectedItem &lt;span class=&quot;kwrd&quot;&gt;is&lt;/span&gt; IDependencyCheck)
     &lt;span class=&quot;kwrd&quot;&gt;return&lt;/span&gt; (collection.SelectedItem &lt;span class=&quot;kwrd&quot;&gt;as&lt;/span&gt; IDependencyCheck).CanDelete;
   &lt;span class=&quot;kwrd&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;true&lt;/span&gt;;
}&lt;/pre&gt;
&lt;br /&gt;
&lt;style type=&quot;text/css&quot;&gt;.csharpcode, .csharpcode pre&lt;br /&gt;{&lt;br /&gt;	font-size: small;&lt;br /&gt;	color: black;&lt;br /&gt;	font-family: consolas, &quot;Courier New&quot;, courier, monospace;&lt;br /&gt;	background-color: #ffffff;&lt;br /&gt;	/*white-space: pre;*/&lt;br /&gt;}&lt;br /&gt;.csharpcode pre { margin: 0em; }&lt;br /&gt;.csharpcode .rem { color: #008000; }&lt;br /&gt;.csharpcode .kwrd { color: #0000ff; }&lt;br /&gt;.csharpcode .str { color: #006080; }&lt;br /&gt;.csharpcode .op { color: #0000c0; }&lt;br /&gt;.csharpcode .preproc { color: #cc6633; }&lt;br /&gt;.csharpcode .asp { background-color: #ffff00; }&lt;br /&gt;.csharpcode .html { color: #800000; }&lt;br /&gt;.csharpcode .attr { color: #ff0000; }&lt;br /&gt;.csharpcode .alt &lt;br /&gt;{&lt;br /&gt;	background-color: #f4f4f4;&lt;br /&gt;	width: 100%;&lt;br /&gt;	margin: 0em;&lt;br /&gt;}&lt;br /&gt;.csharpcode .lnum { color: #606060; }&lt;br /&gt;&lt;/style&gt;&lt;br /&gt;
&lt;br /&gt;
Please note I am using IScreenObject.HasSelection extension that has already been introduced in a &lt;a href=&quot;http://kostaschristodoulou.blogspot.gr/2012/06/simple-extension-methods-part-2.html&quot; target=&quot;_blank&quot;&gt;previous post&lt;/a&gt;. That’s why I am not checking if the cast to IVisualCollection is successful (not null).&lt;br /&gt;
&lt;br /&gt;
The second one has to be accessible by the Common project only:&lt;br /&gt;
&lt;pre class=&quot;csharpcode&quot;&gt;    &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;bool&lt;/span&gt; CanDelete(&lt;span class=&quot;kwrd&quot;&gt;this&lt;/span&gt; IEntityObject entity) {
      IEnumerable&amp;lt;IEntityCollectionProperty&amp;gt; collectionProperties = 
        entity.Details.Properties.All()
        .Where(p =&amp;gt; p.GetType().GetInterfaces()
          .Where(t =&amp;gt; t.Name.Equals(&lt;span class=&quot;str&quot;&gt;&quot;IEntityCollectionProperty&quot;&lt;/span&gt;))
          .FirstOrDefault() != &lt;span class=&quot;kwrd&quot;&gt;null&lt;/span&gt;)
        .Cast&amp;lt;IEntityCollectionProperty&amp;gt;();
      &lt;span class=&quot;kwrd&quot;&gt;if&lt;/span&gt; (collectionProperties == &lt;span class=&quot;kwrd&quot;&gt;null&lt;/span&gt;)
        &lt;span class=&quot;kwrd&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;true&lt;/span&gt;;
      List&amp;lt;&lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt;&amp;gt; strongDependencies = &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; List&amp;lt;&lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt;&amp;gt;();
      IEnumerable&amp;lt;StrongDependencyAttribute&amp;gt; dependencies = 
        entity.GetType()
        .GetCustomAttributes(&lt;span class=&quot;kwrd&quot;&gt;typeof&lt;/span&gt;(StrongDependencyAttribute), &lt;span class=&quot;kwrd&quot;&gt;false&lt;/span&gt;)
        .Cast&amp;lt;StrongDependencyAttribute&amp;gt;();
      &lt;span class=&quot;kwrd&quot;&gt;foreach&lt;/span&gt; (StrongDependencyAttribute dependency &lt;span class=&quot;kwrd&quot;&gt;in&lt;/span&gt; dependencies)
        strongDependencies.AddRange(dependency.Dependencies);
      &lt;span class=&quot;kwrd&quot;&gt;bool&lt;/span&gt; hasDependencies = strongDependencies.FirstOrDefault() != &lt;span class=&quot;kwrd&quot;&gt;null&lt;/span&gt;;
      &lt;span class=&quot;kwrd&quot;&gt;bool&lt;/span&gt; canDelete = &lt;span class=&quot;kwrd&quot;&gt;true&lt;/span&gt;;
      &lt;span class=&quot;kwrd&quot;&gt;foreach&lt;/span&gt; (IEntityCollectionProperty property &lt;span class=&quot;kwrd&quot;&gt;in&lt;/span&gt; collectionProperties) {
        &lt;span class=&quot;kwrd&quot;&gt;if&lt;/span&gt; (hasDependencies &amp;amp;&amp;amp;strongDependencies.FirstOrDefault(d =&amp;gt; d.Equals(property.Name)) == &lt;span class=&quot;kwrd&quot;&gt;null&lt;/span&gt;)
          &lt;span class=&quot;kwrd&quot;&gt;continue&lt;/span&gt;;
        IEnumerable &lt;span class=&quot;kwrd&quot;&gt;value&lt;/span&gt; = entity.GetType()
          .GetProperty(&lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt;.Format(&lt;span class=&quot;str&quot;&gt;&quot;{0}Query&quot;&lt;/span&gt;, property.Name))
          .GetValue(entity, &lt;span class=&quot;kwrd&quot;&gt;null&lt;/span&gt;) &lt;span class=&quot;kwrd&quot;&gt;as&lt;/span&gt; IEnumerable;
        &lt;span class=&quot;kwrd&quot;&gt;try&lt;/span&gt; {
          &lt;span class=&quot;kwrd&quot;&gt;if&lt;/span&gt; (&lt;span class=&quot;kwrd&quot;&gt;value&lt;/span&gt; != &lt;span class=&quot;kwrd&quot;&gt;null&lt;/span&gt; &amp;amp;&amp;amp; &lt;span class=&quot;kwrd&quot;&gt;value&lt;/span&gt;.GetEnumerator().MoveNext()) {
            canDelete = &lt;span class=&quot;kwrd&quot;&gt;false&lt;/span&gt;;
            &lt;span class=&quot;kwrd&quot;&gt;break&lt;/span&gt;;
          }
        }
        &lt;span class=&quot;kwrd&quot;&gt;catch&lt;/span&gt; {
          &lt;span class=&quot;kwrd&quot;&gt;continue&lt;/span&gt;;
        }
      }
      &lt;span class=&quot;kwrd&quot;&gt;return&lt;/span&gt; canDelete;
    }&lt;/pre&gt;
&lt;br /&gt;
&lt;br /&gt;&lt;style type=&quot;text/css&quot;&gt;.csharpcode, .csharpcode pre&lt;br /&gt;{&lt;br /&gt;	font-size: small;&lt;br /&gt;	color: black;&lt;br /&gt;	font-family: consolas, &quot;Courier New&quot;, courier, monospace;&lt;br /&gt;	background-color: #ffffff;&lt;br /&gt;	/*white-space: pre;*/&lt;br /&gt;}&lt;br /&gt;.csharpcode pre { margin: 0em; }&lt;br /&gt;.csharpcode .rem { color: #008000; }&lt;br /&gt;.csharpcode .kwrd { color: #0000ff; }&lt;br /&gt;.csharpcode .str { color: #006080; }&lt;br /&gt;.csharpcode .op { color: #0000c0; }&lt;br /&gt;.csharpcode .preproc { color: #cc6633; }&lt;br /&gt;.csharpcode .asp { background-color: #ffff00; }&lt;br /&gt;.csharpcode .html { color: #800000; }&lt;br /&gt;.csharpcode .attr { color: #ff0000; }&lt;br /&gt;.csharpcode .alt &lt;br /&gt;{&lt;br /&gt;	background-color: #f4f4f4;&lt;br /&gt;	width: 100%;&lt;br /&gt;	margin: 0em;&lt;br /&gt;}&lt;br /&gt;.csharpcode .lnum { color: #606060; }&lt;br /&gt;&lt;/style&gt;&lt;br /&gt;Although it’s obvious at first glance what the code does &lt;img alt=&quot;Hot smile&quot; class=&quot;wlEmoticon wlEmoticon-hotsmile&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgS-nV4lnt6-s3nMOzSm4yGf0x8dUc1KEl9Vrno_ZyQrCC3AmpBGjaTPl-c0w0UFz_29_iMByu9rqlEj-wHZWEn65u1qqeYRktAcueHArEGra0rFteCSXjvL8uPvMJpAKS-BCI2VBHhAPD-//?imgmax=800&quot; style=&quot;border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none;&quot; /&gt;, I will give brief explanation:&lt;br /&gt;
&lt;br /&gt;
If there is not a &lt;strong&gt;StrongDependencyAtttibute&lt;/strong&gt; defined for the entity then all reference properties are checked and if at least one has members then the entity cannot be deleted. If a &lt;strong&gt;StrongDependencyAtttibute&lt;/strong&gt; is defined for the entity then only reference properties included in the attribute are checked. That’s all…&lt;br /&gt;
&lt;br /&gt;
If you manage to read the code (I am not very proud about the absence of comments) you will notice that only one-to-many and many-to-many references are handled. In my world one-to-one references mean inheritance and in this case both objects should be deleted. But what if the base object can be deleted (has no direct references) and the derived object has? Again in my world, if you are trying to delete the base object you are already doing it wrong! Anyway if someone lives in a world other than mine (I am very democratic guy &lt;img alt=&quot;Be right back&quot; class=&quot;wlEmoticon wlEmoticon-berightback&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEih1kPSlDymFhnzmig3ye9F9IELMGxbzflzg_m0JXxAh9neS-6oUfpQ9JIafQIqkahbcEiLOZy9GHvpjFqbIswlLF0ad6uklQJqWndd3P4BsOm6kQDHFZ5wRe9ORfv3u0E4hDFW-4Gpi6FD//?imgmax=800&quot; style=&quot;border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none;&quot; /&gt;) and wants to support one-to-one relations all he/she has to do is find where &lt;strong&gt;IEntityCollectionProperty &lt;/strong&gt;definition is and look for the respective property type (I believe it is &lt;strong&gt;IEntityReferenceProperty &lt;/strong&gt;but I am not quite sure).&lt;br /&gt;
&lt;br /&gt;
And for the end an example so that anyone can see what all of the above end up to:&lt;br /&gt;
&lt;br /&gt;
Suppose you have a &lt;strong&gt;Customer&lt;/strong&gt; entity. And this Customer entity has a collection of &lt;strong&gt;Orders&lt;/strong&gt;. The property of the &lt;strong&gt;Customer&lt;/strong&gt; entity that holds these orders is called &lt;strong&gt;CustomerOrders&lt;/strong&gt;. In your Datasource you right-click &lt;strong&gt;Customer&lt;/strong&gt; entity and select &lt;strong&gt;View Table Code&lt;/strong&gt;. A partial class implementation file is created (if it does not already exist). Modify the definition of you class as follows:&lt;br /&gt;
&lt;pre class=&quot;csharpcode&quot;&gt;[StrongDependency(&lt;span class=&quot;str&quot;&gt;&quot;CustomerOrders&quot;&lt;/span&gt;)]
&lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;partial&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;class&lt;/span&gt; Customer : IDependencyCheck {
...

  &lt;span class=&quot;preproc&quot;&gt;#region&lt;/span&gt; IDependencyCheck members 
  &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;bool&lt;/span&gt; CanDelete {
    get { &lt;span class=&quot;kwrd&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;this&lt;/span&gt;.CanDelete(); }
  }
  &lt;span class=&quot;preproc&quot;&gt;#endregion&lt;/span&gt; IDependencyCheck members
}&lt;/pre&gt;
&lt;br /&gt;
&lt;style type=&quot;text/css&quot;&gt;.csharpcode, .csharpcode pre&lt;br /&gt;{&lt;br /&gt;	font-size: small;&lt;br /&gt;	color: black;&lt;br /&gt;	font-family: consolas, &quot;Courier New&quot;, courier, monospace;&lt;br /&gt;	background-color: #ffffff;&lt;br /&gt;	/*white-space: pre;*/&lt;br /&gt;}&lt;br /&gt;.csharpcode pre { margin: 0em; }&lt;br /&gt;.csharpcode .rem { color: #008000; }&lt;br /&gt;.csharpcode .kwrd { color: #0000ff; }&lt;br /&gt;.csharpcode .str { color: #006080; }&lt;br /&gt;.csharpcode .op { color: #0000c0; }&lt;br /&gt;.csharpcode .preproc { color: #cc6633; }&lt;br /&gt;.csharpcode .asp { background-color: #ffff00; }&lt;br /&gt;.csharpcode .html { color: #800000; }&lt;br /&gt;.csharpcode .attr { color: #ff0000; }&lt;br /&gt;.csharpcode .alt &lt;br /&gt;{&lt;br /&gt;	background-color: #f4f4f4;&lt;br /&gt;	width: 100%;&lt;br /&gt;	margin: 0em;&lt;br /&gt;}&lt;br /&gt;.csharpcode .lnum { color: #606060; }&lt;br /&gt;&lt;/style&gt;&lt;br /&gt;
&lt;br /&gt;
Remember to reference (using) the namespace where your extension method (&lt;strong&gt;CanDelete)&lt;/strong&gt; is declared.&lt;br /&gt;
&lt;br /&gt;
Please note that &lt;strong&gt;IDependencyCheck&lt;/strong&gt; gives you the potential to write whatever else hardcoded (or not) check you want in your &lt;strong&gt;CanDelete&lt;/strong&gt; property implementation. In the code above I just call the extension method I introduced earlier. But you can do whatever you want. You can even skip the dependencies mechanism suggested altogether. The client side extension will still work.&lt;br /&gt;
&lt;br /&gt;
So in the screen that you have your list of Customers right click the &lt;strong&gt;Delete&lt;/strong&gt; command of the list or grid and in the &lt;strong&gt;&lt;em&gt;CustomersDelete_CanExecute &lt;/em&gt;&lt;/strong&gt;just write:&lt;br /&gt;
&lt;pre class=&quot;csharpcode&quot;&gt;&lt;span class=&quot;kwrd&quot;&gt;partial&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;void&lt;/span&gt; CustomersDelete_CanExecute(&lt;span class=&quot;kwrd&quot;&gt;ref&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;bool&lt;/span&gt; result){
  result = &lt;span class=&quot;kwrd&quot;&gt;this&lt;/span&gt;.CanDeleteSelection(&lt;span class=&quot;str&quot;&gt;&quot;Customers&quot;&lt;/span&gt;);
}&lt;/pre&gt;
&lt;br /&gt;
&lt;style type=&quot;text/css&quot;&gt;.csharpcode, .csharpcode pre&lt;br /&gt;{&lt;br /&gt;	font-size: small;&lt;br /&gt;	color: black;&lt;br /&gt;	font-family: consolas, &quot;Courier New&quot;, courier, monospace;&lt;br /&gt;	background-color: #ffffff;&lt;br /&gt;	/*white-space: pre;*/&lt;br /&gt;}&lt;br /&gt;.csharpcode pre { margin: 0em; }&lt;br /&gt;.csharpcode .rem { color: #008000; }&lt;br /&gt;.csharpcode .kwrd { color: #0000ff; }&lt;br /&gt;.csharpcode .str { color: #006080; }&lt;br /&gt;.csharpcode .op { color: #0000c0; }&lt;br /&gt;.csharpcode .preproc { color: #cc6633; }&lt;br /&gt;.csharpcode .asp { background-color: #ffff00; }&lt;br /&gt;.csharpcode .html { color: #800000; }&lt;br /&gt;.csharpcode .attr { color: #ff0000; }&lt;br /&gt;.csharpcode .alt &lt;br /&gt;{&lt;br /&gt;	background-color: #f4f4f4;&lt;br /&gt;	width: 100%;&lt;br /&gt;	margin: 0em;&lt;br /&gt;}&lt;br /&gt;.csharpcode .lnum { color: #606060; }&lt;br /&gt;&lt;/style&gt;&lt;br /&gt;
&lt;br /&gt;
As partial implementation of Execute write:&lt;br /&gt;
&lt;pre class=&quot;csharpcode&quot;&gt;&lt;span class=&quot;kwrd&quot;&gt;partial&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;void&lt;/span&gt; CustomersDelete_Execute(){
  &lt;span class=&quot;kwrd&quot;&gt;this&lt;/span&gt;.Customers.DeleteSelected();
}&lt;/pre&gt;
&lt;br /&gt;
&lt;style type=&quot;text/css&quot;&gt;.csharpcode, .csharpcode pre&lt;br /&gt;{&lt;br /&gt;	font-size: small;&lt;br /&gt;	color: black;&lt;br /&gt;	font-family: consolas, &quot;Courier New&quot;, courier, monospace;&lt;br /&gt;	background-color: #ffffff;&lt;br /&gt;	/*white-space: pre;*/&lt;br /&gt;}&lt;br /&gt;.csharpcode pre { margin: 0em; }&lt;br /&gt;.csharpcode .rem { color: #008000; }&lt;br /&gt;.csharpcode .kwrd { color: #0000ff; }&lt;br /&gt;.csharpcode .str { color: #006080; }&lt;br /&gt;.csharpcode .op { color: #0000c0; }&lt;br /&gt;.csharpcode .preproc { color: #cc6633; }&lt;br /&gt;.csharpcode .asp { background-color: #ffff00; }&lt;br /&gt;.csharpcode .html { color: #800000; }&lt;br /&gt;.csharpcode .attr { color: #ff0000; }&lt;br /&gt;.csharpcode .alt &lt;br /&gt;{&lt;br /&gt;	background-color: #f4f4f4;&lt;br /&gt;	width: 100%;&lt;br /&gt;	margin: 0em;&lt;br /&gt;}&lt;br /&gt;.csharpcode .lnum { color: #606060; }&lt;br /&gt;&lt;/style&gt;&lt;br /&gt;
&lt;br /&gt;
I know some of you have already noticed the overhead of potentially loading the dependent objects the first time you select an item of your list or grid. I cannot argue with that, except for the fact that my approach is suggested for intranet implementations (I am not sure I would do something like that over the web) and the fact that the time under these circumstances is an acceptable price to pay in order to avoid the annoying referential integrity message. At least in my world &lt;img alt=&quot;Smile&quot; class=&quot;wlEmoticon wlEmoticon-smile&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgSg-HJ_F5kLTHBRXEopZ_ws7r5_U9OgavHn-fgPW-bKWj1qpv0vACGXC-I69RhVKEDp3OyE8ASWaS4HIrNEerewo2y-_lPN7GTT-O0kKmmtI_1tbdxLuAhMV7DK2rSHKaJAXQeZ05jqg_H//?imgmax=800&quot; style=&quot;border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none;&quot; /&gt;.&amp;nbsp; &lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://kostaschristodoulou.blogspot.com/feeds/811651232058246639/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kostaschristodoulou.blogspot.com/2013/02/can-i-delete-this.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1977783208088103440/posts/default/811651232058246639'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1977783208088103440/posts/default/811651232058246639'/><link rel='alternate' type='text/html' href='http://kostaschristodoulou.blogspot.com/2013/02/can-i-delete-this.html' title='Can I delete this?'/><author><name>Kostas Christodoulou</name><uri>http://www.blogger.com/profile/07577025344678922877</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='29' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg-vpaqKzo9_w1Z5f97Dh74HcFctRHYFDWYNgNp35Gy2_84EvKNIZl57RAMvxB8JlsIic3iTrZ2Pv7D7leYIc_15MOo4Uh8hJI-4OF2Mv1G9-GYOCsOO_k7uxsAzbLxRNQ/s220/Me2.jpg'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgSg-HJ_F5kLTHBRXEopZ_ws7r5_U9OgavHn-fgPW-bKWj1qpv0vACGXC-I69RhVKEDp3OyE8ASWaS4HIrNEerewo2y-_lPN7GTT-O0kKmmtI_1tbdxLuAhMV7DK2rSHKaJAXQeZ05jqg_H/s72-c/?imgmax=800" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1977783208088103440.post-8583017614353388692</id><published>2012-11-07T11:16:00.001+02:00</published><updated>2012-11-07T16:51:24.909+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Advanced"/><category scheme="http://www.blogger.com/atom/ns#" term="Intermediate"/><category scheme="http://www.blogger.com/atom/ns#" term="Under the Hood"/><title type='text'>De-fault Screens</title><content type='html'>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
If you have tried implementing something that required a mechanism more complex than the default one provided by LightSwitch regarding default screen selection, you already are familiar with the limitations.&lt;br /&gt;
For the ones that don’t get what I mean, a very common example is open the details screen of an object from a list containing items from a view (database view) that include the id of the original object. Imagine you have a &lt;strong&gt;Customer&lt;/strong&gt; entity and a &lt;strong&gt;CustomerInfo&lt;/strong&gt; entity that comes from a database view bringing aggregated data of the customer from various tables. Selecting and editing the &lt;strong&gt;CustomerInfo&lt;/strong&gt; you want to edit the &lt;strong&gt;Customer &lt;/strong&gt;not the &lt;strong&gt;CustomerInfo.&lt;/strong&gt; &lt;br /&gt;
The above is only one fast example. Another would be having Add/Edit Screens i.e. screens that can handle both create or edit an existing object. In any case if you need to modify the default signature of a default screen (adding an extra parameter for example) causes this screen to be unselected as default screen because LightSwitch mechanism for default screens cannot handle it.&lt;br /&gt;
Going back to the &lt;strong&gt;Customer/CustomerInfo&lt;/strong&gt; example, I have come across at least a couple of posts in threads trying to find a way to “override” the default click behavior of links in collections. In our example clicking on the link of the customer’s name (for example) will open a default screen for &lt;strong&gt;CustomerInfo&lt;/strong&gt;.&lt;br /&gt;
So, one easy solution is creating a default screen for &lt;strong&gt;CustomerInfo&lt;/strong&gt; where upon load you will open the &lt;strong&gt;Customers &lt;/strong&gt;default screen passing the id of the customer and close the current one. But how do you handle allowing only one instance of a details screen per object? Or all other issues that might come come up? (Imagine you have more than one view entities for the &lt;strong&gt;Customer &lt;/strong&gt;entity).&lt;br /&gt;
Anyway, this is my approach at solving this issue, that works fine for me in a big project whose development runs for almost a year now (and by the way is the reason for not posting very often –understatement of the year- here lately):&lt;br /&gt;
Reintroducing the &lt;strong&gt;ShowDefaultScreen&lt;/strong&gt; method of the &lt;strong&gt;Application&lt;/strong&gt; in the &lt;strong&gt;Client &lt;/strong&gt;project along with an interface defined and implemented by all screens that need to be involved.&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;This is the interface definition:&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;csharpcode&quot;&gt;&lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;interface&lt;/span&gt; IDefaultScreen : IScreenObject
{
    &lt;span class=&quot;kwrd&quot;&gt;bool&lt;/span&gt; Shows(IEntityObject instance);
    IEntityObject Object { get; }
}&lt;/pre&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;style type=&quot;text/css&quot;&gt;.csharpcode, .csharpcode pre&lt;br /&gt;{&lt;br /&gt;	font-size: small;&lt;br /&gt;	color: black;&lt;br /&gt;	font-family: consolas, &quot;Courier New&quot;, courier, monospace;&lt;br /&gt;	background-color: #ffffff;&lt;br /&gt;	/*white-space: pre;*/&lt;br /&gt;}&lt;br /&gt;.csharpcode pre { margin: 0em; }&lt;br /&gt;.csharpcode .rem { color: #008000; }&lt;br /&gt;.csharpcode .kwrd { color: #0000ff; }&lt;br /&gt;.csharpcode .str { color: #006080; }&lt;br /&gt;.csharpcode .op { color: #0000c0; }&lt;br /&gt;.csharpcode .preproc { color: #cc6633; }&lt;br /&gt;.csharpcode .asp { background-color: #ffff00; }&lt;br /&gt;.csharpcode .html { color: #800000; }&lt;br /&gt;.csharpcode .attr { color: #ff0000; }&lt;br /&gt;.csharpcode .alt &lt;br /&gt;{&lt;br /&gt;	background-color: #f4f4f4;&lt;br /&gt;	width: 100%;&lt;br /&gt;	margin: 0em;&lt;br /&gt;}&lt;br /&gt;.csharpcode .lnum { color: #606060; }&lt;br /&gt;&lt;/style&gt;

&lt;br /&gt;
&lt;ul&gt;&lt;br /&gt;
&lt;li&gt;This is the code in Application.cs:&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;csharpcode&quot;&gt;&lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;void&lt;/span&gt; ShowDefaultScreen(IEntityObject instance) {
      &lt;span class=&quot;kwrd&quot;&gt;this&lt;/span&gt;.ShowOrFocusDefaultScreen(instance);
}

&lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;void&lt;/span&gt; ShowOrFocusDefaultScreen(IEntityObject entity) {
  &lt;span class=&quot;kwrd&quot;&gt;foreach&lt;/span&gt; (IActiveScreen activeScreen &lt;span class=&quot;kwrd&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;this&lt;/span&gt;.ActiveScreens) {
    &lt;span class=&quot;kwrd&quot;&gt;if&lt;/span&gt; ((activeScreen.Screen &lt;span class=&quot;kwrd&quot;&gt;is&lt;/span&gt; IDefaultScreen) &amp;amp;&amp;amp;
        (activeScreen.Screen &lt;span class=&quot;kwrd&quot;&gt;as&lt;/span&gt; IDefaultScreen).Shows(entity)) {
          activeScreen.Activate();
          &lt;span class=&quot;kwrd&quot;&gt;return&lt;/span&gt;;
        }
      }
  entity.Details.Dispatcher.BeginInvoke(() =&amp;gt; {
    &lt;span class=&quot;kwrd&quot;&gt;if&lt;/span&gt; (!HandleEntityDefaultScreen(entity))
      &lt;span class=&quot;kwrd&quot;&gt;base&lt;/span&gt;.ShowDefaultScreen(entity);
  });
}

&lt;span class=&quot;kwrd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;bool&lt;/span&gt; HandleEntityDefaultScreen(IEntityObject entity) {
  &lt;span class=&quot;kwrd&quot;&gt;switch&lt;/span&gt; (entity.GetType().Name) {
    &lt;span class=&quot;kwrd&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;str&quot;&gt;&quot;CustomerInfo&quot;&lt;/span&gt;: {
        &lt;span class=&quot;kwrd&quot;&gt;this&lt;/span&gt;.ShowEditCustomer((entity &lt;span class=&quot;kwrd&quot;&gt;as&lt;/span&gt; CustomerInfo).Id);
        &lt;span class=&quot;kwrd&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;true&lt;/span&gt;;
      }
      .
      .
      .
  }
  &lt;span class=&quot;kwrd&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;false&lt;/span&gt;;
}
&lt;/pre&gt;
&lt;pre class=&quot;csharpcode&quot;&gt;&lt;span style=&quot;font-family: Arial;&quot;&gt;In the code displayed above the implementation in &lt;strong&gt;HandleEntityDefaultScreen &lt;/strong&gt;code is just to demonstrate the concept. The ellipsis below the first &lt;strong&gt;case&lt;/strong&gt; implies you can write whatever is required by your application.&lt;/span&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;ul&gt;&lt;br /&gt;
&lt;li&gt;&lt;pre class=&quot;csharpcode&quot;&gt;&lt;span style=&quot;font-family: Arial;&quot;&gt;And finally this is the code from the &lt;strong&gt;Customer &lt;/strong&gt;details screen that implements &lt;strong&gt;IDefaultScreen:&lt;/strong&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;csharpcode&quot;&gt;&lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;partial&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;class&lt;/span&gt; EditCustomer : IDefaultScreen
{
   .
   .
   .
  &lt;span class=&quot;preproc&quot;&gt;#region&lt;/span&gt; IDefaultScreen Members
  &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;bool&lt;/span&gt; Shows(IEntityObject instance) {
    &lt;span class=&quot;kwrd&quot;&gt;return&lt;/span&gt; (instance &lt;span class=&quot;kwrd&quot;&gt;is&lt;/span&gt; CustomerInfo) &amp;amp;&amp;amp;
           (instance &lt;span class=&quot;kwrd&quot;&gt;as&lt;/span&gt; CustomerInfo).Id.Equals(&lt;span class=&quot;kwrd&quot;&gt;this&lt;/span&gt;.CustomerProperty.Id);
  }

  &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; IEntityObject Object {
    get { &lt;span class=&quot;kwrd&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;this&lt;/span&gt;.CustomerProperty; }
  }
  &lt;span class=&quot;preproc&quot;&gt;#endregion&lt;/span&gt;
}&lt;/pre&gt;
&lt;br /&gt;
The careful reader will notice that the &lt;strong&gt;IEntityObject Object { get; } &lt;/strong&gt;property exposed by &lt;strong&gt;IDefaultScreen&lt;/strong&gt; is not used in the sample code. I ported the code exactly as I use it in my projects (apart from the changes made to demonstrate the &lt;strong&gt;Customer/CustomerInfo&lt;/strong&gt; paradigm) where this property is used for a different purpose. You can either remove it or find a good use for it &lt;img alt=&quot;Winking smile&quot; class=&quot;wlEmoticon wlEmoticon-winkingsmile&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhRlmk0ekzKg4eb4esnhbgP0EPOb4vB5R54SlWHvGUvX6VnBzk7n4LsFjt5XfS425d3swcQEyItVJjYTOAHckcJf94OWgbDtJfcl6qq2G3jbHhDy1-OssamkGO8JVW6JEH_yZE7dGTonG93//?imgmax=800&quot; style=&quot;border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none;&quot; /&gt;.&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://kostaschristodoulou.blogspot.com/feeds/8583017614353388692/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kostaschristodoulou.blogspot.com/2012/11/de-fault-screens.html#comment-form' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1977783208088103440/posts/default/8583017614353388692'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1977783208088103440/posts/default/8583017614353388692'/><link rel='alternate' type='text/html' href='http://kostaschristodoulou.blogspot.com/2012/11/de-fault-screens.html' title='De-fault Screens'/><author><name>Kostas Christodoulou</name><uri>http://www.blogger.com/profile/07577025344678922877</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='29' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg-vpaqKzo9_w1Z5f97Dh74HcFctRHYFDWYNgNp35Gy2_84EvKNIZl57RAMvxB8JlsIic3iTrZ2Pv7D7leYIc_15MOo4Uh8hJI-4OF2Mv1G9-GYOCsOO_k7uxsAzbLxRNQ/s220/Me2.jpg'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhRlmk0ekzKg4eb4esnhbgP0EPOb4vB5R54SlWHvGUvX6VnBzk7n4LsFjt5XfS425d3swcQEyItVJjYTOAHckcJf94OWgbDtJfcl6qq2G3jbHhDy1-OssamkGO8JVW6JEH_yZE7dGTonG93/s72-c/?imgmax=800" height="72" width="72"/><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1977783208088103440.post-6072580914240530204</id><published>2012-07-13T13:48:00.001+03:00</published><updated>2012-07-13T15:29:36.576+03:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Advanced"/><category scheme="http://www.blogger.com/atom/ns#" term="Design Patterns"/><category scheme="http://www.blogger.com/atom/ns#" term="Extension Methods"/><title type='text'>Just Visiting or (not so) Simple Extension Methods (part 4)</title><content type='html'>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
One of my favorite design patterns since the age of c++ is the &lt;strong&gt;Visitor Pattern&lt;/strong&gt;. I will not explain here what the &lt;a href=&quot;http://www.oodesign.com/visitor-pattern.html&quot; target=&quot;_blank&quot;&gt;visitor pattern&lt;/a&gt; is. But, if you know how to use the design pattern this is a post worth reading.&lt;br /&gt;
One may ask what the visitor pattern has to do with LightSwitch. Well, it doesn’t! I mean not exclusively. But the code below provides a full visitor pattern implementation background that can also be used in LS. Also, a part of the implementation is ideal for LS, since one of the challenges I had to face, when trying to widely use the visitor pattern, was make it work for “sealed” classes, classes that were not written by me and could not easily fit to my –reflection based- visitor pattern implementation. To solve this the best thing I could think of was “wrapping”. And working with LS, most of the classes (apart from the ones that belong to the domain/datasource) are actually “sealed” in the way described above.(I have to note here that this reflection-based implementation is a revision of an implementation I found (if I recall correct) in CodeProject).&lt;br /&gt;
First the two basic interfaces that have to be defined:&lt;br /&gt;
The &lt;strong&gt;IVisitor&lt;/strong&gt; interface that has to be implemented by the “worker” (or helper to follow the VB-oriented naming of the LS Team &lt;img alt=&quot;Sarcastic smile&quot; class=&quot;wlEmoticon wlEmoticon-sarcasticsmile&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhRw7wBJZf6cH9UNoCM8jBpxwaaPbNzON0SQgeDqsQILIWP7s_GFN7TDTREUHdborXpbP7Vx_VbYOP15PCMo8-fKiAnZrPLl5_KePv_1CLJgOHTMV3K-bHVyi0gpa2U5XrMqs5QFXpGV1Ck//?imgmax=800&quot; style=&quot;border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none;&quot; /&gt;) class.&lt;br /&gt;
&lt;pre class=&quot;csharpcode&quot;&gt;&lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;interface&lt;/span&gt; IVisitor
{
  &lt;span class=&quot;kwrd&quot;&gt;void&lt;/span&gt; VisitDefault(IVisitorTarget source);
}&lt;/pre&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;style type=&quot;text/css&quot;&gt;
.csharpcode, .csharpcode pre&lt;br /&gt;{&lt;br /&gt; font-size: small;&lt;br /&gt; color: black;&lt;br /&gt; font-family: consolas, &quot;Courier New&quot;, courier, monospace;&lt;br /&gt; background-color: #ffffff;&lt;br /&gt; /*white-space: pre;*/&lt;br /&gt;}&lt;br /&gt;.csharpcode pre { margin: 0em; }&lt;br /&gt;.csharpcode .rem { color: #008000; }&lt;br /&gt;.csharpcode .kwrd { color: #0000ff; }&lt;br /&gt;.csharpcode .str { color: #006080; }&lt;br /&gt;.csharpcode .op { color: #0000c0; }&lt;br /&gt;.csharpcode .preproc { color: #cc6633; }&lt;br /&gt;.csharpcode .asp { background-color: #ffff00; }&lt;br /&gt;.csharpcode .html { color: #800000; }&lt;br /&gt;.csharpcode .attr { color: #ff0000; }&lt;br /&gt;.csharpcode .alt &lt;br /&gt;{&lt;br /&gt; background-color: #f4f4f4;&lt;br /&gt; width: 100%;&lt;br /&gt; margin: 0em;&lt;br /&gt;}&lt;br /&gt;.csharpcode .lnum { color: #606060; }&lt;br /&gt;
&lt;/style&gt;&lt;br /&gt;
Then the &lt;strong&gt;IVisitorTarget &lt;/strong&gt;interface (implied above) that has to be implemented by the class to be “consumed/visited” by the &lt;strong&gt;Visitor.&lt;/strong&gt;&lt;br /&gt;
&lt;pre class=&quot;csharpcode&quot;&gt;&lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;interface&lt;/span&gt; IVisitorTarget
{
  &lt;span class=&quot;kwrd&quot;&gt;void&lt;/span&gt; Accept(IVisitor visitor);
}&lt;/pre&gt;
&lt;br /&gt;
&lt;style type=&quot;text/css&quot;&gt;
.csharpcode, .csharpcode pre&lt;br /&gt;{&lt;br /&gt; font-size: small;&lt;br /&gt; color: black;&lt;br /&gt; font-family: consolas, &quot;Courier New&quot;, courier, monospace;&lt;br /&gt; background-color: #ffffff;&lt;br /&gt; /*white-space: pre;*/&lt;br /&gt;}&lt;br /&gt;.csharpcode pre { margin: 0em; }&lt;br /&gt;.csharpcode .rem { color: #008000; }&lt;br /&gt;.csharpcode .kwrd { color: #0000ff; }&lt;br /&gt;.csharpcode .str { color: #006080; }&lt;br /&gt;.csharpcode .op { color: #0000c0; }&lt;br /&gt;.csharpcode .preproc { color: #cc6633; }&lt;br /&gt;.csharpcode .asp { background-color: #ffff00; }&lt;br /&gt;.csharpcode .html { color: #800000; }&lt;br /&gt;.csharpcode .attr { color: #ff0000; }&lt;br /&gt;.csharpcode .alt &lt;br /&gt;{&lt;br /&gt; background-color: #f4f4f4;&lt;br /&gt; width: 100%;&lt;br /&gt; margin: 0em;&lt;br /&gt;}&lt;br /&gt;.csharpcode .lnum { color: #606060; }&lt;br /&gt;
&lt;/style&gt;&lt;br /&gt;
&lt;strong&gt;&lt;/strong&gt;&lt;br /&gt;
Ok, I know, nothing much up to now. But as I say “The longest journey starts with the first step”…(yes I am an old Chinese philosopher)&lt;br /&gt;
&lt;br /&gt;
To have your visitor pattern in place you need an extension method to do the trick:&lt;br /&gt;
&lt;pre class=&quot;csharpcode&quot;&gt;&lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;bool&lt;/span&gt; ConcreteVisit(&lt;span class=&quot;kwrd&quot;&gt;this&lt;/span&gt; IVisitorTarget target, IVisitor visitor) {
  Type[] types = &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; Type[] { target.GetType() };
  MethodInfo mi = visitor.GetType().GetMethod(&lt;span class=&quot;str&quot;&gt;&quot;Visit&quot;&lt;/span&gt;, types);

  &lt;span class=&quot;kwrd&quot;&gt;if&lt;/span&gt; (mi == &lt;span class=&quot;kwrd&quot;&gt;null&lt;/span&gt;)
    &lt;span class=&quot;kwrd&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;false&lt;/span&gt;;

  mi.Invoke(visitor, &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;object&lt;/span&gt;[] { target });
  &lt;span class=&quot;kwrd&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;true&lt;/span&gt;;
}&lt;/pre&gt;
&lt;br /&gt;
Now that these pieces are in place let’s say we have a class called DisplayNameBuilder that implements the &lt;strong&gt;IVisitor&lt;/strong&gt; interface. Also, let’s say we have a &lt;strong&gt;Customer &lt;/strong&gt;entity in our datasource and we want it to implement the &lt;strong&gt;IVisitorTarget &lt;/strong&gt;interface. All we have to do is open &lt;strong&gt;Customer&lt;/strong&gt; entity in the designer, click Write Code and change the class declaration to:&lt;br /&gt;
&lt;pre class=&quot;csharpcode&quot;&gt;&lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;partial&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;class&lt;/span&gt; Model : IVisitorTarget&lt;/pre&gt;
&lt;br /&gt;
&lt;style type=&quot;text/css&quot;&gt;
.csharpcode, .csharpcode pre&lt;br /&gt;{&lt;br /&gt; font-size: small;&lt;br /&gt; color: black;&lt;br /&gt; font-family: consolas, &quot;Courier New&quot;, courier, monospace;&lt;br /&gt; background-color: #ffffff;&lt;br /&gt; /*white-space: pre;*/&lt;br /&gt;}&lt;br /&gt;.csharpcode pre { margin: 0em; }&lt;br /&gt;.csharpcode .rem { color: #008000; }&lt;br /&gt;.csharpcode .kwrd { color: #0000ff; }&lt;br /&gt;.csharpcode .str { color: #006080; }&lt;br /&gt;.csharpcode .op { color: #0000c0; }&lt;br /&gt;.csharpcode .preproc { color: #cc6633; }&lt;br /&gt;.csharpcode .asp { background-color: #ffff00; }&lt;br /&gt;.csharpcode .html { color: #800000; }&lt;br /&gt;.csharpcode .attr { color: #ff0000; }&lt;br /&gt;.csharpcode .alt &lt;br /&gt;{&lt;br /&gt; background-color: #f4f4f4;&lt;br /&gt; width: 100%;&lt;br /&gt; margin: 0em;&lt;br /&gt;}&lt;br /&gt;.csharpcode .lnum { color: #606060; }&lt;br /&gt;
&lt;/style&gt;&lt;br /&gt;
&lt;br /&gt;
make sure you are &lt;strong&gt;using&lt;/strong&gt; the namespace of the class where the above extension method is implemented and implement the &lt;strong&gt;IVisitorTarget&lt;/strong&gt; interface like this:&lt;br /&gt;
&lt;pre class=&quot;csharpcode&quot;&gt;&lt;span class=&quot;preproc&quot;&gt;#region&lt;/span&gt; IVisitorTarget Members
&lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;void&lt;/span&gt; Accept(IVisitor visitor) {
  &lt;span class=&quot;kwrd&quot;&gt;if&lt;/span&gt; (!&lt;span class=&quot;kwrd&quot;&gt;this&lt;/span&gt;.ConcreteVisit(visitor))
    visitor.VisitDefault(&lt;span class=&quot;kwrd&quot;&gt;this&lt;/span&gt;);
}
&lt;span class=&quot;preproc&quot;&gt;#endregion&lt;/span&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;style type=&quot;text/css&quot;&gt;
.csharpcode, .csharpcode pre&lt;br /&gt;{&lt;br /&gt; font-size: small;&lt;br /&gt; color: black;&lt;br /&gt; font-family: consolas, &quot;Courier New&quot;, courier, monospace;&lt;br /&gt; background-color: #ffffff;&lt;br /&gt; /*white-space: pre;*/&lt;br /&gt;}&lt;br /&gt;.csharpcode pre { margin: 0em; }&lt;br /&gt;.csharpcode .rem { color: #008000; }&lt;br /&gt;.csharpcode .kwrd { color: #0000ff; }&lt;br /&gt;.csharpcode .str { color: #006080; }&lt;br /&gt;.csharpcode .op { color: #0000c0; }&lt;br /&gt;.csharpcode .preproc { color: #cc6633; }&lt;br /&gt;.csharpcode .asp { background-color: #ffff00; }&lt;br /&gt;.csharpcode .html { color: #800000; }&lt;br /&gt;.csharpcode .attr { color: #ff0000; }&lt;br /&gt;.csharpcode .alt &lt;br /&gt;{&lt;br /&gt; background-color: #f4f4f4;&lt;br /&gt; width: 100%;&lt;br /&gt; margin: 0em;&lt;br /&gt;}&lt;br /&gt;.csharpcode .lnum { color: #606060; }&lt;br /&gt;
&lt;/style&gt;&lt;br /&gt;
&lt;br /&gt;
Also this is a sample implementation of the DisplayNameBuilder class:&lt;br /&gt;
&lt;pre class=&quot;csharpcode&quot;&gt;&lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;class&lt;/span&gt; DisplayNameBuilder : IVisitor
{
  &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt; Name{
    get;
    &lt;span class=&quot;kwrd&quot;&gt;private&lt;/span&gt; set;
  }

  &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;void&lt;/span&gt; VisitDefault(IVisitorTarget visitorTarget){
    Name = visitorTarget.ToString();
  }

  &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;void&lt;/span&gt; Visit(Customer visitorTarget){
    Name = &lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt;.Format(&lt;span class=&quot;str&quot;&gt;&quot;{0}{1}{2}&quot;&lt;/span&gt;, visitorTarget.FirstName, &lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt;.IsNullOrWhiteSpace(visitorTarget.FirstName) ? &lt;span class=&quot;str&quot;&gt;&quot;&quot;&lt;/span&gt;, &lt;span class=&quot;str&quot;&gt;&quot; &quot;&lt;/span&gt;, visitorTarget.LastName);
  }
}&lt;/pre&gt;
&lt;br /&gt;
&lt;style type=&quot;text/css&quot;&gt;
.csharpcode, .csharpcode pre&lt;br /&gt;{&lt;br /&gt; font-size: small;&lt;br /&gt; color: black;&lt;br /&gt; font-family: consolas, &quot;Courier New&quot;, courier, monospace;&lt;br /&gt; background-color: #ffffff;&lt;br /&gt; /*white-space: pre;*/&lt;br /&gt;}&lt;br /&gt;.csharpcode pre { margin: 0em; }&lt;br /&gt;.csharpcode .rem { color: #008000; }&lt;br /&gt;.csharpcode .kwrd { color: #0000ff; }&lt;br /&gt;.csharpcode .str { color: #006080; }&lt;br /&gt;.csharpcode .op { color: #0000c0; }&lt;br /&gt;.csharpcode .preproc { color: #cc6633; }&lt;br /&gt;.csharpcode .asp { background-color: #ffff00; }&lt;br /&gt;.csharpcode .html { color: #800000; }&lt;br /&gt;.csharpcode .attr { color: #ff0000; }&lt;br /&gt;.csharpcode .alt &lt;br /&gt;{&lt;br /&gt; background-color: #f4f4f4;&lt;br /&gt; width: 100%;&lt;br /&gt; margin: 0em;&lt;br /&gt;}&lt;br /&gt;.csharpcode .lnum { color: #606060; }&lt;br /&gt;
&lt;/style&gt;&lt;br /&gt;
&lt;br /&gt;
In the above code please note these:&lt;br /&gt;
&lt;br /&gt;
&lt;ol&gt;&lt;br /&gt;
&lt;li&gt;The code was written in Live Writer as it’s demo code, so maybe it does not compile as is.&lt;img alt=&quot;Embarrassed smile&quot; class=&quot;wlEmoticon wlEmoticon-embarrassedsmile&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiqKMOZtDQugfiSO2cePdiPxa3KnICuidwkNRKF-OD4ZkbLtPSewLqxcnXRMZds58x3uEq5jQJBEkpEusEm-XV-bJmCLvmpndJ7eyfFXtU3hygCaQ-42v6pcWNmI6-0w8SJW31rpyE1mfa-//?imgmax=800&quot; style=&quot;border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none;&quot; /&gt;&lt;/li&gt;
&lt;br /&gt;
&lt;li&gt;The customer is implied to have a nullable &lt;strong&gt;FirstName&lt;/strong&gt; property and a not nullable &lt;strong&gt;LastName &lt;/strong&gt;(which I believe it’s a fair assumption and I agree with me).&lt;/li&gt;
&lt;br /&gt;
&lt;li&gt;The implementation, as obvious, is domain aware as it knows what &lt;strong&gt;Customer &lt;/strong&gt;is. This implies that the ideal place for this class to live is in the &lt;strong&gt;Common &lt;/strong&gt;project.&lt;/li&gt;
&lt;/ol&gt;
&lt;br /&gt;
Now lets say you create a calculated string field in Customer entity called hmmmmm… &lt;strong&gt;DisplayName&lt;/strong&gt; (surprised? It’s a gift I have regarding giving original names&lt;img alt=&quot;Smile with tongue out&quot; class=&quot;wlEmoticon wlEmoticon-smilewithtongueout&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgodRFU5aQeG6gx3BDxCcUmxORk0T-IyKio6ttshm72_hVTVrADVsDokUsph-a41D87IR1GQISqPhs2EOH9nZMFe1kArIceC0F9HkVZL1gYXszqvlZsWyrh0DgGEmJQcT3h2Zzgt2X-nuuE//?imgmax=800&quot; style=&quot;border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none;&quot; /&gt;). This would be the code that would implement the calculation of &lt;strong&gt;DisplayName&lt;/strong&gt; property:&lt;br /&gt;
&lt;pre class=&quot;csharpcode&quot;&gt;&lt;span class=&quot;kwrd&quot;&gt;partial&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;void&lt;/span&gt; DisplayName_Compute(&lt;span class=&quot;kwrd&quot;&gt;ref&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt; result) {
  DisplayNameBuilder builder = &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; DisplayNameBuilder();
  &lt;span class=&quot;kwrd&quot;&gt;this&lt;/span&gt;.Accept(builder);
  result = builder.Name;
}&lt;/pre&gt;
&lt;br /&gt;
I HAVE to stress one more time that the code is for demonstration purposes only. It’s not just you, it IS too much fuss for nothing.&lt;br /&gt;
&lt;br /&gt;
Ok, now it should be easier to understand the problem of using the visitor pattern with pre-defined classes. You cannot add the &lt;strong&gt;IVisitorTarget &lt;/strong&gt;behavior to most of the classes, automatically generated by LS.&lt;br /&gt;
&lt;br /&gt;
So this is the solution to the problem.&lt;br /&gt;
&lt;pre class=&quot;csharpcode&quot;&gt;&lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;class&lt;/span&gt; IVisitorWrapper&amp;lt;TObjectType&amp;gt; : IVisitorTarget
{
  &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; TObjectType Content {
    get;
    set;
  }

  &lt;span class=&quot;preproc&quot;&gt;#region&lt;/span&gt; IVisitorTarget Members
  &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;void&lt;/span&gt; Accept(IVisitor visitor) {
    &lt;span class=&quot;kwrd&quot;&gt;if&lt;/span&gt; (!this.ConcreteVisit(&lt;span class=&quot;kwrd&quot;&gt;this&lt;/span&gt;, visitor))
      &lt;span class=&quot;kwrd&quot;&gt;if&lt;/span&gt; (!this.VisitWrapper(&lt;span class=&quot;kwrd&quot;&gt;this&lt;/span&gt;, visitor))
        visitor.VisitDefault(&lt;span class=&quot;kwrd&quot;&gt;this&lt;/span&gt;);
  }
  &lt;span class=&quot;preproc&quot;&gt;#endregion&lt;/span&gt;
}&lt;/pre&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;style type=&quot;text/css&quot;&gt;
.csharpcode, .csharpcode pre&lt;br /&gt;{&lt;br /&gt; font-size: small;&lt;br /&gt; color: black;&lt;br /&gt; font-family: consolas, &quot;Courier New&quot;, courier, monospace;&lt;br /&gt; background-color: #ffffff;&lt;br /&gt; /*white-space: pre;*/&lt;br /&gt;}&lt;br /&gt;.csharpcode pre { margin: 0em; }&lt;br /&gt;.csharpcode .rem { color: #008000; }&lt;br /&gt;.csharpcode .kwrd { color: #0000ff; }&lt;br /&gt;.csharpcode .str { color: #006080; }&lt;br /&gt;.csharpcode .op { color: #0000c0; }&lt;br /&gt;.csharpcode .preproc { color: #cc6633; }&lt;br /&gt;.csharpcode .asp { background-color: #ffff00; }&lt;br /&gt;.csharpcode .html { color: #800000; }&lt;br /&gt;.csharpcode .attr { color: #ff0000; }&lt;br /&gt;.csharpcode .alt &lt;br /&gt;{&lt;br /&gt; background-color: #f4f4f4;&lt;br /&gt; width: 100%;&lt;br /&gt; margin: 0em;&lt;br /&gt;}&lt;br /&gt;.csharpcode .lnum { color: #606060; }&lt;br /&gt;
&lt;/style&gt;&lt;br /&gt;
&lt;br /&gt;
This is a wrapper class (one could say it is an &lt;strong&gt;IVisitorTarget&lt;/strong&gt; decorator). If you are still with me and you keep on reading the code you have already noticed that &lt;strong&gt;VisitWrapper&lt;/strong&gt; extension method is not yet defined, so this is it:&lt;br /&gt;
&lt;pre class=&quot;csharpcode&quot;&gt;&lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;bool&lt;/span&gt; VisitWrapper&amp;lt;TObjectType&amp;gt;(&lt;span class=&quot;kwrd&quot;&gt;this&lt;/span&gt; IVisitorWrapper&amp;lt;TObjectType&amp;gt; wrapper, IVisitor visitor) {
  Type[] types = &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; Type[] { &lt;span class=&quot;kwrd&quot;&gt;typeof&lt;/span&gt;(TObjectType) };
  MethodInfo mi = visitor.GetType().GetMethod(&lt;span class=&quot;str&quot;&gt;&quot;Visit&quot;&lt;/span&gt;, types);

  &lt;span class=&quot;kwrd&quot;&gt;if&lt;/span&gt; (mi == &lt;span class=&quot;kwrd&quot;&gt;null&lt;/span&gt;)
    &lt;span class=&quot;kwrd&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;false&lt;/span&gt;;

  mi.Invoke(visitor, &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;object&lt;/span&gt;[] { wrapper.Content });
  &lt;span class=&quot;kwrd&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;true&lt;/span&gt;;
}&lt;/pre&gt;
&lt;br /&gt;
&lt;style type=&quot;text/css&quot;&gt;
.csharpcode, .csharpcode pre&lt;br /&gt;{&lt;br /&gt; font-size: small;&lt;br /&gt; color: black;&lt;br /&gt; font-family: consolas, &quot;Courier New&quot;, courier, monospace;&lt;br /&gt; background-color: #ffffff;&lt;br /&gt; /*white-space: pre;*/&lt;br /&gt;}&lt;br /&gt;.csharpcode pre { margin: 0em; }&lt;br /&gt;.csharpcode .rem { color: #008000; }&lt;br /&gt;.csharpcode .kwrd { color: #0000ff; }&lt;br /&gt;.csharpcode .str { color: #006080; }&lt;br /&gt;.csharpcode .op { color: #0000c0; }&lt;br /&gt;.csharpcode .preproc { color: #cc6633; }&lt;br /&gt;.csharpcode .asp { background-color: #ffff00; }&lt;br /&gt;.csharpcode .html { color: #800000; }&lt;br /&gt;.csharpcode .attr { color: #ff0000; }&lt;br /&gt;.csharpcode .alt &lt;br /&gt;{&lt;br /&gt; background-color: #f4f4f4;&lt;br /&gt; width: 100%;&lt;br /&gt; margin: 0em;&lt;br /&gt;}&lt;br /&gt;.csharpcode .lnum { color: #606060; }&lt;br /&gt;
&lt;/style&gt;&lt;br /&gt;
&lt;br /&gt;
Now you can wrap any type of object and use the &lt;strong&gt;DisplayNameBuilder &lt;/strong&gt;to build it’s display name&lt;strong&gt;. &lt;/strong&gt;Also (as –I hope- you guessed) you have to implement the respective &lt;strong&gt;Visit&lt;/strong&gt; method in &lt;strong&gt;DisplayNameBuilder&lt;/strong&gt; in order not go get the type name back as &lt;strong&gt;Name&lt;/strong&gt;.&lt;br /&gt;
&lt;br /&gt;
Well, as Porky says: That’s all Folks &lt;img alt=&quot;Smile&quot; class=&quot;wlEmoticon wlEmoticon-smile&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhI6rJq5uhNHS9aDwpqQMW7XVJp-lL4EZLz2X0-oBOsD1T8cCqv6P4mY7Rk2PgWGWbr515abUDD3XmQ0cZEv-7DC10aDVe1pyhWAm2Rx14107swhbt3dXbGPMX4-hKDR5fip0hVmQZ8UJa1//?imgmax=800&quot; style=&quot;border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none;&quot; /&gt;. I hope that except for exhausting it was also interesting.&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kostaschristodoulou.blogspot.com/feeds/6072580914240530204/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kostaschristodoulou.blogspot.com/2012/07/just-visiting-or-not-so-simple.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1977783208088103440/posts/default/6072580914240530204'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1977783208088103440/posts/default/6072580914240530204'/><link rel='alternate' type='text/html' href='http://kostaschristodoulou.blogspot.com/2012/07/just-visiting-or-not-so-simple.html' title='Just Visiting or (not so) Simple Extension Methods (part 4)'/><author><name>Kostas Christodoulou</name><uri>http://www.blogger.com/profile/07577025344678922877</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='29' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg-vpaqKzo9_w1Z5f97Dh74HcFctRHYFDWYNgNp35Gy2_84EvKNIZl57RAMvxB8JlsIic3iTrZ2Pv7D7leYIc_15MOo4Uh8hJI-4OF2Mv1G9-GYOCsOO_k7uxsAzbLxRNQ/s220/Me2.jpg'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhRw7wBJZf6cH9UNoCM8jBpxwaaPbNzON0SQgeDqsQILIWP7s_GFN7TDTREUHdborXpbP7Vx_VbYOP15PCMo8-fKiAnZrPLl5_KePv_1CLJgOHTMV3K-bHVyi0gpa2U5XrMqs5QFXpGV1Ck/s72-c/?imgmax=800" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1977783208088103440.post-6923953160494271710</id><published>2012-07-11T16:44:00.001+03:00</published><updated>2012-07-11T17:34:34.205+03:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Advanced"/><category scheme="http://www.blogger.com/atom/ns#" term="Extension Methods"/><category scheme="http://www.blogger.com/atom/ns#" term="Under the Hood"/><title type='text'>Application Logo (tailored on customer demand)</title><content type='html'>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
This is the most recent comment in the &lt;a href=&quot;http://kostaschristodoulou.blogspot.gr/2012/02/application-logo-sample.html&quot; target=&quot;_blank&quot;&gt;Application Logo Sample&lt;/a&gt; post:&lt;br /&gt;
&lt;em&gt;“Hi Kostas,&lt;br /&gt;I wanted to find out if there is a way of opening an active screen as soon as I click on the logo. I have tried but my attempt was in vain. If it is possible, could you please help me out?&lt;br /&gt;Thanks,&lt;br /&gt;Darryn”&lt;/em&gt;&lt;br /&gt;
My first reaction was to ask for details (typical way of buying time &lt;img alt=&quot;Smile&quot; class=&quot;wlEmoticon wlEmoticon-smile&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjVIty8hhpL7prfkyjleb9p2IHBZZCK7xMYcASpkLLPORJMMSpOJi4ZsY6nL9ol1fD0bL4y_W5V7AFSMLTDm8KkxdR4Kk1A_-E2cFvTBe2q2Ik19-6icCjOjJZ-D64BKaDDnzCoICxRAKcA//?imgmax=800&quot; style=&quot;border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none;&quot; /&gt;). But then I though I could do the changes required and post a new article. So simply put, this is the answer I propose to Darryn:&lt;br /&gt;
&lt;pre class=&quot;csharpcode&quot;&gt;&lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;void&lt;/span&gt; AddLogo(&lt;span class=&quot;kwrd&quot;&gt;this&lt;/span&gt; Microsoft.LightSwitch.Client.IClientApplication application, System.Windows.HorizontalAlignment alignment, &lt;b&gt;&lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt; screenName&lt;/b&gt;) {
  Microsoft.LightSwitch.Threading.Dispatchers.Main.BeginInvoke(() =&amp;gt; { LogoPlacement.AddLogo(&lt;b&gt;application&lt;/b&gt;, System.Windows.Application.Current.RootVisual, alignment, &lt;strong&gt;screenName&lt;/strong&gt;); });
}


&lt;span class=&quot;kwrd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;class&lt;/span&gt; LogoPlacement
{
  &lt;span class=&quot;kwrd&quot;&gt;internal&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;void&lt;/span&gt; AddLogo(&lt;strong&gt;Microsoft.LightSwitch.Client.IClientApplication application&lt;/strong&gt;, UIElement element, System.Windows.HorizontalAlignment alignment, &lt;strong&gt;&lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt; screenName&lt;/strong&gt;) {
    &lt;span class=&quot;kwrd&quot;&gt;if&lt;/span&gt; (rcb != &lt;span class=&quot;kwrd&quot;&gt;null&lt;/span&gt;) &lt;span class=&quot;kwrd&quot;&gt;return&lt;/span&gt;;

    &lt;span class=&quot;kwrd&quot;&gt;for&lt;/span&gt; (&lt;span class=&quot;kwrd&quot;&gt;int&lt;/span&gt; i = 0; i &amp;lt; System.Windows.Media.VisualTreeHelper.GetChildrenCount(element); i++) {
      &lt;span class=&quot;kwrd&quot;&gt;if&lt;/span&gt; (rcb != &lt;span class=&quot;kwrd&quot;&gt;null&lt;/span&gt;)
        &lt;span class=&quot;kwrd&quot;&gt;return&lt;/span&gt;;
      UIElement child = (UIElement)System.Windows.Media.VisualTreeHelper.GetChild(element, i);
      AddLogo(application, child, alignment, screenName);
    }
    &lt;span class=&quot;kwrd&quot;&gt;if&lt;/span&gt; (element &lt;span class=&quot;kwrd&quot;&gt;is&lt;/span&gt; Microsoft.LightSwitch.Runtime.Shell.Implementation.Standard.RibbonCommandBar) {
      rcb = element &lt;span class=&quot;kwrd&quot;&gt;as&lt;/span&gt; Microsoft.LightSwitch.Runtime.Shell.Implementation.Standard.RibbonCommandBar;
      Image myImage = &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; Image() {
        Stretch = System.Windows.Media.Stretch.Uniform,
        Margin = &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; Thickness(2, 8, 14, 8),
        HorizontalAlignment = alignment,
        Cursor = System.Windows.Input.Cursors.Hand
      };
      myImage.SetValue(ComponentViewModelService.ViewModelNameProperty, &lt;span class=&quot;str&quot;&gt;&quot;Default.LogoViewModel&quot;&lt;/span&gt;);
      myImage.SetBinding(Image.SourceProperty, &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; System.Windows.Data.Binding { Path = &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; PropertyPath(&lt;span class=&quot;str&quot;&gt;&quot;Logo&quot;&lt;/span&gt;) });
      &lt;strong&gt;&lt;span class=&quot;kwrd&quot;&gt;if&lt;/span&gt; (!&lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt;.IsNullOrWhiteSpace(screenName))&lt;/strong&gt;
        myImage.MouseLeftButtonUp += (s, e) =&amp;gt; { &lt;strong&gt;application.Details.Dispatcher.BeginInvoke(() =&amp;gt; application.Details.Methods[&lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt;.Format(&lt;span class=&quot;str&quot;&gt;&quot;Show{0}&quot;&lt;/span&gt;, screenName)].CreateInvocation().Execute()); };&lt;/strong&gt;
      myImage.SizeChanged += (s, e) =&amp;gt; {
        &lt;span class=&quot;kwrd&quot;&gt;double&lt;/span&gt; left = (s &lt;span class=&quot;kwrd&quot;&gt;as&lt;/span&gt; Image).HorizontalAlignment == HorizontalAlignment.Left ? e.NewSize.Width + 10.0 : 0.0;
        &lt;span class=&quot;kwrd&quot;&gt;double&lt;/span&gt; right = (s &lt;span class=&quot;kwrd&quot;&gt;as&lt;/span&gt; Image).HorizontalAlignment == HorizontalAlignment.Right ? e.NewSize.Width + 10.0 : 0.0;
        rcb.Padding = &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; Thickness(left, 0, right, 0);
      };
      ((Grid)rcb.Parent).Children.Add(myImage);
    }
  }&lt;/pre&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;style type=&quot;text/css&quot;&gt;
.csharpcode, .csharpcode pre&lt;br /&gt;{&lt;br /&gt; font-size: small;&lt;br /&gt; color: black;&lt;br /&gt; font-family: consolas, &quot;Courier New&quot;, courier, monospace;&lt;br /&gt; background-color: #ffffff;&lt;br /&gt; /*white-space: pre;*/&lt;br /&gt;}&lt;br /&gt;.csharpcode pre { margin: 0em; }&lt;br /&gt;.csharpcode .rem { color: #008000; }&lt;br /&gt;.csharpcode .kwrd { color: #0000ff; }&lt;br /&gt;.csharpcode .str { color: #006080; }&lt;br /&gt;.csharpcode .op { color: #0000c0; }&lt;br /&gt;.csharpcode .preproc { color: #cc6633; }&lt;br /&gt;.csharpcode .asp { background-color: #ffff00; }&lt;br /&gt;.csharpcode .html { color: #800000; }&lt;br /&gt;.csharpcode .attr { color: #ff0000; }&lt;br /&gt;.csharpcode .alt &lt;br /&gt;{&lt;br /&gt; background-color: #f4f4f4;&lt;br /&gt; width: 100%;&lt;br /&gt; margin: 0em;&lt;br /&gt;}&lt;br /&gt;.csharpcode .lnum { color: #606060; }&lt;br /&gt;
&lt;/style&gt;&lt;br /&gt;
&lt;br /&gt;
With bold I have marked the additions/changes I had to make to accommodate Darryn’s request.&lt;br /&gt;
I hope Darryn is happy &lt;img alt=&quot;Smile with tongue out&quot; class=&quot;wlEmoticon wlEmoticon-smilewithtongueout&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjPjSlXyVHy6_sIG3AlZ0icXkjPg11bty-gy4-I9jKoRCCV6XhTu5OHgxnoigJZPKPGeqRd04RdEXlcv5-KbYy2IoIYENiUl-1pRUa7naD5Abt-fvXtnHj0qBl6J4ZWH3li8tj2U09TAMrP//?imgmax=800&quot; style=&quot;border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none;&quot; /&gt;.&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kostaschristodoulou.blogspot.com/feeds/6923953160494271710/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kostaschristodoulou.blogspot.com/2012/07/application-logo-tailored-on-customer.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1977783208088103440/posts/default/6923953160494271710'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1977783208088103440/posts/default/6923953160494271710'/><link rel='alternate' type='text/html' href='http://kostaschristodoulou.blogspot.com/2012/07/application-logo-tailored-on-customer.html' title='Application Logo (tailored on customer demand)'/><author><name>Kostas Christodoulou</name><uri>http://www.blogger.com/profile/07577025344678922877</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='29' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg-vpaqKzo9_w1Z5f97Dh74HcFctRHYFDWYNgNp35Gy2_84EvKNIZl57RAMvxB8JlsIic3iTrZ2Pv7D7leYIc_15MOo4Uh8hJI-4OF2Mv1G9-GYOCsOO_k7uxsAzbLxRNQ/s220/Me2.jpg'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjVIty8hhpL7prfkyjleb9p2IHBZZCK7xMYcASpkLLPORJMMSpOJi4ZsY6nL9ol1fD0bL4y_W5V7AFSMLTDm8KkxdR4Kk1A_-E2cFvTBe2q2Ik19-6icCjOjJZ-D64BKaDDnzCoICxRAKcA/s72-c/?imgmax=800" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1977783208088103440.post-6625820355744299495</id><published>2012-07-11T14:43:00.001+03:00</published><updated>2012-07-11T14:45:01.459+03:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Business Logic"/><category scheme="http://www.blogger.com/atom/ns#" term="Extension Methods"/><category scheme="http://www.blogger.com/atom/ns#" term="Intermediate"/><title type='text'>Simple Extension Methods (part 3)</title><content type='html'>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
One very common task when one is implementing the business logic in Common project is writing custom &lt;em&gt;&lt;strong&gt;PropertyName_Changed&lt;/strong&gt; &lt;/em&gt;partial methods.&lt;br /&gt;
This “approach” has an undesired “side-effect” when the property is an entity property (as compared to screen properties). The property changes many times during the lifetime of the object. While loading, while deleting etc., whereas what we want to implement is handle the “actual” property changes caused either by the user or by some other piece of business logic.&lt;br /&gt;
I found myself debugging code that shouldn’t be executing (according to my logic, obviously LS had another opinion) before ending up writing a small extension method to use in all &lt;strong&gt;&lt;em&gt;PropertyName_Changed&lt;/em&gt;&lt;/strong&gt; partial methods. I don’t claim this method will help you avoid ALL unwanted business logic code execution, but covers most of the cases. I would be glad to read any comments improving it in a generic way.&lt;br /&gt;
Here is the code of the extension method:&lt;br /&gt;
&lt;pre class=&quot;csharpcode&quot;&gt;&lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;bool&lt;/span&gt; IgnorePropertyChange(&lt;span class=&quot;kwrd&quot;&gt;this&lt;/span&gt; IEntityObject entity) {
  &lt;span class=&quot;kwrd&quot;&gt;return&lt;/span&gt; entity.Details.EntityState == EntityState.Unchanged ||
         entity.Details.EntityState == EntityState.Discarded ||
         entity.Details.EntityState == EntityState.Deleted;
}&lt;/pre&gt;
&lt;br /&gt;
&lt;br /&gt;&lt;style type=&quot;text/css&quot;&gt;
.csharpcode, .csharpcode pre&lt;br /&gt;{&lt;br /&gt; font-size: small;&lt;br /&gt; color: black;&lt;br /&gt; font-family: consolas, &quot;Courier New&quot;, courier, monospace;&lt;br /&gt; background-color: #ffffff;&lt;br /&gt; /*white-space: pre;*/&lt;br /&gt;}&lt;br /&gt;.csharpcode pre { margin: 0em; }&lt;br /&gt;.csharpcode .rem { color: #008000; }&lt;br /&gt;.csharpcode .kwrd { color: #0000ff; }&lt;br /&gt;.csharpcode .str { color: #006080; }&lt;br /&gt;.csharpcode .op { color: #0000c0; }&lt;br /&gt;.csharpcode .preproc { color: #cc6633; }&lt;br /&gt;.csharpcode .asp { background-color: #ffff00; }&lt;br /&gt;.csharpcode .html { color: #800000; }&lt;br /&gt;.csharpcode .attr { color: #ff0000; }&lt;br /&gt;.csharpcode .alt &lt;br /&gt;{&lt;br /&gt; background-color: #f4f4f4;&lt;br /&gt; width: 100%;&lt;br /&gt; margin: 0em;&lt;br /&gt;}&lt;br /&gt;.csharpcode .lnum { color: #606060; }&lt;br /&gt;
&lt;/style&gt;&lt;br /&gt;&lt;br /&gt;And here how all my property changed partial implementations for entity properties look like&lt;br /&gt;
&lt;pre class=&quot;csharpcode&quot;&gt;&lt;span class=&quot;kwrd&quot;&gt;partial&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;void&lt;/span&gt; ScheduledEndDate_Changed() {
  &lt;span class=&quot;kwrd&quot;&gt;if&lt;/span&gt; (&lt;span class=&quot;kwrd&quot;&gt;this&lt;/span&gt;.IgnorePropertyChange())
    &lt;span class=&quot;kwrd&quot;&gt;return&lt;/span&gt;;
  .
  .
  .
}&lt;/pre&gt;
&lt;br /&gt;
&lt;style type=&quot;text/css&quot;&gt;
.csharpcode, .csharpcode pre&lt;br /&gt;{&lt;br /&gt; font-size: small;&lt;br /&gt; color: black;&lt;br /&gt; font-family: consolas, &quot;Courier New&quot;, courier, monospace;&lt;br /&gt; background-color: #ffffff;&lt;br /&gt; /*white-space: pre;*/&lt;br /&gt;}&lt;br /&gt;.csharpcode pre { margin: 0em; }&lt;br /&gt;.csharpcode .rem { color: #008000; }&lt;br /&gt;.csharpcode .kwrd { color: #0000ff; }&lt;br /&gt;.csharpcode .str { color: #006080; }&lt;br /&gt;.csharpcode .op { color: #0000c0; }&lt;br /&gt;.csharpcode .preproc { color: #cc6633; }&lt;br /&gt;.csharpcode .asp { background-color: #ffff00; }&lt;br /&gt;.csharpcode .html { color: #800000; }&lt;br /&gt;.csharpcode .attr { color: #ff0000; }&lt;br /&gt;.csharpcode .alt &lt;br /&gt;{&lt;br /&gt; background-color: #f4f4f4;&lt;br /&gt; width: 100%;&lt;br /&gt; margin: 0em;&lt;br /&gt;}&lt;br /&gt;.csharpcode .lnum { color: #606060; }&lt;br /&gt;
&lt;/style&gt;&lt;br /&gt;
&lt;br /&gt;
This looks (and is) simple but the concept, alone, of “unwanted” code execution is important and should be taken good care of. If not using this extension method any other way one may like &lt;img alt=&quot;Winking smile&quot; class=&quot;wlEmoticon wlEmoticon-winkingsmile&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjnsdRmGWRrJIPJDpz-68sQyZANDAbs_S1uVjfhHbx4QLUh2PvnSurhbQGaz4CaymEFz2J4y2QTINkDiawOJ1YE0_tb7NK5xtukCfsNk8IwUV4le71wkjEqbUgSwNrlwkEEq7vNdRqEldIK//?imgmax=800&quot; style=&quot;border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none;&quot; /&gt;.&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kostaschristodoulou.blogspot.com/feeds/6625820355744299495/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kostaschristodoulou.blogspot.com/2012/07/simple-extension-methods-part-3.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1977783208088103440/posts/default/6625820355744299495'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1977783208088103440/posts/default/6625820355744299495'/><link rel='alternate' type='text/html' href='http://kostaschristodoulou.blogspot.com/2012/07/simple-extension-methods-part-3.html' title='Simple Extension Methods (part 3)'/><author><name>Kostas Christodoulou</name><uri>http://www.blogger.com/profile/07577025344678922877</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='29' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg-vpaqKzo9_w1Z5f97Dh74HcFctRHYFDWYNgNp35Gy2_84EvKNIZl57RAMvxB8JlsIic3iTrZ2Pv7D7leYIc_15MOo4Uh8hJI-4OF2Mv1G9-GYOCsOO_k7uxsAzbLxRNQ/s220/Me2.jpg'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjnsdRmGWRrJIPJDpz-68sQyZANDAbs_S1uVjfhHbx4QLUh2PvnSurhbQGaz4CaymEFz2J4y2QTINkDiawOJ1YE0_tb7NK5xtukCfsNk8IwUV4le71wkjEqbUgSwNrlwkEEq7vNdRqEldIK/s72-c/?imgmax=800" height="72" width="72"/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1977783208088103440.post-9142898613279507027</id><published>2012-06-29T13:50:00.001+03:00</published><updated>2012-09-03T12:18:00.212+03:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Extension Methods"/><category scheme="http://www.blogger.com/atom/ns#" term="Intermediate"/><category scheme="http://www.blogger.com/atom/ns#" term="Under the Hood"/><title type='text'>Simple Extension Methods (part 2)</title><content type='html'>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
In the previous post I presented an extension method used mostly for overriding the edit and delete commands of a collection. One may ask “why do I want to do this?”. Apart from any other requirements/business logic dependent reason one might want to implement, for me there is one simple yet important reason: I don’t like at all (to be kind) the default add/edit modal windows when adding or editing an entry. It’s not a coincidence that the &lt;a href=&quot;http://code.msdn.microsoft.com/Managing-Custom-AddEdit-5772ab80&quot; target=&quot;_blank&quot;&gt;FIRST&lt;/a&gt; sample I wrote for LightSwitch and posted in the Samples of msdn.com/lightswitch was a set of extension methods and contracts to easily replace standard modal windows with custom ones. &lt;br /&gt;
Most of the times when I have an editable grid screen, selecting Add or Edit I DON’T want the modal window to pop-up, I just want to edit in the grid. Or in list and details screen I want to edit the new or existing entry in the detail part of the screen.&lt;br /&gt;
This is the main reason I most of the times override the default Add/Edit command behavior. And for this reason I created and use the next two extension methods:&lt;br /&gt;
&lt;pre class=&quot;csharpcode&quot;&gt;public static void AddFocus&amp;lt;T&amp;gt;(this VisualCollection&amp;lt;T&amp;gt; collection, string focusControl, bool inCollection)
      where T : class, IEntityObject {
      collection.AddNew();
      collection.EditFocus(focusControl, inCollection);
    }

    public static void EditFocus&amp;lt;T&amp;gt;(this VisualCollection&amp;lt;T&amp;gt; collection, string focusControl, bool inCollection)
      where T : class, IEntityObject {
      if (focusControl != null) {
        try {
          IContentItemProxy control = null;
          if (inCollection)
            control = collection.Screen.FindControlInCollection(focusControl, collection.SelectedItem);
          else
            control = collection.Screen.FindControl(focusControl);
          Microsoft.LightSwitch.Threading.Dispatchers.Main.BeginInvoke(() =&amp;gt; {
            try {
              control.Focus();
            }
            catch {
              collection.EditSelected();
            }
          });
        }
        catch {
          if (collection.HasSelection())
            collection.EditSelected();
        }
      }
    }&lt;/pre&gt;
&lt;br /&gt;
&lt;style type=&quot;text/css&quot;&gt;
.csharpcode, .csharpcode pre&lt;br /&gt;{&lt;br /&gt; font-size: small;&lt;br /&gt; color: black;&lt;br /&gt; font-family: consolas, &quot;Courier New&quot;, courier, monospace;&lt;br /&gt; background-color: #ffffff;&lt;br /&gt; /*white-space: pre;*/&lt;br /&gt;}&lt;br /&gt;.csharpcode pre { margin: 0em; }&lt;br /&gt;.csharpcode .rem { color: #008000; }&lt;br /&gt;.csharpcode .kwrd { color: #0000ff; }&lt;br /&gt;.csharpcode .str { color: #006080; }&lt;br /&gt;.csharpcode .op { color: #0000c0; }&lt;br /&gt;.csharpcode .preproc { color: #cc6633; }&lt;br /&gt;.csharpcode .asp { background-color: #ffff00; }&lt;br /&gt;.csharpcode .html { color: #800000; }&lt;br /&gt;.csharpcode .attr { color: #ff0000; }&lt;br /&gt;.csharpcode .alt &lt;br /&gt;{&lt;br /&gt; background-color: #f4f4f4;&lt;br /&gt; width: 100%;&lt;br /&gt; margin: 0em;&lt;br /&gt;}&lt;br /&gt;.csharpcode .lnum { color: #606060; }&lt;br /&gt;
&lt;/style&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;style type=&quot;text/css&quot;&gt;
.csharpcode, .csharpcode pre&lt;br /&gt;{&lt;br /&gt; font-size: small;&lt;br /&gt; color: black;&lt;br /&gt; font-family: consolas, &quot;Courier New&quot;, courier, monospace;&lt;br /&gt; background-color: #ffffff;&lt;br /&gt; /*white-space: pre;*/&lt;br /&gt;}&lt;br /&gt;.csharpcode pre { margin: 0em; }&lt;br /&gt;.csharpcode .rem { color: #008000; }&lt;br /&gt;.csharpcode .kwrd { color: #0000ff; }&lt;br /&gt;.csharpcode .str { color: #006080; }&lt;br /&gt;.csharpcode .op { color: #0000c0; }&lt;br /&gt;.csharpcode .preproc { color: #cc6633; }&lt;br /&gt;.csharpcode .asp { background-color: #ffff00; }&lt;br /&gt;.csharpcode .html { color: #800000; }&lt;br /&gt;.csharpcode .attr { color: #ff0000; }&lt;br /&gt;.csharpcode .alt &lt;br /&gt;{&lt;br /&gt; background-color: #f4f4f4;&lt;br /&gt; width: 100%;&lt;br /&gt; margin: 0em;&lt;br /&gt;}&lt;br /&gt;.csharpcode .lnum { color: #606060; }&lt;br /&gt;
&lt;/style&gt;&lt;br /&gt;
&lt;br /&gt;
So what you have to do in your MyCollectionAddAndEditNew_Execute partial method is write something like:&lt;br /&gt;
&lt;pre class=&quot;csharpcode&quot;&gt;MyCollection.AddFocus(&lt;span class=&quot;str&quot;&gt;&quot;TheNameOfTheControlYouWantToFocus&quot;, true&lt;/span&gt;);&lt;/pre&gt;
&lt;br /&gt;
&lt;style type=&quot;text/css&quot;&gt;
.csharpcode, .csharpcode pre&lt;br /&gt;{&lt;br /&gt; font-size: small;&lt;br /&gt; color: black;&lt;br /&gt; font-family: consolas, &quot;Courier New&quot;, courier, monospace;&lt;br /&gt; background-color: #ffffff;&lt;br /&gt; /*white-space: pre;*/&lt;br /&gt;}&lt;br /&gt;.csharpcode pre { margin: 0em; }&lt;br /&gt;.csharpcode .rem { color: #008000; }&lt;br /&gt;.csharpcode .kwrd { color: #0000ff; }&lt;br /&gt;.csharpcode .str { color: #006080; }&lt;br /&gt;.csharpcode .op { color: #0000c0; }&lt;br /&gt;.csharpcode .preproc { color: #cc6633; }&lt;br /&gt;.csharpcode .asp { background-color: #ffff00; }&lt;br /&gt;.csharpcode .html { color: #800000; }&lt;br /&gt;.csharpcode .attr { color: #ff0000; }&lt;br /&gt;.csharpcode .alt &lt;br /&gt;{&lt;br /&gt; background-color: #f4f4f4;&lt;br /&gt; width: 100%;&lt;br /&gt; margin: 0em;&lt;br /&gt;}&lt;br /&gt;.csharpcode .lnum { color: #606060; }&lt;br /&gt;
&lt;/style&gt;&lt;br /&gt;
&lt;br /&gt;
or for MyCollectionEdit_Execute partial method:&lt;br /&gt;
&lt;pre class=&quot;csharpcode&quot;&gt;MyCollection.EditFocus(&lt;span class=&quot;str&quot;&gt;&quot;TheNameOfTheControlYouWantToFocus&quot;, true&lt;/span&gt;);&lt;/pre&gt;
&lt;br /&gt;
if you have a list detail screen the same code applies but with inCollection = false.&lt;br /&gt;
&lt;br /&gt;
One could implement one method for collections and one for details. Also notice &lt;strong&gt;where&lt;/strong&gt; constraints applied to &lt;strong&gt;T&lt;/strong&gt; generic parameter. The &lt;strong&gt;class &lt;/strong&gt;constraint is required for declaring &lt;strong&gt;VisualCollection&amp;lt;T&amp;gt;&lt;/strong&gt;. The &lt;strong&gt;IEntityObject &lt;/strong&gt;constraint is required so that we avoid the arbitrary casting of &lt;strong&gt;collection.SelectedItem &lt;/strong&gt;to &lt;strong&gt;IEntityObject&lt;/strong&gt; so as to be passed to &lt;strong&gt;FindControlInCollection&lt;/strong&gt; as second parameter.&lt;br /&gt;
&lt;br /&gt;
Notice that in the extension methods I don’t check if the control name exists. I just use try catch. On error (if the control name is not valid) I choose to fall-back to the default behavior. You can change this without any intellectual rights being violated &lt;img alt=&quot;Smile&quot; class=&quot;wlEmoticon wlEmoticon-smile&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgHGHpnK82E8YygWtBjy2pveOi8jUbytYlGjZegS9BFPrw89XyQR7TwI6LO-WuNsWDNcq2b-2L3vG5HTuQkYryrjtA7QmnLjxld3mtgMZR_cDeOL5TodM64kYPQgCQTakGLVSFKP3JuScRn//?imgmax=800&quot; style=&quot;border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none;&quot; /&gt;.&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://kostaschristodoulou.blogspot.com/feeds/9142898613279507027/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kostaschristodoulou.blogspot.com/2012/06/simple-extension-methods-part-2.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1977783208088103440/posts/default/9142898613279507027'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1977783208088103440/posts/default/9142898613279507027'/><link rel='alternate' type='text/html' href='http://kostaschristodoulou.blogspot.com/2012/06/simple-extension-methods-part-2.html' title='Simple Extension Methods (part 2)'/><author><name>Kostas Christodoulou</name><uri>http://www.blogger.com/profile/07577025344678922877</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='29' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg-vpaqKzo9_w1Z5f97Dh74HcFctRHYFDWYNgNp35Gy2_84EvKNIZl57RAMvxB8JlsIic3iTrZ2Pv7D7leYIc_15MOo4Uh8hJI-4OF2Mv1G9-GYOCsOO_k7uxsAzbLxRNQ/s220/Me2.jpg'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgHGHpnK82E8YygWtBjy2pveOi8jUbytYlGjZegS9BFPrw89XyQR7TwI6LO-WuNsWDNcq2b-2L3vG5HTuQkYryrjtA7QmnLjxld3mtgMZR_cDeOL5TodM64kYPQgCQTakGLVSFKP3JuScRn/s72-c/?imgmax=800" height="72" width="72"/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1977783208088103440.post-4659922202053568015</id><published>2012-06-26T09:44:00.001+03:00</published><updated>2012-07-11T14:46:15.087+03:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Extension Methods"/><category scheme="http://www.blogger.com/atom/ns#" term="Intermediate"/><category scheme="http://www.blogger.com/atom/ns#" term="Under the Hood"/><title type='text'>Simple Extension Methods (part 1)</title><content type='html'>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
As soon as I started writing LightSwitch applications I noticed that many times I was repeating the same code over and over for trivial tasks. So after all this time I have collected a number of extension methods that I widely use in my apps.&lt;br /&gt;
For me reusing code is a &lt;strong&gt;must&lt;/strong&gt; and although the implementation of LS (IMHO) does not provide for this out of the box the underlying framework is ideal for writing extension classes and methods that are a major step towards code reusability. If you have downloaded any of my samples from msdn or have seen my &lt;a href=&quot;http://kostaschristodoulou.blogspot.gr/2012/01/application-logo.html&quot; target=&quot;_blank&quot;&gt;Application Logo&lt;/a&gt; post, you already suspect I am an “extension method fanatic”.&lt;br /&gt;
So I will present a small series (I don’t know how small) of posts with extension methods from my Base.LightSwitch.Client library.&lt;br /&gt;
The first method is one of the first (if not the first one) extension methods I wrote. As soon as you want to override the code for default commands like Edit and Delete for a collection (let’s name it MyCollection) you have to write something like that:&lt;br /&gt;
&lt;pre class=&quot;csharpcode&quot;&gt;&lt;span class=&quot;kwrd&quot;&gt;partial&lt;/span&gt;  &lt;span class=&quot;kwrd&quot;&gt;void&lt;/span&gt; MyCollectionDelete_CanExecute(&lt;span class=&quot;kwrd&quot;&gt;ref&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;bool&lt;/span&gt; result){
  &lt;span class=&quot;kwrd&quot;&gt;if&lt;/span&gt; (&lt;span class=&quot;kwrd&quot;&gt;this&lt;/span&gt;.MyCollection &lt;span class=&quot;kwrd&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;null&lt;/span&gt; || &lt;span class=&quot;kwrd&quot;&gt;this&lt;/span&gt;.MyCollection.SelectedItem == &lt;span class=&quot;kwrd&quot;&gt;null&lt;/span&gt;)
    result = &lt;span class=&quot;kwrd&quot;&gt;false&lt;/span&gt;;
  &lt;span class=&quot;kwrd&quot;&gt;else&lt;/span&gt;
    result = &lt;span class=&quot;kwrd&quot;&gt;true&lt;/span&gt;;
}&lt;/pre&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Arial;&quot;&gt;This is the minimum code (it can be written more elegantly I know but this is the concept) you need to write. I don’t take into account the permissions issue.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
A similar chunk of code has to be written for Edit.&lt;br /&gt;
&lt;br /&gt;
Isn’t the code listed below easier to read:&lt;br /&gt;
&lt;pre class=&quot;csharpcode&quot;&gt;&lt;span class=&quot;kwrd&quot;&gt;partial&lt;/span&gt;  &lt;span class=&quot;kwrd&quot;&gt;void&lt;/span&gt; MyCollectionDelete_CanExecute(&lt;span class=&quot;kwrd&quot;&gt;ref&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;bool&lt;/span&gt; result){
  result = &lt;span class=&quot;kwrd&quot;&gt;this&lt;/span&gt;.HasSelection(&lt;span class=&quot;str&quot;&gt;&quot;MyCollection&quot;&lt;/span&gt;);
}&lt;/pre&gt;
&lt;pre class=&quot;csharpcode&quot;&gt;&lt;span style=&quot;font-family: Arial;&quot;&gt;It’s not only easier to read but is less error prone than the original. Plus you can inject any security logic in this &lt;strong&gt;HasSelection&lt;/strong&gt; method.&lt;/span&gt;&lt;/pre&gt;
&lt;pre class=&quot;csharpcode&quot;&gt;&lt;span style=&quot;font-family: Arial;&quot;&gt;And this is the code:&lt;/span&gt;&lt;/pre&gt;
&lt;pre class=&quot;csharpcode&quot;&gt;&lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;bool&lt;/span&gt; HasSelection(&lt;span class=&quot;kwrd&quot;&gt;this&lt;/span&gt; IScreenObject screen, &lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt; collectionName) {
  &lt;span class=&quot;kwrd&quot;&gt;if&lt;/span&gt; (!screen.Details.Properties.Contains(collectionName))
    &lt;span class=&quot;kwrd&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;false&lt;/span&gt;;
  IVisualCollection collection =
    screen.Details.Properties[collectionName].Value &lt;span class=&quot;kwrd&quot;&gt;as&lt;/span&gt; IVisualCollection;
  &lt;span class=&quot;kwrd&quot;&gt;return&lt;/span&gt; collection != &lt;span class=&quot;kwrd&quot;&gt;null&lt;/span&gt; &amp;amp;&amp;amp;
         collection.SelectedItem != &lt;span class=&quot;kwrd&quot;&gt;null &lt;span style=&quot;color: black;&quot;&gt;&amp;amp;&amp;amp;

         (collection.SelectedItem as IEntityObject).Details.EntityState != EntityState.Deleted&lt;/span&gt;&lt;/span&gt;;
}&lt;/pre&gt;
&lt;pre class=&quot;csharpcode&quot;&gt;&lt;span style=&quot;font-family: Arial;&quot;&gt;For the ones that dislike using string property names I can suggest this version :&lt;/span&gt;&lt;/pre&gt;
&lt;pre class=&quot;csharpcode&quot;&gt;&lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;bool&lt;/span&gt; HasSelection&amp;lt;T&amp;gt;(&lt;span class=&quot;kwrd&quot;&gt;this&lt;/span&gt; VisualCollection&amp;lt;T&amp;gt; collection) &lt;span class=&quot;kwrd&quot;&gt;where&lt;/span&gt; T : &lt;span class=&quot;kwrd&quot;&gt;class&lt;/span&gt;, IEntityObject {
  &lt;span class=&quot;kwrd&quot;&gt;return&lt;/span&gt; collection != &lt;span class=&quot;kwrd&quot;&gt;null&lt;/span&gt; &amp;amp;&amp;amp;
         collection.SelectedItem != nul &amp;amp;&amp;amp;
         collection.SelectedItem.Details.EntityState != EntityState.Deleted;
}&lt;/pre&gt;
&lt;br /&gt;
&lt;style type=&quot;text/css&quot;&gt;
.csharpcode, .csharpcode pre&lt;br /&gt;{&lt;br /&gt; font-size: small;&lt;br /&gt; color: black;&lt;br /&gt; font-family: consolas, &quot;Courier New&quot;, courier, monospace;&lt;br /&gt; background-color: #ffffff;&lt;br /&gt; /*white-space: pre;*/&lt;br /&gt;}&lt;br /&gt;.csharpcode pre { margin: 0em; }&lt;br /&gt;.csharpcode .rem { color: #008000; }&lt;br /&gt;.csharpcode .kwrd { color: #0000ff; }&lt;br /&gt;.csharpcode .str { color: #006080; }&lt;br /&gt;.csharpcode .op { color: #0000c0; }&lt;br /&gt;.csharpcode .preproc { color: #cc6633; }&lt;br /&gt;.csharpcode .asp { background-color: #ffff00; }&lt;br /&gt;.csharpcode .html { color: #800000; }&lt;br /&gt;.csharpcode .attr { color: #ff0000; }&lt;br /&gt;.csharpcode .alt &lt;br /&gt;{&lt;br /&gt; background-color: #f4f4f4;&lt;br /&gt; width: 100%;&lt;br /&gt; margin: 0em;&lt;br /&gt;}&lt;br /&gt;.csharpcode .lnum { color: #606060; }&lt;br /&gt;
&lt;/style&gt;&lt;br /&gt;
&lt;pre class=&quot;csharpcode&quot;&gt;&lt;span style=&quot;font-family: Arial;&quot;&gt;This version is more concrete is generic and also does not have to do the (out of thin air) conversion of SelectedItem to IEntityObject. If you use this version though you have to change your partial method as you cannot extend null:&lt;/span&gt;&lt;/pre&gt;
&lt;pre class=&quot;csharpcode&quot;&gt;&lt;span class=&quot;kwrd&quot;&gt;partial&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;void&lt;/span&gt; MyCollectionDelete_CanExecute(&lt;span class=&quot;kwrd&quot;&gt;ref&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;bool&lt;/span&gt; result){
  result = MyCollection!= null &amp;amp;&amp;amp; MyCollection.HasSelection();
}&lt;/pre&gt;
&lt;pre class=&quot;csharpcode&quot;&gt;&lt;span style=&quot;font-family: Arial;&quot;&gt;The choice is yours…&lt;img alt=&quot;Smile&quot; class=&quot;wlEmoticon wlEmoticon-smile&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiFwqpjRIC7Xoay2SNxYPbIKTuVQBUT4VlY1LuxB0x5zbx5GFFUxaKXrY4KJLsU1s4Qb01-IzSZiYSDHfQJSNf4lV20rbOBvRntPwsCA3hEeU9aa_hdgADThWkoLQ-1uajvS6tF8YZUO_An//?imgmax=800&quot; style=&quot;border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none;&quot; /&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kostaschristodoulou.blogspot.com/feeds/4659922202053568015/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kostaschristodoulou.blogspot.com/2012/06/simple-extension-methods-part-1.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1977783208088103440/posts/default/4659922202053568015'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1977783208088103440/posts/default/4659922202053568015'/><link rel='alternate' type='text/html' href='http://kostaschristodoulou.blogspot.com/2012/06/simple-extension-methods-part-1.html' title='Simple Extension Methods (part 1)'/><author><name>Kostas Christodoulou</name><uri>http://www.blogger.com/profile/07577025344678922877</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='29' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg-vpaqKzo9_w1Z5f97Dh74HcFctRHYFDWYNgNp35Gy2_84EvKNIZl57RAMvxB8JlsIic3iTrZ2Pv7D7leYIc_15MOo4Uh8hJI-4OF2Mv1G9-GYOCsOO_k7uxsAzbLxRNQ/s220/Me2.jpg'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiFwqpjRIC7Xoay2SNxYPbIKTuVQBUT4VlY1LuxB0x5zbx5GFFUxaKXrY4KJLsU1s4Qb01-IzSZiYSDHfQJSNf4lV20rbOBvRntPwsCA3hEeU9aa_hdgADThWkoLQ-1uajvS6tF8YZUO_An/s72-c/?imgmax=800" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1977783208088103440.post-8616603558982941829</id><published>2012-06-22T16:49:00.001+03:00</published><updated>2012-06-22T16:58:25.473+03:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Advanced"/><category scheme="http://www.blogger.com/atom/ns#" term="Data"/><category scheme="http://www.blogger.com/atom/ns#" term="DataSources"/><category scheme="http://www.blogger.com/atom/ns#" term="RIA Services"/><title type='text'>RIAlity Issues</title><content type='html'>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
Recently I had to face a very frustrating issue regarding the integration of a RIA Service as a LightSwitch Datasource. I tried to find references for it in the web. I did. But none of them (at least the ones I managed to find) didn’t seem to match my case. So after solving my issue I thought sharing was a good idea…&lt;br /&gt;
After having implemented and tested my RIA service using a small Silverlight application I decided to add a datasource and use it. Which I did. Focusing at the part of the RIA service that caused the problem, I had a class called &lt;strong&gt;ImageAttachment&lt;/strong&gt; and 2 queries exposing it. Below you can see the initial code:&lt;br /&gt;
&lt;div class=&quot;csharpcode&quot;&gt;
&lt;pre class=&quot;alt&quot;&gt;&lt;span class=&quot;lnum&quot;&gt;   1:  &lt;/span&gt;    [Query(IsDefault = &lt;span class=&quot;kwrd&quot;&gt;true&lt;/span&gt;)]&lt;/pre&gt;
&lt;pre&gt;&lt;span class=&quot;lnum&quot;&gt;   2:  &lt;/span&gt;    &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; IQueryable&amp;lt;ImageAttachment&amp;gt; GetImageAttachments() {&lt;/pre&gt;
&lt;pre class=&quot;alt&quot;&gt;&lt;span class=&quot;lnum&quot;&gt;   3:  &lt;/span&gt;      &lt;span class=&quot;kwrd&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; List&amp;lt;ImageAttachment&amp;gt;().AsQueryable();&lt;/pre&gt;
&lt;pre&gt;&lt;span class=&quot;lnum&quot;&gt;   4:  &lt;/span&gt;    }&lt;/pre&gt;
&lt;pre class=&quot;alt&quot;&gt;&lt;span class=&quot;lnum&quot;&gt;   5:  &lt;/span&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre&gt;&lt;span class=&quot;lnum&quot;&gt;   6:  &lt;/span&gt;    &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; IQueryable&amp;lt;ImageAttachment&amp;gt; GetFolderItemImageAttachments(Guid? providerId, &lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt; folderId, &lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt; mailItemId) {&lt;/pre&gt;
&lt;pre class=&quot;alt&quot;&gt;&lt;span class=&quot;lnum&quot;&gt;   7:  &lt;/span&gt;      &lt;span class=&quot;kwrd&quot;&gt;if&lt;/span&gt; (!providerId.HasValue || folderId == &lt;span class=&quot;kwrd&quot;&gt;null&lt;/span&gt; || mailItemId == &lt;span class=&quot;kwrd&quot;&gt;null&lt;/span&gt;)&lt;/pre&gt;
&lt;pre&gt;&lt;span class=&quot;lnum&quot;&gt;   8:  &lt;/span&gt;        &lt;span class=&quot;kwrd&quot;&gt;return&lt;/span&gt; GetImageAttachments();&lt;/pre&gt;
&lt;pre class=&quot;alt&quot;&gt;&lt;span class=&quot;lnum&quot;&gt;   9:  &lt;/span&gt;      &lt;span class=&quot;kwrd&quot;&gt;return&lt;/span&gt; GetAttachments(providerId.Value, folderId, mailItemId);&lt;/pre&gt;
&lt;pre&gt;&lt;span class=&quot;lnum&quot;&gt;  10:  &lt;/span&gt;    }&lt;/pre&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;style type=&quot;text/css&quot;&gt;
.csharpcode, .csharpcode pre&lt;br /&gt;{&lt;br /&gt; font-size: small;&lt;br /&gt; color: black;&lt;br /&gt; font-family: consolas, &quot;Courier New&quot;, courier, monospace;&lt;br /&gt; background-color: #ffffff;&lt;br /&gt; /*white-space: pre;*/&lt;br /&gt;}&lt;br /&gt;.csharpcode pre { margin: 0em; }&lt;br /&gt;.csharpcode .rem { color: #008000; }&lt;br /&gt;.csharpcode .kwrd { color: #0000ff; }&lt;br /&gt;.csharpcode .str { color: #006080; }&lt;br /&gt;.csharpcode .op { color: #0000c0; }&lt;br /&gt;.csharpcode .preproc { color: #cc6633; }&lt;br /&gt;.csharpcode .asp { background-color: #ffff00; }&lt;br /&gt;.csharpcode .html { color: #800000; }&lt;br /&gt;.csharpcode .attr { color: #ff0000; }&lt;br /&gt;.csharpcode .alt &lt;br /&gt;{&lt;br /&gt; background-color: #f4f4f4;&lt;br /&gt; width: 100%;&lt;br /&gt; margin: 0em;&lt;br /&gt;}&lt;br /&gt;.csharpcode .lnum { color: #606060; }&lt;br /&gt;
&lt;/style&gt;&lt;br /&gt;
&lt;br /&gt;
Importing the RIA Service &lt;strong&gt;GetFolderItemImageAttachments&lt;/strong&gt; was properly imported as an optional query for &lt;strong&gt;ImageAttachment&lt;/strong&gt;. &lt;br /&gt;
&lt;br /&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiTikcJZdrCMU3F64ECyRUborBsNV5p8Rzb5SxXmTbSFDiyeJ70rcPuaLajdz2jEg6EO5WxiqdeNrB9JOjY2pbwuKh683RegTMFhjm3hxc4SDRYXzTG31D6XskzTXbhz1VWq70EYiupP-wN/s1600-h/image%25255B2%25255D.png&quot;&gt;&lt;img alt=&quot;image&quot; border=&quot;0&quot; height=&quot;64&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg1HpW1J8z5W_EIiDMNUeQF-Rs93tuNcp3mF0ICefdA6Vq301x6VVlnl6qM04VCjKvYqoOuETxt3MPsY0FGD7pg57tQEvZ9lk3DXX7QSkciCuMZKqJOgzFa_nL_SoaQWh8HbQ8bp_so4hCA//?imgmax=800&quot; style=&quot;background-image: none; border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: inline; margin: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;&quot; title=&quot;image&quot; width=&quot;244&quot; /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
I added an &lt;strong&gt;ImageAttachment &lt;/strong&gt;visual collection in a screen fetching results from &lt;strong&gt;GetFolderItemImageAttachments&lt;/strong&gt; query. Everything worked smoothly. But when the time came to load the visual collection (i.e. run the query) I got an exception I hadn’t come across before neither as a LS developer nor as a Silverlight one:&lt;br /&gt;
&lt;br /&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;b&gt;Load operation failed for query ‘GetFolderItemImageAttachments’.&amp;nbsp; The remote server returned an error: NotFound.&lt;/b&gt;&lt;/div&gt;
&lt;br /&gt;
The behavior was very strange. Although the query was recognized and imported from LS for some reason at runtime it looked like the method was not found. I placed a breakpoint at the method and it didn’t hit. The method was never called. Before doing this I was sure it was some bug of mine in the implementation that caused the RIA service to throw this generic exception. But no! The execution never reached the web method. It was then that I decided to “google” it. Looked like it was a RIA Services+LightSwitch(?) issue. All references where either not appropriate in my case or had no effect. Then I did what I usually do when I have problem I cannot solve: I scrolled to the part of code listed above and started to just stare at the code waiting for an answer. And I came to me! Why not make sure the query method IS a query? So what I did was just add the &lt;strong&gt;QueryAttribute&lt;/strong&gt; to my method with no parameters:&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;csharpcode&quot;&gt;
&lt;pre class=&quot;alt&quot;&gt;&lt;span class=&quot;lnum&quot;&gt;   1:  &lt;/span&gt;    [Query(IsDefault = &lt;span class=&quot;kwrd&quot;&gt;true&lt;/span&gt;)]&lt;/pre&gt;
&lt;pre&gt;&lt;span class=&quot;lnum&quot;&gt;   2:  &lt;/span&gt;    &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; IQueryable&amp;lt;ImageAttachment&amp;gt; GetImageAttachments() {&lt;/pre&gt;
&lt;pre class=&quot;alt&quot;&gt;&lt;span class=&quot;lnum&quot;&gt;   3:  &lt;/span&gt;      &lt;span class=&quot;kwrd&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; List&amp;lt;ImageAttachment&amp;gt;().AsQueryable();&lt;/pre&gt;
&lt;pre&gt;&lt;span class=&quot;lnum&quot;&gt;   4:  &lt;/span&gt;    }&lt;/pre&gt;
&lt;pre class=&quot;alt&quot;&gt;&lt;span class=&quot;lnum&quot;&gt;   5:  &lt;/span&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre&gt;&lt;span class=&quot;lnum&quot;&gt;   6:  &lt;/span&gt;    &lt;strong&gt;&lt;span style=&quot;font-size: large;&quot;&gt;[Query]&lt;/span&gt;&lt;/strong&gt;&lt;/pre&gt;
&lt;pre class=&quot;alt&quot;&gt;&lt;span class=&quot;lnum&quot;&gt;   7:  &lt;/span&gt;    &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; IQueryable&amp;lt;ImageAttachment&amp;gt; GetFolderItemImageAttachments(Guid? providerId, &lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt; folderId, &lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt; mailItemId) {&lt;/pre&gt;
&lt;pre&gt;&lt;span class=&quot;lnum&quot;&gt;   8:  &lt;/span&gt;      &lt;span class=&quot;kwrd&quot;&gt;if&lt;/span&gt; (!providerId.HasValue || folderId == &lt;span class=&quot;kwrd&quot;&gt;null&lt;/span&gt; || mailItemId == &lt;span class=&quot;kwrd&quot;&gt;null&lt;/span&gt;)&lt;/pre&gt;
&lt;pre class=&quot;alt&quot;&gt;&lt;span class=&quot;lnum&quot;&gt;   9:  &lt;/span&gt;        &lt;span class=&quot;kwrd&quot;&gt;return&lt;/span&gt; GetImageAttachments();&lt;/pre&gt;
&lt;pre&gt;&lt;span class=&quot;lnum&quot;&gt;  10:  &lt;/span&gt;      &lt;span class=&quot;kwrd&quot;&gt;return&lt;/span&gt; GetAttachments(providerId.Value, folderId, mailItemId);&lt;/pre&gt;
&lt;pre class=&quot;alt&quot;&gt;&lt;span class=&quot;lnum&quot;&gt;  11:  &lt;/span&gt;    }&lt;/pre&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;style type=&quot;text/css&quot;&gt;
.csharpcode, .csharpcode pre&lt;br /&gt;{&lt;br /&gt; font-size: small;&lt;br /&gt; color: black;&lt;br /&gt; font-family: consolas, &quot;Courier New&quot;, courier, monospace;&lt;br /&gt; background-color: #ffffff;&lt;br /&gt; /*white-space: pre;*/&lt;br /&gt;}&lt;br /&gt;.csharpcode pre { margin: 0em; }&lt;br /&gt;.csharpcode .rem { color: #008000; }&lt;br /&gt;.csharpcode .kwrd { color: #0000ff; }&lt;br /&gt;.csharpcode .str { color: #006080; }&lt;br /&gt;.csharpcode .op { color: #0000c0; }&lt;br /&gt;.csharpcode .preproc { color: #cc6633; }&lt;br /&gt;.csharpcode .asp { background-color: #ffff00; }&lt;br /&gt;.csharpcode .html { color: #800000; }&lt;br /&gt;.csharpcode .attr { color: #ff0000; }&lt;br /&gt;.csharpcode .alt &lt;br /&gt;{&lt;br /&gt; background-color: #f4f4f4;&lt;br /&gt; width: 100%;&lt;br /&gt; margin: 0em;&lt;br /&gt;}&lt;br /&gt;.csharpcode .lnum { color: #606060; }&lt;br /&gt;
&lt;/style&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
I thought that if it didn’t solve the problem I surely would not cause a new one. It IS a query method after all. Why let LS infer it? And it worked.&lt;br /&gt;
&lt;br /&gt;
I am quite sure I was lucky. I mean, the query was recognized either way. I cannot explain what exactly was the bug the &lt;strong&gt;QueryAttribute&lt;/strong&gt; fixed. To stress my point more, I have to admit that went back to the RIA Service and I removed the attribute. Still worked! Like a deadlock resolved. Maybe only LightSwitch Team can explain. Anyhow I thought of sharing in case anyone else runs into something like this.&lt;img alt=&quot;Smile&quot; class=&quot;wlEmoticon wlEmoticon-smile&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgVmkOXpC8UElK7qEdVD46R6pNAryfBpuO_4cepDEnBgHS5cvOSALZ0snK3qq0yuk_LsYr0YYaFF7zEbJBwo1XeULa6l9_HLB9sPl9AVT09tI4Be3OcHjOiDYv3y9H6r297Je0aPr-LzHQV//?imgmax=800&quot; style=&quot;border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none;&quot; /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kostaschristodoulou.blogspot.com/feeds/8616603558982941829/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kostaschristodoulou.blogspot.com/2012/06/riality-issues.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1977783208088103440/posts/default/8616603558982941829'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1977783208088103440/posts/default/8616603558982941829'/><link rel='alternate' type='text/html' href='http://kostaschristodoulou.blogspot.com/2012/06/riality-issues.html' title='RIAlity Issues'/><author><name>Kostas Christodoulou</name><uri>http://www.blogger.com/profile/07577025344678922877</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='29' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg-vpaqKzo9_w1Z5f97Dh74HcFctRHYFDWYNgNp35Gy2_84EvKNIZl57RAMvxB8JlsIic3iTrZ2Pv7D7leYIc_15MOo4Uh8hJI-4OF2Mv1G9-GYOCsOO_k7uxsAzbLxRNQ/s220/Me2.jpg'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg1HpW1J8z5W_EIiDMNUeQF-Rs93tuNcp3mF0ICefdA6Vq301x6VVlnl6qM04VCjKvYqoOuETxt3MPsY0FGD7pg57tQEvZ9lk3DXX7QSkciCuMZKqJOgzFa_nL_SoaQWh8HbQ8bp_so4hCA/s72-c/?imgmax=800" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1977783208088103440.post-3074253642956693354</id><published>2012-06-11T11:14:00.001+03:00</published><updated>2012-06-11T11:19:15.903+03:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Advanced"/><category scheme="http://www.blogger.com/atom/ns#" term="Under the Hood"/><title type='text'>You Are I.</title><content type='html'>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
Finding my application’s URI address either in deployment or development/debugging environment has been an issue I had to face in my early LightSwitch days. Although not a LightSwitch issue, but rather a Siverlight/ASP.NET one, I thought that sharing the 2 lines of code I have ended up using to discover the URI (along with the port, most important for debugging and/or &lt;a href=&quot;http://http//kostaschristodoulou.blogspot.gr/2012/06/class-extensions-version-2-fixes-and.html&quot; target=&quot;_blank&quot;&gt;standalone&lt;/a&gt; deployments) might be useful.&lt;br /&gt;
&lt;u&gt;First the client&lt;/u&gt;. The first and easy approach was extracting the URI and port from &lt;strong&gt;System.Windows.Browser.HtmlPage.Document.DocumentUri.&lt;/strong&gt; Nice! Not really. This only works for web and NOT OOB (Out of Browser) or Desktop according to LS naming, applications. System.Windows.Browser namespace is in general not available in ΟΟΒ applications.&lt;br /&gt;
The way I ended up adopting is accessing &lt;strong&gt;System.Windows.Application.Current.Host.Source.AbsoluteUri. &lt;/strong&gt;Ok, I know it’s WPF/Silverlight way (System.Windows… I mean) but my experience says that a similar approach will be available even if HTML 5 is the next (not too soon I expect) output of LS.&lt;br /&gt;
&lt;u&gt;Then the server&lt;/u&gt;. Here things are simpler and for as long as the server part of a LS application remains a Web Service the path will always be the same: &lt;strong&gt;HttpContext.Current.Request.Headers[&quot;HOST&quot;].&lt;/strong&gt;&lt;br /&gt;
That’s it! Short but juicy (I hope &lt;img alt=&quot;Smile&quot; class=&quot;wlEmoticon wlEmoticon-smile&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg4j8_lOda82gcIKU9DUj23F-lPbM6fZNehuPgNKRgTPfb2v-IAdaSM9WCrqjUGrCs_d457Vpl0ftlRLPPRTNqxE_RSQluSpXl76wPUzbsd2l6u8rxsuDLRQb-ylGaoZWZgs8JJ5EQJ5rbP//?imgmax=800&quot; style=&quot;border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none;&quot; /&gt;).&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kostaschristodoulou.blogspot.com/feeds/3074253642956693354/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kostaschristodoulou.blogspot.com/2012/06/you-are-i.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1977783208088103440/posts/default/3074253642956693354'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1977783208088103440/posts/default/3074253642956693354'/><link rel='alternate' type='text/html' href='http://kostaschristodoulou.blogspot.com/2012/06/you-are-i.html' title='You Are I.'/><author><name>Kostas Christodoulou</name><uri>http://www.blogger.com/profile/07577025344678922877</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='29' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg-vpaqKzo9_w1Z5f97Dh74HcFctRHYFDWYNgNp35Gy2_84EvKNIZl57RAMvxB8JlsIic3iTrZ2Pv7D7leYIc_15MOo4Uh8hJI-4OF2Mv1G9-GYOCsOO_k7uxsAzbLxRNQ/s220/Me2.jpg'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg4j8_lOda82gcIKU9DUj23F-lPbM6fZNehuPgNKRgTPfb2v-IAdaSM9WCrqjUGrCs_d457Vpl0ftlRLPPRTNqxE_RSQluSpXl76wPUzbsd2l6u8rxsuDLRQb-ylGaoZWZgs8JJ5EQJ5rbP/s72-c/?imgmax=800" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1977783208088103440.post-6592528838344642350</id><published>2012-06-04T16:29:00.000+03:00</published><updated>2012-06-04T16:30:04.747+03:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Advanced"/><category scheme="http://www.blogger.com/atom/ns#" term="Business Types"/><category scheme="http://www.blogger.com/atom/ns#" term="CLASS Extensions"/><category scheme="http://www.blogger.com/atom/ns#" term="Extensions"/><title type='text'>CLASS Extensions Version 2 Fixes and Promises</title><content type='html'>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
Although it&#39;s been some time since my last post, I didn&#39;t quit on CLASS Extensions. On the contrary, I have been very busy working for a corporate project that uses CLASS Extensions and in the process I have made additions and fixes in CLASS Extensions. The most important fix is about Drawing business type and control so as to support standalone deployment.&lt;br /&gt;
As you might know, when running standalone a new host is launched every time, listening to a different port. As the drawing business type uses uris to set the drawing&#39;s background, the port active when the image was selected from the server, is included in the drawing serialization string. This means that next time the application is launched (standalone or debugging) and the port is changed the drawing&#39;s background is lost. This is fixed. Although the port is still serialized along with the drawing the port is automatically replaced with the current port of the hosting process.&lt;br /&gt;
There are also other small fixes regarding functionality.
&lt;br /&gt;
Additions are to be announced officially but a (not all inclusive) sample list would include:&lt;br /&gt;
&lt;br /&gt;
&lt;ul style=&quot;text-align: left;&quot;&gt;
&lt;li&gt;an expander group control allowing you to expand/collapse regions of your screen (both horizontal and vertical).&lt;/li&gt;
&lt;li&gt;an ImageContainer group control that adds standard functionality to image editors and drawing controls to import automatically from camera and scanner (yes Del Sole&#39;s code is at the background, so before publishing I will definetly ask for permissions)&lt;/li&gt;
&lt;li&gt;a printable area group control which allows to both save a snapshot of the contained screen region and/or print it.&lt;/li&gt;
&lt;li&gt;a new color picker control that allows you to define a color by selecting it directly from an image using a sampler tool.&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;
The additional features will not be released before the end of August. The price will be adjusted accordingly. Anyone that has already purchased the original version until then, they will get the new features for free earlier than official release for beta testing.&lt;/div&gt;
&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kostaschristodoulou.blogspot.com/feeds/6592528838344642350/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kostaschristodoulou.blogspot.com/2012/06/class-extensions-version-2-fixes-and.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1977783208088103440/posts/default/6592528838344642350'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1977783208088103440/posts/default/6592528838344642350'/><link rel='alternate' type='text/html' href='http://kostaschristodoulou.blogspot.com/2012/06/class-extensions-version-2-fixes-and.html' title='CLASS Extensions Version 2 Fixes and Promises'/><author><name>Kostas Christodoulou</name><uri>http://www.blogger.com/profile/07577025344678922877</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='29' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg-vpaqKzo9_w1Z5f97Dh74HcFctRHYFDWYNgNp35Gy2_84EvKNIZl57RAMvxB8JlsIic3iTrZ2Pv7D7leYIc_15MOo4Uh8hJI-4OF2Mv1G9-GYOCsOO_k7uxsAzbLxRNQ/s220/Me2.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1977783208088103440.post-469636232175345256</id><published>2012-03-23T12:46:00.000+02:00</published><updated>2012-03-23T12:46:34.857+02:00</updated><title type='text'>CLASS Extensions Version 2 Released</title><content type='html'>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
&lt;a href=&quot;http://kostaschristodoulou.blogspot.com/p/class-extnesions-version-2.html&quot; target=&quot;_blank&quot;&gt;CLASS Extensions version 2 is now available&lt;/a&gt;. All the features demonstrated in the &lt;a href=&quot;http://kostaschristodoulou.blogspot.com/2012/03/class-extensions-version-2-demo.html&quot; target=&quot;_blank&quot;&gt;demo videos&lt;/a&gt; are included plus the AttachmentsListEx collection control that is demostrated in the sample application but was not mentioned in the previous post.&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;


Features&lt;/h3&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;li&gt;&lt;strong&gt;Color Business type and Controls&lt;/strong&gt;. This business type is used to represent color values. The underlying CLR type is &lt;strong&gt;integer&lt;/strong&gt;. After a &lt;a href=&quot;http://social.msdn.microsoft.com/Forums/en-US/lightswitch/thread/25722a43-2a9d-4e86-86e5-7f39cc803018/#d1a81e31-07dd-4fab-bdbf-f300bf023a5a&quot; target=&quot;_blank&quot;&gt;request&lt;/a&gt; the change from the previous free version is that by default the pop-up window color picker control is used both for details and collections. Boolean property called “Drop Down” was added in the Appearance category which is false by default. When checked the drop-down/expander color picker control is used instead. This property is &lt;strong&gt;ignored &lt;/strong&gt;in collections (grids/lists etc.) and pop-up is used.&lt;strong&gt;&amp;nbsp;&lt;/strong&gt;The color-picker control (as mentioned in the first version also) is contained in &lt;a href=&quot;http://silverlightcontrib.codeplex.com/&quot; target=&quot;_blank&quot;&gt;SilverlightContrib&lt;/a&gt; Codeplex project under Ms-PL. &lt;br /&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg_2ZHVFRwVIDPVtpH9pP3j-jWzJsdz4OUPGwKScj7MlC214DKpM-zIRULraXFMDOY5lIcdWdTKhKZn_CL5LnuwAm7gJ9FCSYcg7hQHVomePuaIHQbyqHJ6Crs4EO0taN29i-DMyqO69bqL/s1600-h/image%25255B2%25255D.png&quot;&gt;&lt;strong&gt;&lt;img alt=&quot;image&quot; border=&quot;0&quot; height=&quot;244&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjFBnEv41hgBTfi0kkrf-twPXgkqZZtytM7OovK2yxxEjyL1sgdpXAm8i2y9dMFYMMImFKGJqcBRc0rbYD9BmjHOStWljSiYoUcQ2_w6NA5bpZp7WBUUtwydPEdez_kuVaTY2G5u67R4Uc3//?imgmax=800&quot; style=&quot;background-image: none; border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: inline; margin: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;&quot; title=&quot;image&quot; width=&quot;150&quot; /&gt;&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Boolean Checkbox &amp;amp; Boolean Viewer controls.&lt;/strong&gt; These controls handle bool and bool? (Nullable&amp;lt;bool&amp;gt;) values. No changes made from the previous – free – version.&lt;br /&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEinhV-BmECkW5vVbjUhfhPzH4FdEMnLS3Tlz3wxX_RQ-H9WaAhCsxHmmlxsn0EySidEhOT15THwNbVMPLMEgHyJWJZXwxulcLMhhVYbOR8XrBbDyX4Hoe_MXjBvEONC-yyg3zE2Ws096oNZ/s1600-h/checked%25255B2%25255D.png&quot;&gt;&lt;img alt=&quot;checked&quot; border=&quot;0&quot; height=&quot;23&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhKm6LTR0A-vweiXhSsRwPauegvu88GE23dW9vOcSeeuiIVa9jtQ_1-BOXrGyXHnSnQ_g9C9qPW8KxSp63IPnSfWe3SEYDoAe0hb49bwT_gasRqbdApD35Ixy1kHf3U5dmjlgvxHMJpzP9I//?imgmax=800&quot; style=&quot;background-image: none; border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: inline; margin: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;&quot; title=&quot;checked&quot; width=&quot;23&quot; /&gt;&lt;/a&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi0JJxroQgMSdoHkf6vfgpzKaac6qYulTbdm0P5HdW2k_YAyyhxqYJPyx2-zngGUa1gX65gVyrAt7A6rQtpJvMmMuLA5MUjIvxaTgDQohlX9ar9w-vrD1a-G2omF5fLK5Lb0Nh8tQBga5D-/s1600-h/checked_dimmed%25255B2%25255D.png&quot;&gt;&lt;img alt=&quot;checked_dimmed&quot; border=&quot;0&quot; height=&quot;23&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgLx6J-MP6XaFO8Nlqm9wzJGbDxKvecNYhWF-SVn1OLO2purbzkxPiIhiF30vrYkEkJTcZS9Ix4X7FgwgV0hPA-WIPaW4Ib0uWlfUh145OySICOaERJPfy3K5Po6EI9WRlCFMYD123z0lOS//?imgmax=800&quot; style=&quot;background-image: none; border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: inline; margin: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;&quot; title=&quot;checked_dimmed&quot; width=&quot;23&quot; /&gt;&lt;/a&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiyklbSJnnDSU0l6xy9YvgAIn-ZFpRuwYFO1DnD8-Oc6F8RXI3DDZnefLDtZoPnbMdYrcSJ2nPRMe3omiHuGvzPhY0zxvKJDxWG76o6uuvkOXAh840iqvxFycZaZe52YqsEu01zmicUgDjx/s1600-h/unchecked%25255B2%25255D.png&quot;&gt;&lt;img alt=&quot;unchecked&quot; border=&quot;0&quot; height=&quot;23&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhNNMo4UxIYx1k-9q57K9ygkOm6zZUrzfYVWQZusJ90ROHvHgbW3YMidJ71hvZAhkrpFaIdtWyGr9uitzT3tolSG0fEvqnxx3VziunlCSbgY-rxhoHhxUxW8aAPU416f05c5lvyK-eVT5tM//?imgmax=800&quot; style=&quot;background-image: none; border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: inline; margin: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;&quot; title=&quot;unchecked&quot; width=&quot;23&quot; /&gt;&lt;/a&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhg3OHpeI6WHRBkmekkXc7_cmyGa77dPBzYkC0bOSmz2371HZX0EcwPoEto6ESX_TZQ7j9Tfk3jWig7b6EvGVcIFycdPcwNwP0uiy4y61TUcOL1t8ROJNz4AWDsHt2mkKqO5eSTvtpB3nEV/s1600-h/uncheckeddimmed%25255B2%25255D.png&quot;&gt;&lt;img alt=&quot;uncheckeddimmed&quot; border=&quot;0&quot; height=&quot;23&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhUUs7jxKGktp3CQvy3CphIUBEHBPKje8ChQ8w7irLwtFK2gxC8Z3HW3ySHQUHjcvvb1Uc846eO8y40ts5mpSOlac7ebBH-fO5Km9cN0VxAjoKWABzjrbjppvJwXxuDnnMJvPJM8yQmpou5//?imgmax=800&quot; style=&quot;background-image: none; border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: inline; margin: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;&quot; title=&quot;uncheckeddimmed&quot; width=&quot;23&quot; /&gt;&lt;/a&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjK5c6RiyFIXRV7-fT4C9EHxzOeJ5EyWpZWvJvkd2MFomMnJkLW6wjpJc5tJwvufCEp2taqbcc6NvA63yENXaxxTxm8DP7Lc2IReLvu2WHtSBgf3FfJYAqz3YtKLEYd6LI0emV_czCnaT_P/s1600-h/undefinedcheck%25255B2%25255D.png&quot;&gt;&lt;img alt=&quot;undefinedcheck&quot; border=&quot;0&quot; height=&quot;23&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg3DrBg0Cmh16rSLiFZerFpr7E45Sio-7s0XIJ9fzQvzoiWjF8ek2DLyNrlJ5-qW3NNCIXvtL0_lf9rv7SOMSHibKHt_xmUuP6tck_e3zqmsNutpG2DZHXH0R1JEI8KbL18hitKjSXp8cm3//?imgmax=800&quot; style=&quot;background-image: none; border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: inline; margin: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;&quot; title=&quot;undefinedcheck&quot; width=&quot;23&quot; /&gt;&lt;/a&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhCcVZ2IElRR0ubWYtdDMkJpgGw9GkBg5eDkBI176tftO4WzFoa3pb3-C4PeGnZpXVYqbFZ2U1vJe4JPbYxaG3p9DuNXT6ac8tG0Za3-V-vTbFZklVkaZD-Io3eiuwVklwYJbHluqj-T-I4/s1600-h/undefinedcheck_dimmed%25255B2%25255D.png&quot;&gt;&lt;img alt=&quot;undefinedcheck_dimmed&quot; border=&quot;0&quot; height=&quot;23&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEikiXu8WGjpKNeg9O6z2DCHt7YwlQOpmeikhG0KH3ei7bRgHcvighDBDWIpVAodOPup6FLSKlppPnSrN0UNTszuAv2AqeCAzg-vQe2YqnjP2H92w_DihIL88HsxmTnTqeyieZUwGlsv49JS//?imgmax=800&quot; style=&quot;background-image: none; border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;&quot; title=&quot;undefinedcheck_dimmed&quot; width=&quot;23&quot; /&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Rating Business type and Controls.&lt;/strong&gt; This business type is used to represent rating values. The underlying CLR type is &lt;strong&gt;integer&lt;/strong&gt;. The control is using the Mark Heath’s &lt;a href=&quot;http://starratingcontrol.codeplex.com/&quot; target=&quot;_blank&quot;&gt;Silverlight Star Rating Control&lt;/a&gt; from CodePlex under Ms-PL.&lt;br /&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjjLGrL1d_1dyNZVkmgRSUMC3bfP2g56rdH2QZLSV8OgQh4v8j3WzhIrMUFcvRUnk-P8Ne4XHXOhVkMN8caNuxcwIhNDNKwInXd_eZWNMDGWEzC4LXBkPA2EJyjH06igvkUqz2Wq5NCe_We/s1600-h/image%25255B37%25255D.png&quot;&gt;&lt;img alt=&quot;image&quot; border=&quot;0&quot; height=&quot;28&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEguu7pD76Sa-yn59tmEQIbjh9ZPEzYIeWsPFlS5OfeZQ3Wl3caHIahYalWDMnAZ5SkayR8Yp-r7TCD3iltBfXb0efGU633CVO4PmH44h4VbpMu9xLaHsNHXNval571MZ1nq3YsIT_wI1QU1//?imgmax=800&quot; style=&quot;background-image: none; border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: inline; margin: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;&quot; title=&quot;image&quot; width=&quot;121&quot; /&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Percentage Business type and Controls. &lt;/strong&gt;This business type is used to represent percentages. The underlying CLR type is &lt;strong&gt;decimal.&lt;/strong&gt; In read-only mode a progress bar is displayed which is green for percentages &amp;lt;= 100% and red otherwise. It’s ideal for representing progress.&lt;br /&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiJmtNsp0cCSwAinxCzJHmuGBdDGEvUavcxkhWST9FOOFRiuTiJeWnOkVUoDA0oQvFKKVlUFI7c70Pflt1KdGKWaDvWfinD7QD5XbJ8zLQwld-hdcN2ABYwo2Zd24YiCB0iL0h2XVjyq5SF/s1600-h/image%25255B5%25255D.png&quot;&gt;&lt;img alt=&quot;image&quot; border=&quot;0&quot; height=&quot;28&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgH9R_SJWxJXdKP6Lt2XZyrogedStaRAfqwWmT-5LgeHsalqTxzMh9i1FoMvvcvGiX1AXu8eWSzMF3dHFuOI31eluK0xFj-0vLRZKD-FEm4W07_4yp8raIxnmhUlxIbbJap5DaS_AlR6_5n//?imgmax=800&quot; style=&quot;background-image: none; border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: inline; margin: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;&quot; title=&quot;image&quot; width=&quot;66&quot; /&gt;&lt;/a&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhxq2Pd336Q3-dc1FBAORaIgyacSpFUhQHTp-LjMcZG0cilYHK2IpjN1wUxT7-aiJzycevDCBo06ePgY8X5WRt7EB8i35JHptb052BPJA9OMjb8yxIle9JpzIUX0pdYbNRSktglNxf9kzNM/s1600-h/image%25255B8%25255D.png&quot;&gt;&lt;img alt=&quot;image&quot; border=&quot;0&quot; height=&quot;28&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgsGlKLzQq4CLQOURsCY2eSMSYXqnaaeM1xsxzd7SzbAiupLGuxZEeFI0TgtVQ3Sm5frNV90h74AO_jRMJmlMTXejhzfn4m95_mygc386yUQ3hODXmx8PfGyhx1oTm1teMa2_mtQzJLwmf1//?imgmax=800&quot; style=&quot;background-image: none; border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: inline; margin: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;&quot; title=&quot;image&quot; width=&quot;68&quot; /&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ImageURI Business type and Controls. &lt;/strong&gt;This business type is used to display an image from a URI location. The underlying CLR type is &lt;strong&gt;string&lt;/strong&gt;. You can define a thumbnail view and size and also choose if the URI should be visible (editable if not read-only). &lt;strong&gt;Stretch Image&lt;/strong&gt; property applies &lt;strong&gt;Uniform&lt;/strong&gt; stretch to the image.&lt;br /&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi1I1Nt78bHy-lheEaEngjqIonC1doXqEO6w3CLy7QPiG88PaySu16Uam7RudK9eY5SJUYe4_UnuP2D4sihjmvtFHm5UIqFDX8fFawRbqcxozhudJCaHaapv-aAzSrtaQkAA0M_E0MkD5gk/s1600-h/image%25255B12%25255D.png&quot;&gt;&lt;img alt=&quot;image&quot; border=&quot;0&quot; height=&quot;292&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj0ZY2qO0eG__SbUitUwwetF-H1MW9v6ZmyrexudGDsHR-xDfbyALqPlEE-epo15FJ5Gz8eRXwFvplT6LiP6q-0G69rnj3XJ5JayhVTJ-Z17dpgIhnRyQxuqguyJb9u-2npMGvE5C4aWeU7//?imgmax=800&quot; style=&quot;background-image: none; border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;&quot; title=&quot;image&quot; width=&quot;360&quot; /&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;AudioFile Business type and Controls.&lt;/strong&gt;This business type is used to store and reproduce audio files from a URI location. The underlying CLR type is &lt;strong&gt;string&lt;/strong&gt;. You can choose if the URI should be visible (editable if not read-only). Play, Pause, Stop, Volume Control are available. Progress is also displayed.&lt;br /&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgvnBR3tT1V9MGW_EKyflH0l-eSQnMlOwm3er7oMQw3hP0CQ4MX30asVmfv9jJZDoauJviRT1edSPq-s9wYz_79HSxcjn1WrKDMxMowPaK9rBLBi217v0-fmEbujkidjoXP1l5n0ObZ0wTq/s1600-h/image%25255B15%25255D.png&quot;&gt;&lt;img alt=&quot;image&quot; border=&quot;0&quot; height=&quot;28&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhi0gQDTcC6hKmKqSi-WTgIIKeVrPftdKbDH69RwjOi3gjfLa6E0_NlK6EBfIUZ_dKjM3HMv0ZCEsoaWdIWTm7uey6qaoolCjhu7gPI2ZOKwI4YJe64YGiYmzjtFzfzH9tOPzNXPOqcjntI//?imgmax=800&quot; style=&quot;background-image: none; border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: inline; margin: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;&quot; title=&quot;image&quot; width=&quot;211&quot; /&gt;&lt;/a&gt;&amp;nbsp;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;VideoFile Business type and Controls. &lt;/strong&gt;This business type is used to store and reproduce video files from a URI location. The underlying CLR type is &lt;strong&gt;string.&lt;/strong&gt; You can choose if the URI should be visible (editable if not read-only). Play, Pause, Stop, Volume Control are available. Progress is also displayed.&lt;br /&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEijmvLlBsm8ZYKLJGDoCCjMHg-BHSlgA69Nfq5XXOalEYQgdI1n8UYYYLCiITFCb6TMt3V2oMPDIy4skHTetQZR0Qrr5EHvgluEaBmmvknQ1NybV02Xw7G_QC0YlazmmZFB-S-RvOsGKovh/s1600-h/image%25255B19%25255D.png&quot;&gt;&lt;img alt=&quot;image&quot; border=&quot;0&quot; height=&quot;278&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi6-IBkSbzSlfzSBIeivQchLfpfjAwpCvxqMuUXnosDgJXByuGS44aEMVINgtB003asajEQ5jf3sF1UKuDVCXEJ-XggaGHq5upwn2Hpxl5snrePKZQGDSX74znt7ZKQ8ezo-0vJQ_4HRAlP//?imgmax=800&quot; style=&quot;background-image: none; border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;&quot; title=&quot;image&quot; width=&quot;359&quot; /&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;DrawingFile type and Control.&lt;/strong&gt; This business type is used to store drawings. The underlying CLR type is &lt;strong&gt;string&lt;/strong&gt;.&lt;strong&gt; &lt;/strong&gt;The background of the drawing is defined as an image URI (not binary). Using the control you can draw lines, polygons and texts on a layer over the image store and edit afterwards to delete drawings, move edit or delete texts, change fonts and colors e.t.c. The control can also operate in local mode, where all drawings are saved in application’s Isolated Storage. Every time a drawing is saved a png image snapshot of the drawing is also generated and can be easily (with 2 lines of code) saved in traditional Image (byte[]) fields.&lt;br /&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi0q8CXeHyYqqm8Gamo3AHC5WOT03q0mKPvlSrHqfWNlYFct0zREvGAtDacebxzYwfylzQmb4LuISLdLiBPcyw5xDwytvatG9xrW4w18hCk1x7a97qF4AL4hZx7TRtcw4NXt0Amot4j23mw/s1600-h/image%25255B23%25255D.png&quot;&gt;&lt;img alt=&quot;image&quot; border=&quot;0&quot; height=&quot;296&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgnQ4BgbfslwW2luQGizTKu2IdHLYclLvNWilYFQXKS_H51lpEqHRI599Sk7ECUoVvf5RmmvzfbUEfBUKOIvaKnRdHJvbcbs8UduQWDYuHx3h8l1m3hgl5-bt9SFWWdrRNLr1lgXewyMKTJ//?imgmax=800&quot; style=&quot;background-image: none; border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;&quot; title=&quot;image&quot; width=&quot;354&quot; /&gt;&lt;/a&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEijaj_8dBK7ffakOVWZIZfUCdPQ-KhpJlfC8oXNGZgJZwhxOblJCSUhtV_RZNTIJBUDQRK3KiKB9mRwCNJ0k7DcjCxP2inBYM237jRZWIFkkyvvD0_O5vnL0_FZVlIkvMj1gDA8vFv0qaZ2/s1600-h/image%25255B28%25255D.png&quot;&gt;&lt;img alt=&quot;image&quot; border=&quot;0&quot; height=&quot;302&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh2wYhAHvAjEwe-SHQumYfSKDwZlx7c_S8xzP8_tf1RntyOS1NpalsxgiQhzbtEVrlbcnCQMAjBllY6t80afGt8H1pgbnDRXmUcIyycWrufeiA_elqTyorzlHOeozlViIyze9RVLhD7-Qhg//?imgmax=800&quot; style=&quot;background-image: none; border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;&quot; title=&quot;image&quot; width=&quot;355&quot; /&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;AttachmentsListEx Collection Control. &lt;/strong&gt;This is a special use collection control used to represent collections of entities implementing &lt;strong&gt;CLASSExtensions.Contracts.IAttachment.&lt;br /&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh08DesofB5Q-F0Uo_z-HhuWRGkSOaLtkfQqwrbooEN21ljjIZl4zyq6hRklgQi-ALGOtEnQgqV0a9wZXYcFq4HO4Mlr4H-g3sJdF7cRP8_aRfFaKRQYJQ_3u-39eabCGNWRakXUHGApM9f/s1600-h/image%25255B31%25255D.png&quot;&gt;&lt;img alt=&quot;image&quot; border=&quot;0&quot; height=&quot;30&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj-Mn6kGoZn9_vQKIhOcQZ_dxceT7hWsLGjgH1cAsZBNgKcvG9mg9frTnLRq6Nu6yeT0qIeLVF7xWWVlccm9HeKm4JdrUBTFG-IUNIalSWJ7PsE0skfsYn2WKKn8sHtevUByujPUmwB6qBd//?imgmax=800&quot; style=&quot;background-image: none; border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: inline; margin: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;&quot; title=&quot;image&quot; width=&quot;102&quot; /&gt;&lt;/a&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;FileServer Datasource Extension.&lt;/strong&gt; A very important RIA Service datasource provided to smoothly integrate all the URI-based features. This Datasource exports two entity types: &lt;strong&gt;ServerFile&lt;/strong&gt; and &lt;strong&gt;ServerFileType&lt;/strong&gt;. Also provides methods to retrieve &lt;strong&gt;ServerFile&lt;/strong&gt; entities representing the content files (Image, Audio, Video, Document, In the current version these are the &lt;strong&gt;ServerFileTypes&lt;/strong&gt; supported) stored at your application server. Also you can delete &lt;strong&gt;ServerFile&lt;/strong&gt; entities. Upload (insert/update) is not implemented in this version as depending on Whether your application is running out of browser or not it has to be done a different way. Maybe in an update. The idea for this datasource was based on &lt;a href=&quot;http://lightswitchhelpwebsite.com/Blog/tabid/61/EntryId/35/Saving-Files-To-File-System-With-LightSwitch-Uploading-Files.aspx&quot; target=&quot;_blank&quot;&gt;this&lt;/a&gt; article of Michael Washington. &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;A good numbered (30+) collection of ValueConverters and Extension Classes.&lt;/strong&gt; You can reuse in your applications either to create your own custom controls and extensions or application code in general.&lt;/li&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;


&lt;strong&gt;&lt;/strong&gt;&lt;/h3&gt;
&lt;h3&gt;


Pricing&lt;/h3&gt;
The price is 50$ for the package without the code. Depending on demand a code inclusive version and pricing may become available. The payment is done through PayPal and if invoice is required will be sent by post. After payment you will receive a zip file containing the vsix file the sample application used for the demostration videos.&lt;br /&gt;
&lt;h3&gt;


&lt;strong&gt;Remarks&lt;/strong&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Regarding &lt;strong&gt;Rating business type &lt;/strong&gt;the Maximum and Default rating properties have to be set on the control. Although I found I way to add attributes to the business type, I couldn’t find a way to retrieve in the control so that these parameters could be set once on the entity’s property.&lt;/li&gt;
&lt;li&gt;The reason &lt;strong&gt;DrawingFile&lt;/strong&gt; is using URI as image background and not a binary image was a result of my intention to create a lightweight drawing type which is also portable. As long as the image URI is public the drawings can be ported to any other application using the extension copying just a few KBs.&lt;/li&gt;
&lt;li&gt;For the &lt;strong&gt;FileServer Datasource &lt;/strong&gt;to work you must create a folder hierarchy in your web application’s folder. You have to create a &lt;strong&gt;Content&lt;/strong&gt; (see also ContentDirectory appSetting below) sub-folder in the root folder of your application and a hierarchy like shown below. If the folders are not there, an attempt will be made by code to be created, but to avoid extra permissions issues you can create in advance. Also if you want to be able to delete files you have to take care of file permissions so that the account can delete files. &lt;br /&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjAxbHq7uDGPXHNsncxUHW1xL_Id1lmSf5vn9ftVSphMQGjZWssBZiRL-iiXa2OQE9ovgbsF-PyUIPwwWBQcd8cUnzLD-HCxybEbt5x50wEEwFPtf439uBwBgkBEzSboJQ0GwIfWljiiQ_u/s1600-h/image%25255B34%25255D.png&quot;&gt;&lt;img alt=&quot;image&quot; border=&quot;0&quot; height=&quot;89&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiZ6ytTWMGuEOnTQas-oeoiWgmpGE-WGgWYKJUtlyULK2ZGAAPb5gDkuc9or2aAdSa9FLKZvKpwp8rktO52nHHkpe-SfJySXD0G2BCpspZ-n7DY-4ip474y4rooGv0GaGTi5mIVQsrtX4rL//?imgmax=800&quot; style=&quot;background-image: none; border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: inline; margin: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;&quot; title=&quot;image&quot; width=&quot;92&quot; /&gt;&lt;/a&gt;&lt;br /&gt;Also, as you can see in the sample application you will receive along with the extensions, in ServerGenerated\web.config there are 2 appSettings entries:&lt;br /&gt;&lt;br /&gt;&amp;lt;add key=&quot;VirtualDirectory&quot; value=&quot;&quot; /&amp;gt;&lt;br /&gt;&amp;lt;add key=&quot;ContentDirectory&quot; value=&quot;Content&quot; /&amp;gt;&lt;br /&gt;&lt;br /&gt;The first one &lt;strong&gt;VirtualDirectory&lt;/strong&gt; is compulsory and if your application is not running at the root of the publishing site the value should be the name of the virtual directory under which your application is running. In the sample the value is null.&lt;br /&gt;The second one &lt;strong&gt;ContentDirectory&lt;/strong&gt; is optional and if omitted then &lt;strong&gt;Content&lt;/strong&gt; is assumed as the folder to look for files.&lt;/li&gt;
&lt;li&gt;For &lt;b&gt;AudioFile and VideoFile&lt;/b&gt;&amp;nbsp;controls: The total duration of the media file is not always available so many times in the rightmost digital time display the value will be zero.&lt;/li&gt;
&lt;li&gt;For all URI based types: If you are using the &lt;strong&gt;FileServer Datasource&lt;/strong&gt; while debugging you will have issues regarding the validity of the URIs. As between builds and runs the host’s port can change, a URI provided from the &lt;strong&gt;FileServer Datasource&lt;/strong&gt; (containing the current port) during one debug session, may be invalid in a next session if the port changes. Of course after deployment this will never be an issue unless you somehow change your application’s URL.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kostaschristodoulou.blogspot.com/feeds/469636232175345256/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kostaschristodoulou.blogspot.com/2012/03/class-extensions-version-2-released.html#comment-form' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1977783208088103440/posts/default/469636232175345256'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1977783208088103440/posts/default/469636232175345256'/><link rel='alternate' type='text/html' href='http://kostaschristodoulou.blogspot.com/2012/03/class-extensions-version-2-released.html' title='CLASS Extensions Version 2 Released'/><author><name>Kostas Christodoulou</name><uri>http://www.blogger.com/profile/07577025344678922877</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='29' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg-vpaqKzo9_w1Z5f97Dh74HcFctRHYFDWYNgNp35Gy2_84EvKNIZl57RAMvxB8JlsIic3iTrZ2Pv7D7leYIc_15MOo4Uh8hJI-4OF2Mv1G9-GYOCsOO_k7uxsAzbLxRNQ/s220/Me2.jpg'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjFBnEv41hgBTfi0kkrf-twPXgkqZZtytM7OovK2yxxEjyL1sgdpXAm8i2y9dMFYMMImFKGJqcBRc0rbYD9BmjHOStWljSiYoUcQ2_w6NA5bpZp7WBUUtwydPEdez_kuVaTY2G5u67R4Uc3/s72-c/?imgmax=800" height="72" width="72"/><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1977783208088103440.post-2429640913705295878</id><published>2012-03-17T15:11:00.000+02:00</published><updated>2012-03-17T15:11:16.338+02:00</updated><title type='text'>CLASS Extensions Version 2 Demo</title><content type='html'>&lt;p&gt;After a long time of preparation, my company &lt;a href=&quot;http://www.computerlife.gr&quot; target=&quot;_blank&quot;&gt;Computer Life&lt;/a&gt; and me we are ready to publish the next –commercial- version of CLASS Extensions.&lt;/p&gt; &lt;p&gt;In &lt;a href=&quot;https://skydrive.live.com/?cid=6C344D9AD6A0DEC2&amp;amp;id=6C344D9AD6A0DEC2%21200&amp;amp;sc=documents&quot; target=&quot;_blank&quot;&gt;this&lt;/a&gt; SkyDrive location you can find 2 videos briefly presenting capabilities of this new version. In less than a week a page will be started here, where you would be able to buy the package you prefer. There will be 2 packages: no source code and with code and code documentation. Pricing will be announced along with the official release.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&quot;https://skydrive.live.com/?cid=6C344D9AD6A0DEC2&amp;amp;id=6C344D9AD6A0DEC2%21200&amp;amp;sc=documents&quot; target=&quot;_blank&quot;&gt;CLASS Extensions Demo Part I.swf&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;a href=&quot;https://skydrive.live.com/?cid=6C344D9AD6A0DEC2&amp;amp;id=6C344D9AD6A0DEC2%21200&amp;amp;sc=documents&quot; target=&quot;_blank&quot;&gt;&lt;img style=&quot;background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px&quot; title=&quot;Part1&quot; border=&quot;0&quot; alt=&quot;Part1&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhp0ZTwnwis1Lg3igXbi6cEzPBQnonglahal1ARcch9tWt6AK-873c0CeSRdmQtg238ZPQJK4a8UkqW67rzehHAmQJ3SI9Y-3wIIiZXzB4NxR9_TuFqbWKKxmHkc7bXRFLAGVsugueaUwid//?imgmax=800&quot; width=&quot;244&quot; height=&quot;133&quot;&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&quot;https://skydrive.live.com/?cid=6C344D9AD6A0DEC2&amp;amp;id=6C344D9AD6A0DEC2%21200&amp;amp;sc=documents&quot; target=&quot;_blank&quot;&gt;CLASS Extensions Demo Part II.swf&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;a href=&quot;https://skydrive.live.com/?cid=6C344D9AD6A0DEC2&amp;amp;id=6C344D9AD6A0DEC2%21200&amp;amp;sc=documents&quot;&gt;&lt;img style=&quot;background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px&quot; title=&quot;Part2&quot; border=&quot;0&quot; alt=&quot;Part2&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgrQPI3UVi1VxgX-p-xtXbOGbVyksiI8LpGokMHpBCgXo5tzMQj5NWN2gtLz4aprosVbC1qG-ljHNtiGhf3IN05mLR571oStKlMj4V6tS9IkHWNIrEgHvO-4xDJAtYXXSphWgWHEmZ_gRpB//?imgmax=800&quot; width=&quot;244&quot; height=&quot;153&quot;&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;In these videos you will find a brief demonstration of the following controls and/or business types:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;strong&gt;Color Business Type and Control&lt;/strong&gt;. This was available also in the first free version. It has been improved to automatically detect grid or detail and read-only or not.&lt;/li&gt; &lt;li&gt;&lt;strong&gt;BooleanCheckbox and BooleanViewer controls.&lt;/strong&gt; These were also available in the first version. No change to this one.&lt;/li&gt; &lt;li&gt;&lt;strong&gt;Rating Business Type and Control.&lt;/strong&gt; A new business type to support ratings. You can set maximum rating, star size, show/hide starts and/or labels, allow/disallow half stars.&lt;/li&gt; &lt;li&gt;&lt;strong&gt;Image Uri Business Type and Control. &lt;/strong&gt;A new business type to support displaying images from a URI location instead of binary data.&lt;/li&gt; &lt;li&gt;&lt;strong&gt;Audio Uri Business Type and Control. &lt;/strong&gt;A new business type to support playing audio files from a URI location.&lt;/li&gt; &lt;li&gt;&lt;strong&gt;Video Uri Business Type and Control. &lt;/strong&gt;A new business type to support playing video files from a URI location.&lt;/li&gt; &lt;li&gt;&lt;strong&gt;Drawing Business Type and Control.&lt;/strong&gt;&amp;nbsp; A new business type that allows the user to create drawings using an image URI (not binary) as background. The drawing can be saved either as a property of an entity (the underlying type is string) or in the IsolatedStorage of the application. Also, every time the drawing is saved a PNG snapshot of the drawing is available and can be used any way you want, with 2 (two) lines of additional code. The drawings, both local or data service provided, can be retrieved any time and modified and saved back again.&lt;/li&gt; &lt;li&gt;&lt;strong&gt;FileServer Datasource Extension.&lt;/strong&gt; A very important RIA Service datasource provided to smoothly integrate all the URI-based features. This Datasources exports two EntityTypes: ServerFile and ServerFileType. Also provides methods to retrieve ServerFile entities representing the content files (Image, Audio, Video, Document, In the current version these are the ServerFileTypes supported) stored at your application server. Also you can delete ServerFile entities. Upload (insert/update) is not implemented in this version as depending on Whether your application is running out of browser or not it has to be done a different way.&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;Last but not least. There is a list of people whose code and ideas helped me a lot in the implementation of this version. Upon official release they will be properly mentioned as community is priceless.&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://kostaschristodoulou.blogspot.com/feeds/2429640913705295878/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kostaschristodoulou.blogspot.com/2012/03/class-extensions-version-2-demo.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1977783208088103440/posts/default/2429640913705295878'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1977783208088103440/posts/default/2429640913705295878'/><link rel='alternate' type='text/html' href='http://kostaschristodoulou.blogspot.com/2012/03/class-extensions-version-2-demo.html' title='CLASS Extensions Version 2 Demo'/><author><name>Kostas Christodoulou</name><uri>http://www.blogger.com/profile/07577025344678922877</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='29' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg-vpaqKzo9_w1Z5f97Dh74HcFctRHYFDWYNgNp35Gy2_84EvKNIZl57RAMvxB8JlsIic3iTrZ2Pv7D7leYIc_15MOo4Uh8hJI-4OF2Mv1G9-GYOCsOO_k7uxsAzbLxRNQ/s220/Me2.jpg'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhp0ZTwnwis1Lg3igXbi6cEzPBQnonglahal1ARcch9tWt6AK-873c0CeSRdmQtg238ZPQJK4a8UkqW67rzehHAmQJ3SI9Y-3wIIiZXzB4NxR9_TuFqbWKKxmHkc7bXRFLAGVsugueaUwid/s72-c/?imgmax=800" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1977783208088103440.post-8100636074771663949</id><published>2012-02-22T12:27:00.002+02:00</published><updated>2012-07-11T14:47:20.556+03:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Advanced"/><category scheme="http://www.blogger.com/atom/ns#" term="Extension Methods"/><category scheme="http://www.blogger.com/atom/ns#" term="Under the Hood"/><title type='text'>Application Logo Sample</title><content type='html'>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
Application Logo post had the dazzling number of 4 questions regarding how to use the code. So as I promised to the last guy that asked how to use the extension class I created a small sample and uploaded to msdn&#39;s Lightswitch samples. You can find it &lt;a href=&quot;http://code.msdn.microsoft.com/Application-Logo-Demo-8edb214d&quot;&gt;here&lt;/a&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kostaschristodoulou.blogspot.com/feeds/8100636074771663949/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kostaschristodoulou.blogspot.com/2012/02/application-logo-sample.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1977783208088103440/posts/default/8100636074771663949'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1977783208088103440/posts/default/8100636074771663949'/><link rel='alternate' type='text/html' href='http://kostaschristodoulou.blogspot.com/2012/02/application-logo-sample.html' title='Application Logo Sample'/><author><name>Kostas Christodoulou</name><uri>http://www.blogger.com/profile/07577025344678922877</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='29' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg-vpaqKzo9_w1Z5f97Dh74HcFctRHYFDWYNgNp35Gy2_84EvKNIZl57RAMvxB8JlsIic3iTrZ2Pv7D7leYIc_15MOo4Uh8hJI-4OF2Mv1G9-GYOCsOO_k7uxsAzbLxRNQ/s220/Me2.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1977783208088103440.post-7518715368993422160</id><published>2012-02-07T20:47:00.001+02:00</published><updated>2012-02-13T09:41:57.807+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Data"/><category scheme="http://www.blogger.com/atom/ns#" term="DataSources"/><category scheme="http://www.blogger.com/atom/ns#" term="Intermediate"/><title type='text'>Re-Views</title><content type='html'>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
In previous &lt;a href=&quot;http://kostaschristodoulou.blogspot.com/2011/10/sort-this-you-light-of-switch.html&quot; target=&quot;_blank&quot;&gt;posts&lt;/a&gt; I made reference to views (DB or RIA) as an alternative (amongst other well-known potentials of views) to search and sort against fields that would normally be relations (lookups or however you want to call them).&lt;br /&gt;
From the very beginning I had an issue with SQL Server views imported to LS. LightSwitch had a very strange way to define the primary keys of the views. These “inferred” primary keys are most of the time very complex combined keys. And this is not an issue actually until you decide to add a relationship between this view (which 99% of the times has only one field as actual primary key) and another table. Then you realize this, otherwise benign, complex primary key is an issue (to say the least).&lt;br /&gt;
It was only recently, in this &lt;a href=&quot;http://social.msdn.microsoft.com/Forums/en-US/lightswitch/thread/560532c7-fb8b-499f-8422-aef49feed12b/#f2bf1ed1-2923-4172-80e0-796550fcb327&quot; target=&quot;_blank&quot;&gt;thread&lt;/a&gt;, after Yann Duran’s suggested reading (always to the rescue and always having something useful to contribute), that I managed to both understand how LS “infers” the Primary Key for a View and realize how one can “force” a primary key.&lt;br /&gt;
The bottom line is that LS decides that all not-nullable fields will be part of the inferred primary key. Not very inspired but I must admit I cannot think of anything better. So, how one can force the primary key one wants? The way is re-introducing all you not-nullable, non-key fields by cast/convert to the same data-type (or another one if needed). This way the definition of the “table”/”view” imported by LS contains all, originally not nullable fields, as nullable.&lt;br /&gt;
Very short example. Imagine Table Person as&lt;br /&gt;
Id int not null, PK&lt;br /&gt;
LastName nvarchar(50) not null,&lt;br /&gt;
FirstName nvarchar(50) null,&lt;br /&gt;
.&lt;br /&gt;
.&lt;br /&gt;
.&lt;br /&gt;
Your view’s SQL would be&lt;br /&gt;
select Id, CONVERT(nvarchar(50), LastName) as LastName, FirstName&lt;br /&gt;
from Person&lt;br /&gt;
Simple, dummy example just to display what I mean.&lt;br /&gt;
I feel I am re-inventing the wheel as this information was already out there, but in Greece we say “Επανάληψη μήτηρ μαθήσεως” or “Repetition is the mother of Learning” or something like that. Looks like we never learned much from this anyways… &lt;br /&gt;
&lt;br /&gt;
P.S. After Yann&#39;s suggestion I have to note that actually this inferred primary key mechanism is Entity Framwork&#39;s native and not LightSwitch own behaviour. Although I had that in my mind I didn&#39;t make it clear here. I apologize for any missunderstanding and I thank Yann once more for the comment.&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kostaschristodoulou.blogspot.com/feeds/7518715368993422160/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kostaschristodoulou.blogspot.com/2012/02/re-views.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1977783208088103440/posts/default/7518715368993422160'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1977783208088103440/posts/default/7518715368993422160'/><link rel='alternate' type='text/html' href='http://kostaschristodoulou.blogspot.com/2012/02/re-views.html' title='Re-Views'/><author><name>Kostas Christodoulou</name><uri>http://www.blogger.com/profile/07577025344678922877</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='29' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg-vpaqKzo9_w1Z5f97Dh74HcFctRHYFDWYNgNp35Gy2_84EvKNIZl57RAMvxB8JlsIic3iTrZ2Pv7D7leYIc_15MOo4Uh8hJI-4OF2Mv1G9-GYOCsOO_k7uxsAzbLxRNQ/s220/Me2.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1977783208088103440.post-4633695746588999497</id><published>2012-01-20T22:20:00.001+02:00</published><updated>2012-07-11T14:47:34.823+03:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Advanced"/><category scheme="http://www.blogger.com/atom/ns#" term="Extension Methods"/><category scheme="http://www.blogger.com/atom/ns#" term="Under the Hood"/><title type='text'>Application Logo</title><content type='html'>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
Reading &lt;a href=&quot;http://social.msdn.microsoft.com/Forums/en-US/lightswitch/thread/2d16c638-f833-4c4c-beec-656912a87b8e&quot; target=&quot;_blank&quot;&gt;this&lt;/a&gt; article in MSDN forums and taking the best (I hope) of what &lt;a href=&quot;http://social.msdn.microsoft.com/profile/lr__/?type=forum&amp;amp;referrer=http://social.msdn.microsoft.com/Forums/en-US/lightswitch/thread/2d16c638-f833-4c4c-beec-656912a87b8e&quot; target=&quot;_blank&quot;&gt;LR_&lt;/a&gt; and &lt;a href=&quot;http://social.msdn.microsoft.com/profile/adefwebserver/?ws=usercard-hover&quot; target=&quot;_blank&quot;&gt;Michael Washington&lt;/a&gt; offered as solutions I ended up with an extension class that allows you to put your application’s logo on the Ribbon Bar of any shell having one. You also have the choice to put it either on the left or the right. LR_’s original code was only modified in 2 points.&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;You can decide if you want you Application Logo on the left or on the right of your commands.&lt;/li&gt;
&lt;li&gt;You don’t need to pass a URL to the image. The application’s logo (defined in project properties) is bound inspired by the XAML provided by Michael Washington.&lt;/li&gt;
&lt;/ol&gt;
I even left the LeftButtonDown part as it’s a good idea.&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;background-color: white; color: #2e3d47; font-family: Tahoma, Arial, sans-serif; font-size: 13px; text-align: -webkit-auto;&quot;&gt;Although implied from the detailed reference to them I want to thank both guys for making it so easy for me to put my logo on screen.&lt;/span&gt;
&lt;br /&gt;
&lt;span style=&quot;background-color: white; color: #2e3d47; font-family: Tahoma, Arial, sans-serif; font-size: 13px; text-align: -webkit-auto;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;pre class=&quot;csharpcode&quot;&gt;    &lt;span class=&quot;kwrd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;class&lt;/span&gt; LogoPlacement

    {

         &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;void&lt;/span&gt; AddLogo(&lt;span class=&quot;kwrd&quot;&gt;this&lt;/span&gt; Microsoft.LightSwitch.Client.IClientApplication application, System.Windows.HorizontalAlignment alignment) {

           Microsoft.LightSwitch.Threading.Dispatchers.Main.BeginInvoke(() =&amp;gt; { LogoPlacement.AddLogo(System.Windows.Application.Current.RootVisual, alignment); });

         }

      &lt;span class=&quot;kwrd&quot;&gt;internal&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;void&lt;/span&gt; AddLogo(UIElement element, System.Windows.HorizontalAlignment alignment) {

        &lt;span class=&quot;kwrd&quot;&gt;if&lt;/span&gt; (rcb != &lt;span class=&quot;kwrd&quot;&gt;null&lt;/span&gt;) &lt;span class=&quot;kwrd&quot;&gt;return&lt;/span&gt;;

 

        &lt;span class=&quot;kwrd&quot;&gt;for&lt;/span&gt; (&lt;span class=&quot;kwrd&quot;&gt;int&lt;/span&gt; i = 0; i &amp;lt; System.Windows.Media.VisualTreeHelper.GetChildrenCount(element); i++) {

          &lt;span class=&quot;kwrd&quot;&gt;if&lt;/span&gt; (rcb != &lt;span class=&quot;kwrd&quot;&gt;null&lt;/span&gt;)

            &lt;span class=&quot;kwrd&quot;&gt;return&lt;/span&gt;;

          UIElement child = (UIElement)System.Windows.Media.VisualTreeHelper.GetChild(element, i);

          AddLogo(child, alignment);

        }

        &lt;span class=&quot;kwrd&quot;&gt;if&lt;/span&gt; (element &lt;span class=&quot;kwrd&quot;&gt;is&lt;/span&gt; Microsoft.LightSwitch.Runtime.Shell.Implementation.Standard.RibbonCommandBar) {

          rcb = element &lt;span class=&quot;kwrd&quot;&gt;as&lt;/span&gt; Microsoft.LightSwitch.Runtime.Shell.Implementation.Standard.RibbonCommandBar;

          Image myImage = &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; Image() {

            Stretch = System.Windows.Media.Stretch.Uniform,

            Margin = &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; Thickness(2,8,14,8),

            HorizontalAlignment = alignment,

            Cursor = System.Windows.Input.Cursors.Hand

          };

          myImage.SetValue(ComponentViewModelService.ViewModelNameProperty, &lt;span class=&quot;str&quot;&gt;&quot;Default.LogoViewModel&quot;&lt;/span&gt;);

          myImage.SetBinding(Image.SourceProperty, &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; System.Windows.Data.Binding { Path = &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; PropertyPath(&lt;span class=&quot;str&quot;&gt;&quot;Logo&quot;&lt;/span&gt;) });

          myImage.MouseLeftButtonUp += (s, e) =&amp;gt; MessageBox.Show(&lt;span class=&quot;str&quot;&gt;&quot;Here may be some About...&quot;&lt;/span&gt;);

          myImage.SizeChanged += (s, e) =&amp;gt; {

            &lt;span class=&quot;kwrd&quot;&gt;double&lt;/span&gt; left = (s &lt;span class=&quot;kwrd&quot;&gt;as&lt;/span&gt; Image).HorizontalAlignment == HorizontalAlignment.Left ? e.NewSize.Width + 10.0 : 0.0;

            &lt;span class=&quot;kwrd&quot;&gt;double&lt;/span&gt; right = (s &lt;span class=&quot;kwrd&quot;&gt;as&lt;/span&gt; Image).HorizontalAlignment == HorizontalAlignment.Right ? e.NewSize.Width + 10.0 : 0.0;

            rcb.Padding = &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; Thickness(left, 0, right, 0);

          };

          ((Grid)rcb.Parent).Children.Add(myImage);

        }

      }

 

      &lt;span class=&quot;kwrd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;static&lt;/span&gt; RibbonCommandBar rcb = &lt;span class=&quot;kwrd&quot;&gt;null&lt;/span&gt;;

    }&lt;/pre&gt;
&lt;br /&gt;
&lt;style type=&quot;text/css&quot;&gt;
.csharpcode, .csharpcode pre&lt;br /&gt;{&lt;br /&gt; font-size: small;&lt;br /&gt; color: black;&lt;br /&gt; font-family: consolas, &quot;Courier New&quot;, courier, monospace;&lt;br /&gt; background-color: #ffffff;&lt;br /&gt; /*white-space: pre;*/&lt;br /&gt;}&lt;br /&gt;.csharpcode pre { margin: 0em; }&lt;br /&gt;.csharpcode .rem { color: #008000; }&lt;br /&gt;.csharpcode .kwrd { color: #0000ff; }&lt;br /&gt;.csharpcode .str { color: #006080; }&lt;br /&gt;.csharpcode .op { color: #0000c0; }&lt;br /&gt;.csharpcode .preproc { color: #cc6633; }&lt;br /&gt;.csharpcode .asp { background-color: #ffff00; }&lt;br /&gt;.csharpcode .html { color: #800000; }&lt;br /&gt;.csharpcode .attr { color: #ff0000; }&lt;br /&gt;.csharpcode .alt &lt;br /&gt;{&lt;br /&gt; background-color: #f4f4f4;&lt;br /&gt; width: 100%;&lt;br /&gt; margin: 0em;&lt;br /&gt;}&lt;br /&gt;.csharpcode .lnum { color: #606060; }&lt;br /&gt;
&lt;/style&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;style type=&quot;text/css&quot;&gt;
.csharpcode, .csharpcode pre&lt;br /&gt;{&lt;br /&gt; font-size: small;&lt;br /&gt; color: black;&lt;br /&gt; font-family: consolas, &quot;Courier New&quot;, courier, monospace;&lt;br /&gt; background-color: #ffffff;&lt;br /&gt; /*white-space: pre;*/&lt;br /&gt;}&lt;br /&gt;.csharpcode pre { margin: 0em; }&lt;br /&gt;.csharpcode .rem { color: #008000; }&lt;br /&gt;.csharpcode .kwrd { color: #0000ff; }&lt;br /&gt;.csharpcode .str { color: #006080; }&lt;br /&gt;.csharpcode .op { color: #0000c0; }&lt;br /&gt;.csharpcode .preproc { color: #cc6633; }&lt;br /&gt;.csharpcode .asp { background-color: #ffff00; }&lt;br /&gt;.csharpcode .html { color: #800000; }&lt;br /&gt;.csharpcode .attr { color: #ff0000; }&lt;br /&gt;.csharpcode .alt &lt;br /&gt;{&lt;br /&gt; background-color: #f4f4f4;&lt;br /&gt; width: 100%;&lt;br /&gt; margin: 0em;&lt;br /&gt;}&lt;br /&gt;.csharpcode .lnum { color: #606060; }&lt;br /&gt;
&lt;/style&gt;  &lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kostaschristodoulou.blogspot.com/feeds/4633695746588999497/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kostaschristodoulou.blogspot.com/2012/01/application-logo.html#comment-form' title='14 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1977783208088103440/posts/default/4633695746588999497'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1977783208088103440/posts/default/4633695746588999497'/><link rel='alternate' type='text/html' href='http://kostaschristodoulou.blogspot.com/2012/01/application-logo.html' title='Application Logo'/><author><name>Kostas Christodoulou</name><uri>http://www.blogger.com/profile/07577025344678922877</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='29' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg-vpaqKzo9_w1Z5f97Dh74HcFctRHYFDWYNgNp35Gy2_84EvKNIZl57RAMvxB8JlsIic3iTrZ2Pv7D7leYIc_15MOo4Uh8hJI-4OF2Mv1G9-GYOCsOO_k7uxsAzbLxRNQ/s220/Me2.jpg'/></author><thr:total>14</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1977783208088103440.post-2685429723332011521</id><published>2012-01-16T19:17:00.001+02:00</published><updated>2012-01-17T16:42:10.246+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Advanced"/><category scheme="http://www.blogger.com/atom/ns#" term="Data"/><category scheme="http://www.blogger.com/atom/ns#" term="DataSources"/><title type='text'>Save (is a pain in the) As</title><content type='html'>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
Currently being in the process of developing a business application, I came across an issue that looked harmless, but turned out to be what the title elegantly :-P implies.&lt;br /&gt;
Being very proud of what I can achieve in no time with LS, I had my product manager testing the application, when she ask me the simple: “How can I change something and save it as a new object with a new name?”. “It’s not implemented yet, but I am getting my hands on it right now and you will have it in no time”. What a typical developer answer!&lt;br /&gt;
“No time” turned out to be a full workday of experimenting trying to find out the best and most generic way to implement Save As functionality. Having an object being copied to another was something I had already implemented but I worked fine only on originals. Fetching an object to the client, modifying it somehow and then trying to copy to a new one, discard the changes of the original object and save the copy…well it was not a piece of cake, rather a pastry shop.&lt;br /&gt;
Creating a new object in a different instance of the dataworkspace and trying to copy ended up in a threading hell, as my object was not a simple one but having many one to many and many to many relations and threading had to be made “safe” to ensure consistency. Even if could manage to do it for the type of object requested by my product manager, the solution would be specific to this object and generalization would be a project on its own, with doubtful result.&lt;br /&gt;
Having the original and the copy on the same screen and context, made almost impossible to find a general way to discard changes made to the original (or any of the related objects) before saving the dataworkspace.&lt;br /&gt;
The final solution was rather naive, but totally generic and “LightSwitch” with only one drawback that I will mention at the end.&lt;br /&gt;
My datasource was an SQL Server based one. So I created a new one called &lt;strong&gt;&lt;em&gt;myDataSourceName&lt;/em&gt;Copy &lt;/strong&gt;from the same database and also named all the entities &lt;strong&gt;&lt;em&gt;EntityName&lt;/em&gt;Copy&lt;/strong&gt; (much better that &lt;em&gt;EntityName&lt;/em&gt;1 suggested by default from LS. Now I had a &lt;strong&gt;&lt;em&gt;myDataSourceName.&lt;/em&gt;Customer&lt;/strong&gt; (for example) instance on my Customer Details screen and a &lt;strong&gt;&lt;em&gt;myDataSourceName&lt;/em&gt;Copy.CustomerCopy&lt;/strong&gt; property waiting to be instantiated upon “Save As” command by the user. &lt;br /&gt;
A small parenthesis: one of the first contracts I designed and implemented for all the objects need was &lt;strong&gt;ICopyTo&amp;lt;TEntityType&amp;gt; where TEntityType : IEntityObject&lt;/strong&gt;, which exposes a &lt;strong&gt;void CopyTo(TEntityType target)&lt;/strong&gt;. So Customer was already implementing &lt;strong&gt;ICopyTo&amp;lt;Customer&amp;gt;&lt;/strong&gt; and what I had to do was implement &lt;strong&gt;ICopyTo&amp;lt;CustomerCopy&amp;gt;&lt;/strong&gt; (and all referenced objects accordingly of course).&lt;br /&gt;
In order to by able to save from my screen both in &lt;em&gt;&lt;strong&gt;myDataSourceName&lt;/strong&gt; &lt;/em&gt;and &lt;em&gt;&lt;strong&gt;myDataSourceNameCopy&lt;/strong&gt; &lt;/em&gt;Ι took a look at &lt;a href=&quot;http://msdn.microsoft.com/en-us/lightswitch/Video/hh313625&quot; target=&quot;_blank&quot;&gt;this video tutorial&lt;/a&gt;. In the end when the used confirms the Save As, I save the changes in &lt;em&gt;&lt;strong&gt;myDataSourceNameCopy&lt;/strong&gt;, &lt;/em&gt;I discard the changes of &lt;em&gt;&lt;strong&gt;myDataSourceName&lt;/strong&gt;, &lt;/em&gt;close the screen, refresh the list of Customers (or whatever) and my “Saved As” Customer is there in the list of Customers ready to use. Well, I have to update two datasources every time my database changes but it’s a small price to pay, given that save as Is very important for my application.&lt;br /&gt;
The drawback is that I haven’t yet managed to figure out how this can be achieved with native LS datasources.&lt;br /&gt;
If anyone has implemented some other generic way to support Save As functionality and has to offer any ideas I would very much appreciate the comments.&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kostaschristodoulou.blogspot.com/feeds/2685429723332011521/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kostaschristodoulou.blogspot.com/2012/01/save-is-pain-in-as_16.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1977783208088103440/posts/default/2685429723332011521'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1977783208088103440/posts/default/2685429723332011521'/><link rel='alternate' type='text/html' href='http://kostaschristodoulou.blogspot.com/2012/01/save-is-pain-in-as_16.html' title='Save (is a pain in the) As'/><author><name>Kostas Christodoulou</name><uri>http://www.blogger.com/profile/07577025344678922877</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='29' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg-vpaqKzo9_w1Z5f97Dh74HcFctRHYFDWYNgNp35Gy2_84EvKNIZl57RAMvxB8JlsIic3iTrZ2Pv7D7leYIc_15MOo4Uh8hJI-4OF2Mv1G9-GYOCsOO_k7uxsAzbLxRNQ/s220/Me2.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1977783208088103440.post-2899696433124606289</id><published>2011-12-21T21:41:00.001+02:00</published><updated>2011-12-21T21:41:17.541+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Advanced"/><category scheme="http://www.blogger.com/atom/ns#" term="Extensions"/><title type='text'>Custom Controls vs. Extensions</title><content type='html'>&lt;p&gt;Did you know that, although I have &lt;a href=&quot;http://http://kostaschristodoulou.blogspot.com/2011/10/class-extensions-making-of-introduction.html&quot; target=&quot;_blank&quot;&gt;previously&lt;/a&gt; voted for extensions, my experience with LightSwitch helped me realize that in some cases custom controls can be more effective than extensions or even handle issues extensions are not meant to handle. &lt;/p&gt; &lt;p&gt;When special manipulation and user interaction has to be handled (like drag’ n’ drop handling especially between differently typed collections) although extensions can be employed, IMHO, the plumbing needed to achieve the desired goal is to be taken under serious consideration. In general the question to be answered, as to whether one should implement an Extension Control or a Custom Control, is if the effort needed to extract the general behaviors and characteristics required by the entities to be handled and thus generalize the control, is worth it. And by “worth it” I mean what are the chances one will be able to reuse it. &lt;/p&gt; &lt;p&gt;There are cases that very special data manipulation requirements need to be met (once and maybe never again). In these cases a &lt;strong&gt;“Project”&lt;/strong&gt; Custom Control (proprietary terminology) is the best solution. By &lt;strong&gt;“Project”&lt;/strong&gt; I mean a custom control that is aware of the domain. Created in the &lt;strong&gt;Client&lt;/strong&gt; project maybe or any other project with a reference to the &lt;strong&gt;Client&lt;/strong&gt; project. The &lt;strong&gt;Client&lt;/strong&gt; project apart from being aware of the domain has also direct reference to the concrete client &lt;strong&gt;LightswitchApplication &lt;/strong&gt;with all the plumbing required to have access to the concrete Dataworkspace.&lt;/p&gt; &lt;p&gt;One thing is for sure, as soon as you have a custom control operating without having concrete reference to your domain and application, you have a perfect candidate for a Control Extension and you should implement it as soon as possible.&lt;/p&gt;  </content><link rel='replies' type='application/atom+xml' href='http://kostaschristodoulou.blogspot.com/feeds/2899696433124606289/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kostaschristodoulou.blogspot.com/2011/12/custom-controls-vs-extensions.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1977783208088103440/posts/default/2899696433124606289'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1977783208088103440/posts/default/2899696433124606289'/><link rel='alternate' type='text/html' href='http://kostaschristodoulou.blogspot.com/2011/12/custom-controls-vs-extensions.html' title='Custom Controls vs. Extensions'/><author><name>Kostas Christodoulou</name><uri>http://www.blogger.com/profile/07577025344678922877</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='29' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg-vpaqKzo9_w1Z5f97Dh74HcFctRHYFDWYNgNp35Gy2_84EvKNIZl57RAMvxB8JlsIic3iTrZ2Pv7D7leYIc_15MOo4Uh8hJI-4OF2Mv1G9-GYOCsOO_k7uxsAzbLxRNQ/s220/Me2.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1977783208088103440.post-330752930588182843</id><published>2011-11-20T12:49:00.001+02:00</published><updated>2011-11-20T12:50:38.776+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Concurrency"/><category scheme="http://www.blogger.com/atom/ns#" term="Data"/><category scheme="http://www.blogger.com/atom/ns#" term="Intermediate"/><category scheme="http://www.blogger.com/atom/ns#" term="RIA Services"/><title type='text'>Auditing and Concurrency don’t mix (easily)…</title><content type='html'>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
In MSDN forums I came across a &lt;a href=&quot;http://social.msdn.microsoft.com/Forums/en-US/lightswitch/thread/b15fc963-806f-4e0c-a533-f4946fb8c3eb/#c6f6a4bc-c4e5-467a-8265-16e28286c42d&quot; target=&quot;_blank&quot;&gt;post&lt;/a&gt; addressing an issue I have also faced. Auditing fields can cause concurrency issues in LightSwitch (not exclusively).&lt;br /&gt;
In general basic auditing includes keeping track of when an entity was created/modified and by whom. I say basic auditing because auditing is in general much more than this.&lt;br /&gt;
Anyhow, this basic auditing mechanism is very widely implemented (it’s a way for developers to be able to easily find a user to blame for their own bugs :-p), so let’s see what this can cause and why in LightSwitch.&lt;br /&gt;
In the aforementioned post but also in this &lt;a href=&quot;http://kostaschristodoulou.blogspot.com/2011/10/concurrent-or-fast-id-rather-have-both.html&quot; target=&quot;_blank&quot;&gt;one&lt;/a&gt;, I have clearly stated that IMHO the best way to handle concurrency issues is using RIA Services. If you don’t, read what follows.&lt;br /&gt;
Normally in any application, updating the fields that implement Audit tracking would be a task completed in the business layer (or even Data layer in some cases and this could go as deep as a database trigger). So in LightSwitch the first place one would look into to put this logic would be &lt;em&gt;EntityName&lt;/em&gt;_Inserting and &lt;em&gt;EntityName_&lt;/em&gt;Updating&amp;nbsp; partial methods that run on the server. Which is right, but causes concurrency issues, since after saving the client instance of the entity is not updated by the changes made at the server and as soon as you try to save again this will cause concurrency error.&lt;br /&gt;
So, what can you do, apart from refreshing after every save which is not very appealing? Update at the client. Not appealing either but at least it can be done elegantly:&lt;br /&gt;
Let’s say all entities to implement auditing have 4 fields:&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;DateCreated  &lt;/li&gt;
&lt;li&gt;CreatedBy  &lt;/li&gt;
&lt;li&gt;DateModified  &lt;/li&gt;
&lt;li&gt;ModifiedBy&lt;/li&gt;
&lt;/ul&gt;
Add to the Common project a new interface called &lt;strong&gt;IAuditable &lt;/strong&gt;like below:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;csharpcode&quot;&gt;&lt;span class=&quot;kwrd&quot;&gt;namespace&lt;/span&gt; LightSwitchApplication{
    &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;interface&lt;/span&gt; IAuditable{
        DateTime DateCreated { get; set; }
        &lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt; CreatedBy { get; set; }
        DateTime DateModified { get; set; }
        &lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt; ModifiedBy { get; set; }
    }
}
&lt;/pre&gt;
&lt;br /&gt;
&lt;style type=&quot;text/css&quot;&gt;
.csharpcode, .csharpcode pre&lt;br /&gt;{&lt;br /&gt; font-size: small;&lt;br /&gt; color: black;&lt;br /&gt; font-family: consolas, &quot;Courier New&quot;, courier, monospace;&lt;br /&gt; background-color: #ffffff;&lt;br /&gt; /*white-space: pre;*/&lt;br /&gt;}&lt;br /&gt;.csharpcode pre { margin: 0em; }&lt;br /&gt;.csharpcode .rem { color: #008000; }&lt;br /&gt;.csharpcode .kwrd { color: #0000ff; }&lt;br /&gt;.csharpcode .str { color: #006080; }&lt;br /&gt;.csharpcode .op { color: #0000c0; }&lt;br /&gt;.csharpcode .preproc { color: #cc6633; }&lt;br /&gt;.csharpcode .asp { background-color: #ffff00; }&lt;br /&gt;.csharpcode .html { color: #800000; }&lt;br /&gt;.csharpcode .attr { color: #ff0000; }&lt;br /&gt;.csharpcode .alt &lt;br /&gt;{&lt;br /&gt; background-color: #f4f4f4;&lt;br /&gt; width: 100%;&lt;br /&gt; margin: 0em;&lt;br /&gt;}&lt;br /&gt;.csharpcode .lnum { color: #606060; }&lt;br /&gt;
&lt;/style&gt;&lt;br /&gt;
&lt;br /&gt;
Then, also in the common project, add a new class called &lt;strong&gt;EntityExtensions:&lt;/strong&gt;&lt;br /&gt;
&lt;pre class=&quot;csharpcode&quot;&gt;&lt;span class=&quot;kwrd&quot;&gt;namespace&lt;/span&gt; LightSwitchApplication{
    &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;class&lt;/span&gt; EntityExtensions{
        &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;void&lt;/span&gt; Created&amp;lt;TEntityType&amp;gt;(&lt;span class=&quot;kwrd&quot;&gt;this&lt;/span&gt; TEntityType entity, IUser user)
           &lt;span class=&quot;kwrd&quot;&gt;where&lt;/span&gt; TEntityType: IAuditable{
           entity.DateCreated = entity.DateModified = DateTime.Now;
           entity.CreatedBy = enity.ModifiedBy = user.Name;
        }

        &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;void&lt;/span&gt; Modified&amp;lt;TEntityType&amp;gt;(&lt;span class=&quot;kwrd&quot;&gt;this&lt;/span&gt; TEntityType entity, IUser user)
           &lt;span class=&quot;kwrd&quot;&gt;where&lt;/span&gt; TEntityType: IAuditable{
           entity.DateModified = DateTime.Now;
           entity.ModifiedBy = user.Name;
        }
    }
}&lt;/pre&gt;
&lt;br /&gt;
&lt;style type=&quot;text/css&quot;&gt;
.csharpcode, .csharpcode pre&lt;br /&gt;{&lt;br /&gt; font-size: small;&lt;br /&gt; color: black;&lt;br /&gt; font-family: consolas, &quot;Courier New&quot;, courier, monospace;&lt;br /&gt; background-color: #ffffff;&lt;br /&gt; /*white-space: pre;*/&lt;br /&gt;}&lt;br /&gt;.csharpcode pre { margin: 0em; }&lt;br /&gt;.csharpcode .rem { color: #008000; }&lt;br /&gt;.csharpcode .kwrd { color: #0000ff; }&lt;br /&gt;.csharpcode .str { color: #006080; }&lt;br /&gt;.csharpcode .op { color: #0000c0; }&lt;br /&gt;.csharpcode .preproc { color: #cc6633; }&lt;br /&gt;.csharpcode .asp { background-color: #ffff00; }&lt;br /&gt;.csharpcode .html { color: #800000; }&lt;br /&gt;.csharpcode .attr { color: #ff0000; }&lt;br /&gt;.csharpcode .alt &lt;br /&gt;{&lt;br /&gt; background-color: #f4f4f4;&lt;br /&gt; width: 100%;&lt;br /&gt; margin: 0em;&lt;br /&gt;}&lt;br /&gt;.csharpcode .lnum { color: #606060; }&lt;br /&gt;
&lt;/style&gt;&lt;br /&gt;
&lt;br /&gt;
Now let’s suppose your entity’s name is &lt;strong&gt;Customer&lt;/strong&gt; (imagination was never my strong point), the screen’s name is &lt;strong&gt;CustomerList&lt;/strong&gt; and the query is called &lt;strong&gt;Customers&lt;/strong&gt;.&lt;br /&gt;
&lt;br /&gt;
First Viewing the Customer entity in designer click write code and make sure that:&lt;br /&gt;
&lt;pre class=&quot;csharpcode&quot;&gt;&lt;span class=&quot;kwrd&quot;&gt;partial&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;class&lt;/span&gt; Customer : IAuditable{
}&lt;/pre&gt;
&lt;br /&gt;
Then at your screen’s saving method write this:&lt;br /&gt;
&lt;pre class=&quot;csharpcode&quot;&gt;&lt;span class=&quot;kwrd&quot;&gt;partial&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;void&lt;/span&gt; CustomerList_Saving{
    &lt;span class=&quot;kwrd&quot;&gt;foreach&lt;/span&gt;(Customer customer &lt;span class=&quot;kwrd&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;this&lt;/span&gt;.DataworkSpace.ApplicationData.Details.GetChanges().AddedEntities.OfType&amp;lt;Customer&amp;gt;())
        customer.Created(&lt;span class=&quot;kwrd&quot;&gt;this&lt;/span&gt;.Application.User);
    &lt;span class=&quot;kwrd&quot;&gt;foreach&lt;/span&gt;(Customer customer &lt;span class=&quot;kwrd&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;this&lt;/span&gt;.DataworkSpace.ApplicationData.Details.GetChanges().ModifiedEntities.OfType&amp;lt;Customer&amp;gt;())
        customer.Modified(&lt;span class=&quot;kwrd&quot;&gt;this&lt;/span&gt;.Application.User);
}&lt;/pre&gt;
&lt;br /&gt;
&lt;style type=&quot;text/css&quot;&gt;
.csharpcode, .csharpcode pre&lt;br /&gt;{&lt;br /&gt; font-size: small;&lt;br /&gt; color: black;&lt;br /&gt; font-family: consolas, &quot;Courier New&quot;, courier, monospace;&lt;br /&gt; background-color: #ffffff;&lt;br /&gt; /*white-space: pre;*/&lt;br /&gt;}&lt;br /&gt;.csharpcode pre { margin: 0em; }&lt;br /&gt;.csharpcode .rem { color: #008000; }&lt;br /&gt;.csharpcode .kwrd { color: #0000ff; }&lt;br /&gt;.csharpcode .str { color: #006080; }&lt;br /&gt;.csharpcode .op { color: #0000c0; }&lt;br /&gt;.csharpcode .preproc { color: #cc6633; }&lt;br /&gt;.csharpcode .asp { background-color: #ffff00; }&lt;br /&gt;.csharpcode .html { color: #800000; }&lt;br /&gt;.csharpcode .attr { color: #ff0000; }&lt;br /&gt;.csharpcode .alt &lt;br /&gt;{&lt;br /&gt; background-color: #f4f4f4;&lt;br /&gt; width: 100%;&lt;br /&gt; margin: 0em;&lt;br /&gt;}&lt;br /&gt;.csharpcode .lnum { color: #606060; }&lt;br /&gt;
&lt;/style&gt;&lt;br /&gt;
This should do it. This way you can also easily move your logic to the server as the interface and extension class are defined in the Common project and they are also available to the server. &lt;br /&gt;
&lt;pre class=&quot;csharpcode&quot;&gt;&amp;nbsp;&lt;/pre&gt;
&lt;br /&gt;
&lt;style type=&quot;text/css&quot;&gt;
.csharpcode, .csharpcode pre&lt;br /&gt;{&lt;br /&gt; font-size: small;&lt;br /&gt; color: black;&lt;br /&gt; font-family: consolas, &quot;Courier New&quot;, courier, monospace;&lt;br /&gt; background-color: #ffffff;&lt;br /&gt; /*white-space: pre;*/&lt;br /&gt;}&lt;br /&gt;.csharpcode pre { margin: 0em; }&lt;br /&gt;.csharpcode .rem { color: #008000; }&lt;br /&gt;.csharpcode .kwrd { color: #0000ff; }&lt;br /&gt;.csharpcode .str { color: #006080; }&lt;br /&gt;.csharpcode .op { color: #0000c0; }&lt;br /&gt;.csharpcode .preproc { color: #cc6633; }&lt;br /&gt;.csharpcode .asp { background-color: #ffff00; }&lt;br /&gt;.csharpcode .html { color: #800000; }&lt;br /&gt;.csharpcode .attr { color: #ff0000; }&lt;br /&gt;.csharpcode .alt &lt;br /&gt;{&lt;br /&gt; background-color: #f4f4f4;&lt;br /&gt; width: 100%;&lt;br /&gt; margin: 0em;&lt;br /&gt;}&lt;br /&gt;.csharpcode .lnum { color: #606060; }&lt;br /&gt;
&lt;/style&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;style type=&quot;text/css&quot;&gt;
.csharpcode, .csharpcode pre&lt;br /&gt;{&lt;br /&gt; font-size: small;&lt;br /&gt; color: black;&lt;br /&gt; font-family: consolas, &quot;Courier New&quot;, courier, monospace;&lt;br /&gt; background-color: #ffffff;&lt;br /&gt; /*white-space: pre;*/&lt;br /&gt;}&lt;br /&gt;.csharpcode pre { margin: 0em; }&lt;br /&gt;.csharpcode .rem { color: #008000; }&lt;br /&gt;.csharpcode .kwrd { color: #0000ff; }&lt;br /&gt;.csharpcode .str { color: #006080; }&lt;br /&gt;.csharpcode .op { color: #0000c0; }&lt;br /&gt;.csharpcode .preproc { color: #cc6633; }&lt;br /&gt;.csharpcode .asp { background-color: #ffff00; }&lt;br /&gt;.csharpcode .html { color: #800000; }&lt;br /&gt;.csharpcode .attr { color: #ff0000; }&lt;br /&gt;.csharpcode .alt &lt;br /&gt;{&lt;br /&gt; background-color: #f4f4f4;&lt;br /&gt; width: 100%;&lt;br /&gt; margin: 0em;&lt;br /&gt;}&lt;br /&gt;.csharpcode .lnum { color: #606060; }&lt;br /&gt;
&lt;/style&gt;  &lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kostaschristodoulou.blogspot.com/feeds/330752930588182843/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kostaschristodoulou.blogspot.com/2011/11/in-msdn-forums-i-came-across-post_20.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1977783208088103440/posts/default/330752930588182843'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1977783208088103440/posts/default/330752930588182843'/><link rel='alternate' type='text/html' href='http://kostaschristodoulou.blogspot.com/2011/11/in-msdn-forums-i-came-across-post_20.html' title='Auditing and Concurrency don’t mix (easily)…'/><author><name>Kostas Christodoulou</name><uri>http://www.blogger.com/profile/07577025344678922877</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='29' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg-vpaqKzo9_w1Z5f97Dh74HcFctRHYFDWYNgNp35Gy2_84EvKNIZl57RAMvxB8JlsIic3iTrZ2Pv7D7leYIc_15MOo4Uh8hJI-4OF2Mv1G9-GYOCsOO_k7uxsAzbLxRNQ/s220/Me2.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1977783208088103440.post-1004792680133861533</id><published>2011-11-08T23:24:00.001+02:00</published><updated>2011-11-08T23:26:03.620+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Advanced"/><category scheme="http://www.blogger.com/atom/ns#" term="Extensions"/><category scheme="http://www.blogger.com/atom/ns#" term="Intermediate"/><category scheme="http://www.blogger.com/atom/ns#" term="Under the Hood"/><title type='text'>CLASS Extensions. Making of (the end)</title><content type='html'>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
If you have installed &lt;a href=&quot;http://visualstudiogallery.msdn.microsoft.com/dd5fe416-2186-490f-945c-9a387a94bed5&quot; target=&quot;_blank&quot;&gt;CLASS Extensions&lt;/a&gt; you know that there are two different controls that are used to handle Color business type. The ColorPicker and the ColorViewer. If you have read the &lt;a href=&quot;http://kostaschristodoulou.blogspot.com/2011/10/class-extensions-making-of-part-ii.html&quot; target=&quot;_blank&quot;&gt;previous post&lt;/a&gt; of the series you know that behind the scenes, each one of these controls is a wrapper for 2 other controls. The ColorPicker is for editing whereas ColorViewer is used for viewing only. The reason of exposing 2 different controls was that I didn’t manage to correctly retrieve the information about the content being read-only and changing dynamically the behavior of the controls.&lt;br /&gt;
If you browse the code you will see in &amp;lt;Control&amp;gt;_Load and other places (be kind, I was desperate) the attempt to bind to IsReadOnly property of the DataContext.&lt;br /&gt;
What I wanted to achieve was to support the “Use read-only controls” functionality. As I wrote in the previous post I was very close. I found out after publishing that the IsReadOnly property was set &lt;strong&gt;ONLY &lt;/strong&gt;when the field or the whole dataset was read-only, like a calculated field or a view-dataset (containing data from more than one source or directly mapped to a DB view). What I was looking for was a property I found out digging exhaustively down the Quick-Watch window, called …(drum-roll) &lt;strong&gt;IsBrowseOnly. &lt;/strong&gt;After discovering it and search back against the documentation, still didn’t manage to locate any reference to this property.&lt;br /&gt;
Anyway all well that ends well. Took me some time but as I mentioned in a &lt;a href=&quot;http://kostaschristodoulou.blogspot.com/2011/10/class-extensions-making-of-introduction.html&quot; target=&quot;_blank&quot;&gt;previous post&lt;/a&gt; of the series, I was prepared, given that documentation is far from being complete and definitely there is nothing like a complete Reference Guide, or maybe I am not good at reading it :-).&lt;br /&gt;
So, IsBrowseOnly binding, along with designer initial settings issues solved, and 3 new business types (Rating, AudioUri and VideoUri) will be included to the next version of CLASS extensions. Code will, most probably, not be published this time. So keep an eye open and stay tuned…&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjW-13f34AiAQ-jChafIn1DCTucorQknYIChC-_YiJI85uRGumH9fxzkDCa4DH7um5-T-R71k5qr6m2WEdVLoBFvD-MJpM83Nwxmif4DH6rk08OaODR7x2rfPqjTHZ6dlq2jqz57QWH_-m1//?imgmax=800&quot; imageanchor=&quot;1&quot;&gt;&lt;img alt=&quot;Winking smile&quot; border=&quot;0&quot; class=&quot;wlEmoticon wlEmoticon-winkingsmile&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjW-13f34AiAQ-jChafIn1DCTucorQknYIChC-_YiJI85uRGumH9fxzkDCa4DH7um5-T-R71k5qr6m2WEdVLoBFvD-MJpM83Nwxmif4DH6rk08OaODR7x2rfPqjTHZ6dlq2jqz57QWH_-m1//?imgmax=800&quot; style=&quot;border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none;&quot; /&gt;&lt;/a&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kostaschristodoulou.blogspot.com/feeds/1004792680133861533/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kostaschristodoulou.blogspot.com/2011/11/class-extensions-making-of-end_986.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1977783208088103440/posts/default/1004792680133861533'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1977783208088103440/posts/default/1004792680133861533'/><link rel='alternate' type='text/html' href='http://kostaschristodoulou.blogspot.com/2011/11/class-extensions-making-of-end_986.html' title='CLASS Extensions. Making of (the end)'/><author><name>Kostas Christodoulou</name><uri>http://www.blogger.com/profile/07577025344678922877</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='29' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg-vpaqKzo9_w1Z5f97Dh74HcFctRHYFDWYNgNp35Gy2_84EvKNIZl57RAMvxB8JlsIic3iTrZ2Pv7D7leYIc_15MOo4Uh8hJI-4OF2Mv1G9-GYOCsOO_k7uxsAzbLxRNQ/s220/Me2.jpg'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjW-13f34AiAQ-jChafIn1DCTucorQknYIChC-_YiJI85uRGumH9fxzkDCa4DH7um5-T-R71k5qr6m2WEdVLoBFvD-MJpM83Nwxmif4DH6rk08OaODR7x2rfPqjTHZ6dlq2jqz57QWH_-m1/s72-c/?imgmax=800" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1977783208088103440.post-2494127355857751345</id><published>2011-10-29T11:59:00.001+03:00</published><updated>2011-10-29T12:11:58.457+03:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Advanced"/><category scheme="http://www.blogger.com/atom/ns#" term="Business Types"/><category scheme="http://www.blogger.com/atom/ns#" term="Designer"/><category scheme="http://www.blogger.com/atom/ns#" term="Extensions"/><title type='text'>CLASS Extensions. Making of (Part II)</title><content type='html'>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
Crashing your LightSwitch project with your extensions is a piece of cake. The first simplest thing I did was change the business type to handle integer values instead of string ones. But I changed “&lt;em&gt;:String” &lt;/em&gt;to “&lt;em&gt;:Int”&lt;/em&gt;. That was enough to do it. It should be “&lt;em&gt;:Int32”.&lt;/em&gt;&lt;br /&gt;
So, after managing to create and use (declare as a type for an integer field in an entity) my business type, keeping my LightSwitch project in one piece, I had to work on my control. As I have already mentioned I had my custom control ready and tested, so, it should be easy.&lt;br /&gt;
I had used my custom control only in detail parts and although the expander used was “deforming” the layout when expanded (I have to fix this anyhow in the future) everything were going back to normal after collapsing the expander. This was not so for collections. Using my control in a grid the result after collapsing the color picker control was a grid row having a height of the expanded control. The reason is that the grid rows are auto-sized and have no specific height so…&lt;br /&gt;
I was only after having implemented a wrapper control to provide 2 different controls, one for collections and one for details, based on the reply by &lt;strong&gt;Justin Anderson&lt;/strong&gt; to a &lt;a href=&quot;http://social.msdn.microsoft.com/Forums/en-US/lsextensibility/thread/2b01dd43-5a5f-4275-9b87-973d141d7f9c&quot; target=&quot;_blank&quot;&gt;thread&lt;/a&gt; initially intended to help me handle read-only controls, that I got an &lt;a href=&quot;http://forums.silverlight.net/t/240017.aspx/1?Resize+DataGrid+row+back+to+normal&quot; target=&quot;_blank&quot;&gt;answer&lt;/a&gt; from Silverlight forum where I knew it was the right place to post my question. Either way, implementing what the reply suggested (although it works fine) required a lot of handling of transitions between expanded and collapsed. Also the “deform” in a grid when the control is expanded(even temporary) is, in my opinion, more annoying than in details.&lt;br /&gt;
&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;color: #0b5394; font-family: &#39;Courier New&#39;, Courier, monospace; font-size: x-small;&quot;&gt;if ((this.DataContext as IContentItem).ContainerState.HasFlag(ContainerState.Cell)) {&lt;br /&gt;&amp;nbsp; ColorControl control = new ColorControl();&lt;br /&gt;&amp;nbsp; control.DataContext = this.DataContext;&lt;br /&gt;&amp;nbsp; control.SetBinding(ColorControl.IsReadOnlyProperty, new Binding(&quot;IsReadOnly&quot;));&lt;br /&gt;&amp;nbsp; MainGrid.Children.Add(control);&lt;br /&gt;}&lt;br /&gt;else {&lt;br /&gt;&amp;nbsp; ColorPickerDrop control = new ColorPickerDrop();&lt;br /&gt;&amp;nbsp; control.DataContext = this.DataContext;&lt;br /&gt;&amp;nbsp; control.SetBinding(ColorPickerDrop.IsReadOnlyProperty, new Binding(&quot;IsReadOnly&quot;));&lt;br /&gt;&amp;nbsp; MainGrid.Children.Add(control);&lt;br /&gt;}  &lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
In the code above you can see selecting the control to “use” based on the &lt;strong&gt;ContainerState&lt;/strong&gt; property of the &lt;strong&gt;IContentItem&lt;/strong&gt; that is passed as &lt;strong&gt;DataContext.&lt;/strong&gt; You can also see the attempt to make the control read-only. My attempt was to make the controls automatically read-only when “&lt;strong&gt;Use read-only controls”&lt;/strong&gt; is checked from the designer. I was &lt;u&gt;that&lt;/u&gt; close… &lt;br /&gt;
Also for some reason my control when implemented in extension tended to take too much space by default. I had to change alignment to left/top by hand. It was only after releasing the first (and only one available until now) version that I managed to handle this along with other issues regarding designer behavior.&lt;br /&gt;
Hopefully before the end of 2011 I will be able to publish the next version, which contains also one more business type (rating) and respective control.&lt;br /&gt;
In the next post I will discuss the read-only issue that I didn’t manage to deal with in the published version…&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kostaschristodoulou.blogspot.com/feeds/2494127355857751345/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kostaschristodoulou.blogspot.com/2011/10/class-extensions-making-of-part-ii.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1977783208088103440/posts/default/2494127355857751345'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1977783208088103440/posts/default/2494127355857751345'/><link rel='alternate' type='text/html' href='http://kostaschristodoulou.blogspot.com/2011/10/class-extensions-making-of-part-ii.html' title='CLASS Extensions. Making of (Part II)'/><author><name>Kostas Christodoulou</name><uri>http://www.blogger.com/profile/07577025344678922877</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='29' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg-vpaqKzo9_w1Z5f97Dh74HcFctRHYFDWYNgNp35Gy2_84EvKNIZl57RAMvxB8JlsIic3iTrZ2Pv7D7leYIc_15MOo4Uh8hJI-4OF2Mv1G9-GYOCsOO_k7uxsAzbLxRNQ/s220/Me2.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1977783208088103440.post-4633252645491579933</id><published>2011-10-23T20:46:00.001+03:00</published><updated>2011-10-23T21:35:37.290+03:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Advanced"/><category scheme="http://www.blogger.com/atom/ns#" term="Extensions"/><category scheme="http://www.blogger.com/atom/ns#" term="Intermediate"/><title type='text'>CLASS Extensions. Making of (Part I)</title><content type='html'>&lt;div style=&quot;text-align: left&quot; dir=&quot;ltr&quot; trbidi=&quot;on&quot;&gt;I haven’t been able to post during the last week. It’s been a very hectic week and I didn’t have time or when I did have the time I didn’t have the courage…&lt;br&gt;Anyhow, I am going to share with you issues I had to face creating my first LightSwitch Extensions project.&lt;br&gt;First thing was to create the Color business type. I already had custom Silverlight control and value converters I had already published in a &lt;a href=&quot;http://code.msdn.microsoft.com/Managing-Custom-AddEdit-ab1c6b58&quot; target=&quot;_blank&quot;&gt;sample&lt;/a&gt; in MSDN’s LightSwitch Developer Center. So half of the work was done, right? Well, not quite…&lt;br&gt;I must say here that many of the problems were a result of the fact that editing the &lt;strong&gt;lsml &lt;/strong&gt;file is very error prone as there is nothing to help you while editing the file by hand. I mean it’s not like editing the XAML of a Silverlight control, with code completion, syntax checking and all the goodies. It’s raw XML editing. And the thing with errors in lsml is that the result is terrifying…a tag improperly closed crashes the universe. The LightSwitch test project becomes unloadable (screens and data sources disappear). Of course it’s only temporary since as soon as you fix the syntax or spelling error everything (no matter if the extension works as expected or not) comes back to normal. There are a few things I learned during the numerous (to say the least) trial and error editing-running-debugging cycles and I want to share. They are not advices they just that; sharing:&lt;br&gt; &lt;ul&gt; &lt;li&gt;When the above mentioned mess happens (the test project fails to load) the best thing to do is try to build. Most (not all, depending on the kind of error) of the times examining the error list bottom-up, you can deduce useful information about the origin of the error and where is the lsml is the error.  &lt;li&gt;Make small changes between testing cycles as this makes it, obviously, easier to locate any potential syntactical or spelling error. This is one of the most important rules of thumb I ended up with.  &lt;li&gt;Copy-paste-modify of &lt;strong&gt;correct&lt;/strong&gt; xml &lt;strong&gt;blocks&lt;/strong&gt; is the safest way to minimize syntactical and spelling errors. In general, I dislike copying blocks of code because I fill like I am using something I don’t understand, even if it’s not really so. But, in this case I ended up copying whole blocks of XML from the &lt;a href=&quot;http://msdn.microsoft.com/en-us/lightswitch/hh304488&quot; target=&quot;_blank&quot;&gt;How to&lt;/a&gt; articles and edit afterwards and it felt right…  &lt;li&gt;And one last practical thing. The procedure that worked better for me, regarding debugging the extensions was &lt;strong&gt;not&lt;/strong&gt; the &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/hh304424.aspx&quot; target=&quot;_blank&quot;&gt;one suggested&lt;/a&gt; and preconfigured when creating an extension project. I had various debugging issues I didn’t manage to identify and solve. Most probably it’s something I was doing wrong since the procedure described in the above link is used for all extensions of VS for quite some years. Anyhow, for what it might worth what I did was:  &lt;ol&gt; &lt;li&gt;I created a LightSwitch project in the same solution as the extension that used the extension.  &lt;li&gt;When I wanted to test a change, I was going to Extensions Manager and uninstall the extension. I closed the Extensions Manager (don’t press Restart Now, not now)  &lt;li&gt;Right click the &lt;strong&gt;vsix&lt;/strong&gt; project select build.  &lt;li&gt;After build right click and choose Open Folder in Windows Explorer. Install the package from the bin folder.  &lt;li&gt;Go back to Extensions Manager and choose Restart Now, now.&lt;/li&gt;&lt;/ol&gt;&lt;/li&gt;&lt;/ul&gt;I know these are more procedure details, rather than technical or implementation ones, but I wanted to share with anyone that might be interested. In the next post, which I hope I will write in the next couple of days, I will share more technical details like read-only, collection / details controls, handling nullable types.&lt;br&gt;I guess I have to change the subtitle of the blog from “&lt;em&gt;daily updated” &lt;/em&gt;to “&lt;em&gt;frequently updated”&lt;/em&gt;…&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjW-13f34AiAQ-jChafIn1DCTucorQknYIChC-_YiJI85uRGumH9fxzkDCa4DH7um5-T-R71k5qr6m2WEdVLoBFvD-MJpM83Nwxmif4DH6rk08OaODR7x2rfPqjTHZ6dlq2jqz57QWH_-m1//?imgmax=800&quot; imageanchor=&quot;1&quot;&gt;&lt;img style=&quot;border-bottom-style: none; border-right-style: none; border-top-style: none; border-left-style: none&quot; class=&quot;wlEmoticon wlEmoticon-winkingsmile&quot; border=&quot;0&quot; alt=&quot;Winking smile&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjW-13f34AiAQ-jChafIn1DCTucorQknYIChC-_YiJI85uRGumH9fxzkDCa4DH7um5-T-R71k5qr6m2WEdVLoBFvD-MJpM83Nwxmif4DH6rk08OaODR7x2rfPqjTHZ6dlq2jqz57QWH_-m1//?imgmax=800&quot;&gt;&lt;/a&gt;&lt;/div&gt;  </content><link rel='replies' type='application/atom+xml' href='http://kostaschristodoulou.blogspot.com/feeds/4633252645491579933/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kostaschristodoulou.blogspot.com/2011/10/class-extensions-making-of-part-i.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1977783208088103440/posts/default/4633252645491579933'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1977783208088103440/posts/default/4633252645491579933'/><link rel='alternate' type='text/html' href='http://kostaschristodoulou.blogspot.com/2011/10/class-extensions-making-of-part-i.html' title='CLASS Extensions. Making of (Part I)'/><author><name>Kostas Christodoulou</name><uri>http://www.blogger.com/profile/07577025344678922877</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='29' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg-vpaqKzo9_w1Z5f97Dh74HcFctRHYFDWYNgNp35Gy2_84EvKNIZl57RAMvxB8JlsIic3iTrZ2Pv7D7leYIc_15MOo4Uh8hJI-4OF2Mv1G9-GYOCsOO_k7uxsAzbLxRNQ/s220/Me2.jpg'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjW-13f34AiAQ-jChafIn1DCTucorQknYIChC-_YiJI85uRGumH9fxzkDCa4DH7um5-T-R71k5qr6m2WEdVLoBFvD-MJpM83Nwxmif4DH6rk08OaODR7x2rfPqjTHZ6dlq2jqz57QWH_-m1/s72-c/?imgmax=800" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1977783208088103440.post-92059028396362790</id><published>2011-10-16T11:24:00.001+03:00</published><updated>2011-10-16T11:57:20.572+03:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Advanced"/><category scheme="http://www.blogger.com/atom/ns#" term="Extensions"/><category scheme="http://www.blogger.com/atom/ns#" term="Intermediate"/><category scheme="http://www.blogger.com/atom/ns#" term="Learn"/><title type='text'>CLASS Extensions. Making of (the origins)</title><content type='html'>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
Did you know that the main reason I created CLASS Extensions was to make my life easier?&lt;br /&gt;
I had initially discarded LightSwitch from my deck of choices. At first glance (early Beta 1) I had misjudged it as poor relative of application builders that I hate altogether.&lt;br /&gt;
It was after watching Beth Massi’ s &lt;a href=&quot;http://channel9.msdn.com/Events/TechEd/NorthAmerica/2011/DEV354&quot; target=&quot;_blank&quot;&gt;presentation&lt;/a&gt; in Tech-Ed USA 2011 regarding &lt;strong&gt;extensibility&lt;/strong&gt; that made me take a second good look at it. And then…then it was love at second sight.&lt;br /&gt;
Although extensibility was what made me love LS, it took me quite some time to decide to write my own extension. I had custom controls I was using (the Color business type and editors is an example) and referenced libraries for a long time as I was really intimidated by the idea of creating an extension of my own. And it was only after the official release of Visual Studio LightSwitch that I even thought of doing it, as the &lt;a href=&quot;http://blogs.msdn.com/b/lightswitch/archive/2011/03/16/lightswitch-beta-2-extensibility-cookbook.aspx&quot; target=&quot;_blank&quot;&gt;Cookbook&lt;/a&gt;&amp;nbsp; and blank template approach was, to say the least, discouraging, at least for me. I knew I wasn’t the intended audience.&lt;br /&gt;
When I started the development of the first application, I &lt;strong&gt;knew&lt;/strong&gt; I had to write the extensions. Using the custom controls required so much duplication of logic mostly and code and was so restricting (as to how to name the members of the screens etc.) that made it unattainable to use them.&lt;br /&gt;
Just reading the &lt;a href=&quot;http://msdn.microsoft.com/en-us/lightswitch/hh304488&quot; target=&quot;_blank&quot;&gt;How to&lt;/a&gt; articles on extensibility it was obvious the path to follow was there but many things were to be discovered and solve down that path, the hard way. I mean, it’s not the most complete and well structured documentation, but a wealth of information is provided.&lt;br /&gt;
“Be a man” I said to myself and created my first extensibility project. Took me a lot of effort to even have this, preliminary in terms of quality and completeness, version released. But, as I said in the previous post, as soon as I replaced the first custom control with the respective extension control I knew it was all worth it…&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjW-13f34AiAQ-jChafIn1DCTucorQknYIChC-_YiJI85uRGumH9fxzkDCa4DH7um5-T-R71k5qr6m2WEdVLoBFvD-MJpM83Nwxmif4DH6rk08OaODR7x2rfPqjTHZ6dlq2jqz57QWH_-m1//?imgmax=800&quot; imageanchor=&quot;1&quot;&gt;&lt;img alt=&quot;Winking smile&quot; border=&quot;0&quot; class=&quot;wlEmoticon wlEmoticon-winkingsmile&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjW-13f34AiAQ-jChafIn1DCTucorQknYIChC-_YiJI85uRGumH9fxzkDCa4DH7um5-T-R71k5qr6m2WEdVLoBFvD-MJpM83Nwxmif4DH6rk08OaODR7x2rfPqjTHZ6dlq2jqz57QWH_-m1//?imgmax=800&quot; style=&quot;border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none;&quot; /&gt;&lt;/a&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kostaschristodoulou.blogspot.com/feeds/92059028396362790/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kostaschristodoulou.blogspot.com/2011/10/class-extensions-making-of-origins.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1977783208088103440/posts/default/92059028396362790'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1977783208088103440/posts/default/92059028396362790'/><link rel='alternate' type='text/html' href='http://kostaschristodoulou.blogspot.com/2011/10/class-extensions-making-of-origins.html' title='CLASS Extensions. Making of (the origins)'/><author><name>Kostas Christodoulou</name><uri>http://www.blogger.com/profile/07577025344678922877</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='29' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg-vpaqKzo9_w1Z5f97Dh74HcFctRHYFDWYNgNp35Gy2_84EvKNIZl57RAMvxB8JlsIic3iTrZ2Pv7D7leYIc_15MOo4Uh8hJI-4OF2Mv1G9-GYOCsOO_k7uxsAzbLxRNQ/s220/Me2.jpg'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjW-13f34AiAQ-jChafIn1DCTucorQknYIChC-_YiJI85uRGumH9fxzkDCa4DH7um5-T-R71k5qr6m2WEdVLoBFvD-MJpM83Nwxmif4DH6rk08OaODR7x2rfPqjTHZ6dlq2jqz57QWH_-m1/s72-c/?imgmax=800" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1977783208088103440.post-1937882931156228954</id><published>2011-10-13T22:50:00.001+03:00</published><updated>2011-10-14T14:17:22.020+03:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Advanced"/><category scheme="http://www.blogger.com/atom/ns#" term="Extensions"/><category scheme="http://www.blogger.com/atom/ns#" term="Intermediate"/><category scheme="http://www.blogger.com/atom/ns#" term="Learn"/><title type='text'>CLASS Extensions. Making of (Introduction)</title><content type='html'>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
Did you know that even for a simple extension there are numerous things the developer has to take into account?&lt;br /&gt;
I didn’t know it either until I decided to pack a few of the custom Silverlight controls and accompanying classes (like value converters) in &lt;a href=&quot;http://visualstudiogallery.msdn.microsoft.com/dd5fe416-2186-490f-945c-9a387a94bed5?SRC=Home&quot; target=&quot;_blank&quot;&gt;CLASS Extensions&lt;/a&gt;. Many details, from very simple like setting the image of the control to be displayed in the LightSwitch designer, to more complex like automatically using one control for collections (like in a grid) and another for details and setting default settings. I must say here that if it weren’t for the &lt;a href=&quot;http://social.msdn.microsoft.com/Forums/en-US/lsextensibility/threads&quot; target=&quot;_blank&quot;&gt;community&lt;/a&gt; and all the members being more than willing to help, it would have been impossible to manage (what I have managed anyway, as this first attempt is far from complete). &lt;br /&gt;
It was the first time in my developer live I felt I really needed two screens. One for reading the proper &lt;a href=&quot;http://msdn.microsoft.com/en-us/lightswitch/hh304488&quot; target=&quot;_blank&quot;&gt;LightSwitch extensibility How to&lt;/a&gt; article and one for the Visual Studio IDE to write code and XML. From these articles I managed to finally solve many of the issues reported in version 1.0 and will be included in the next version.&lt;br /&gt;
At the end of the day, I have to say that it was worth all the effort. Using extensions instead of custom controls and referenced libraries I had written and been using, is so much more productive that any time spent was paid back in just a few screens’ design time.&lt;br /&gt;
So, if you are hesitating to go through the process of learning how to write extensions, all I have to say is &lt;strong&gt;go for it!&lt;/strong&gt; And this is a &lt;u&gt;good&lt;/u&gt; tip…&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjW-13f34AiAQ-jChafIn1DCTucorQknYIChC-_YiJI85uRGumH9fxzkDCa4DH7um5-T-R71k5qr6m2WEdVLoBFvD-MJpM83Nwxmif4DH6rk08OaODR7x2rfPqjTHZ6dlq2jqz57QWH_-m1//?imgmax=800&quot; imageanchor=&quot;1&quot;&gt;&lt;img alt=&quot;Winking smile&quot; border=&quot;0&quot; class=&quot;wlEmoticon wlEmoticon-winkingsmile&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjW-13f34AiAQ-jChafIn1DCTucorQknYIChC-_YiJI85uRGumH9fxzkDCa4DH7um5-T-R71k5qr6m2WEdVLoBFvD-MJpM83Nwxmif4DH6rk08OaODR7x2rfPqjTHZ6dlq2jqz57QWH_-m1//?imgmax=800&quot; style=&quot;border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none;&quot; /&gt;&lt;/a&gt;&lt;br /&gt;
P.S. In upcoming posts I will talk&amp;nbsp; about the details of the implementation that i believe is worth sharing.&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kostaschristodoulou.blogspot.com/feeds/1937882931156228954/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kostaschristodoulou.blogspot.com/2011/10/class-extensions-making-of-introduction.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1977783208088103440/posts/default/1937882931156228954'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1977783208088103440/posts/default/1937882931156228954'/><link rel='alternate' type='text/html' href='http://kostaschristodoulou.blogspot.com/2011/10/class-extensions-making-of-introduction.html' title='CLASS Extensions. Making of (Introduction)'/><author><name>Kostas Christodoulou</name><uri>http://www.blogger.com/profile/07577025344678922877</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='29' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg-vpaqKzo9_w1Z5f97Dh74HcFctRHYFDWYNgNp35Gy2_84EvKNIZl57RAMvxB8JlsIic3iTrZ2Pv7D7leYIc_15MOo4Uh8hJI-4OF2Mv1G9-GYOCsOO_k7uxsAzbLxRNQ/s220/Me2.jpg'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjW-13f34AiAQ-jChafIn1DCTucorQknYIChC-_YiJI85uRGumH9fxzkDCa4DH7um5-T-R71k5qr6m2WEdVLoBFvD-MJpM83Nwxmif4DH6rk08OaODR7x2rfPqjTHZ6dlq2jqz57QWH_-m1/s72-c/?imgmax=800" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1977783208088103440.post-3158372548248483741</id><published>2011-10-12T14:34:00.002+03:00</published><updated>2011-10-12T16:41:38.852+03:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Beginner"/><category scheme="http://www.blogger.com/atom/ns#" term="Business Types"/><category scheme="http://www.blogger.com/atom/ns#" term="Extensions"/><category scheme="http://www.blogger.com/atom/ns#" term="Intermediate"/><title type='text'>CLASS Extensions</title><content type='html'>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
Did you know a new free extension for LightSwitch has been published in VS Gallery?&lt;br /&gt;
Of course not. How on earth could you know that? I had to keep the “Did you know” pattern though…&lt;img alt=&quot;Smile&quot; class=&quot;wlEmoticon wlEmoticon-smile&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjHkWaBqUZ3xlFjY5LaGOE7kxvMf-m2Wyxf2JrAdJTS68h3I_WieLhTPh70-u6GaBxr8FoXoNVfMs99uVRaR1KD0fb6HGHlrb_tYRFnW9hZnBkWZIwdvEON9Hv1T64JI2-DPT9b9ACuvA8P//?imgmax=800&quot; style=&quot;border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none;&quot; /&gt;.&lt;br /&gt;
The name is CLASS Extensions and you can download the extension either from Extension Manager of VS or from &lt;a href=&quot;http://visualstudiogallery.msdn.microsoft.com/dd5fe416-2186-490f-945c-9a387a94bed5&quot; target=&quot;_blank&quot;&gt;Visual Studio Gallery&lt;/a&gt;. &lt;br /&gt;
You can download the source code from &lt;a href=&quot;http://silverlight.adefwebserver.com/files/CLASSExtensions.zip&quot;&gt;here&lt;/a&gt;.&lt;br /&gt;
Feel free to ask questions either here or at the original &lt;a href=&quot;http://visualstudiogallery.msdn.microsoft.com/dd5fe416-2186-490f-945c-9a387a94bed5&quot; target=&quot;_blank&quot;&gt;Visual Studio Gallery&lt;/a&gt; contribution page.&lt;br /&gt;
Less boring than tips…&lt;img alt=&quot;Winking smile&quot; class=&quot;wlEmoticon wlEmoticon-winkingsmile&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgfaGmMg2NW9vjpG2DRzUrYXz75fQ0yvLApJqgs4Zt71TQlbz9uQwJS8m7c_KXQGO4wRsklygAhOLf7HWe5tjNjQEzSDBKZC8_sf_GQLWUicm2Fw7LTPm5HAvxrFnM6KsN8lJvUgtYsNKm_//?imgmax=800&quot; style=&quot;border-bottom-style: none; border-left-style: none; border-right-style: none; border-top-style: none;&quot; /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kostaschristodoulou.blogspot.com/feeds/3158372548248483741/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kostaschristodoulou.blogspot.com/2011/10/class-extensions.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1977783208088103440/posts/default/3158372548248483741'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1977783208088103440/posts/default/3158372548248483741'/><link rel='alternate' type='text/html' href='http://kostaschristodoulou.blogspot.com/2011/10/class-extensions.html' title='CLASS Extensions'/><author><name>Kostas Christodoulou</name><uri>http://www.blogger.com/profile/07577025344678922877</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='29' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg-vpaqKzo9_w1Z5f97Dh74HcFctRHYFDWYNgNp35Gy2_84EvKNIZl57RAMvxB8JlsIic3iTrZ2Pv7D7leYIc_15MOo4Uh8hJI-4OF2Mv1G9-GYOCsOO_k7uxsAzbLxRNQ/s220/Me2.jpg'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjHkWaBqUZ3xlFjY5LaGOE7kxvMf-m2Wyxf2JrAdJTS68h3I_WieLhTPh70-u6GaBxr8FoXoNVfMs99uVRaR1KD0fb6HGHlrb_tYRFnW9hZnBkWZIwdvEON9Hv1T64JI2-DPT9b9ACuvA8P/s72-c/?imgmax=800" height="72" width="72"/><thr:total>0</thr:total></entry></feed>