tag:blogger.com,1999:blog-67140642024-03-07T15:48:51.967-08:00Rnd() Thoughtsexperiences and thoughts about almost everythingChristian F.http://www.blogger.com/profile/02353730979008422628noreply@blogger.comBlogger112125tag:blogger.com,1999:blog-6714064.post-26254254540683658852015-09-25T05:42:00.001-07:002015-09-25T05:42:49.463-07:00Creating an Image Viewer In Xamarin.Forms with NControls<div style="-webkit-print-color-adjust: exact; background-color: white; font-family: Helvetica, arial, sans-serif; font-size: 14px; line-height: 22px; margin-bottom: 15px; margin-top: 15px;">
This blog post is about how to create custom controls within the Xamarin.Forms platform using the <a href="https://github.com/chrfalch/NControl" style="-webkit-print-color-adjust: exact; color: #4183c4;">NControl</a> library (which you can read more about <a href="http://chrfalch.blogspot.no/2015/03/ncontrol-cross-platform-custom-controls.html" style="-webkit-print-color-adjust: exact; color: #4183c4;">here</a>).</div>
<div style="-webkit-print-color-adjust: exact; background-color: white; font-family: Helvetica, arial, sans-serif; font-size: 14px; line-height: 22px; margin-bottom: 15px; margin-top: 15px;">
The scope for this article is to show how to create a control that supports simple scaling and panning (create gesture controls is something we'll save for later.) and has a bindable <code style="-webkit-print-color-adjust: exact; background-color: #f8f8f8; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(234, 234, 234); margin: 0px 2px; padding: 0px 5px; white-space: nowrap;">Source</code> property that can be used in a view to connect with an <code style="-webkit-print-color-adjust: exact; background-color: #f8f8f8; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(234, 234, 234); margin: 0px 2px; padding: 0px 5px; white-space: nowrap;">ImageSource</code>property in your viewmodel. </div>
<div style="-webkit-print-color-adjust: exact; background-color: white; font-family: Helvetica, arial, sans-serif; font-size: 14px; line-height: 22px; margin-bottom: 15px; margin-top: 15px;">
<strong style="-webkit-print-color-adjust: exact;">What we'll do in this blog post is:</strong></div>
<ul style="-webkit-print-color-adjust: exact; background-color: white; font-family: Helvetica, arial, sans-serif; font-size: 14px; line-height: 22px; margin: 15px 0px; padding-left: 30px;">
<li style="-webkit-print-color-adjust: exact; margin: 0px;">Create a new Cross Platform Xamarin.Forms project</li>
<li style="-webkit-print-color-adjust: exact; margin: 0px;">Install NControl from NuGet</li>
<li style="-webkit-print-color-adjust: exact; margin: 0px;">Create a new custom control (our Image Viewer control)</li>
<li style="-webkit-print-color-adjust: exact; margin: 0px;">Add a bindable property for the Image source property in our control</li>
<li style="-webkit-print-color-adjust: exact; margin: 0px;">Add an inner image in our control</li>
<li style="-webkit-print-color-adjust: exact; margin: 0px;">Handle touch events to add panning</li>
</ul>
<h2 id="toc_1" style="-webkit-font-smoothing: antialiased; -webkit-print-color-adjust: exact; background-color: white; border-bottom-color: rgb(204, 204, 204); border-bottom-style: solid; border-bottom-width: 1px; cursor: text; font-family: Helvetica, arial, sans-serif; font-size: 24px; margin: 20px 0px 10px; padding: 0px; position: relative;">
New Project</h2>
<div style="-webkit-print-color-adjust: exact; background-color: white; font-family: Helvetica, arial, sans-serif; font-size: 14px; line-height: 22px; margin-bottom: 15px; margin-top: 15px;">
Create a new Cross Platform App in Xamarin Studio by opening the <code style="-webkit-print-color-adjust: exact; background-color: #f8f8f8; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(234, 234, 234); margin: 0px 2px; padding: 0px 5px; white-space: nowrap;">File</code> <strong style="-webkit-print-color-adjust: exact;">></strong> <code style="-webkit-print-color-adjust: exact; background-color: #f8f8f8; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(234, 234, 234); margin: 0px 2px; padding: 0px 5px; white-space: nowrap;">New Solution</code> menu and follow the wizard so you end up with a solution containing an iOS, Android and shared project (and maybe a project for UI testing as well).</div>
<h3 id="toc_2" style="-webkit-font-smoothing: antialiased; -webkit-print-color-adjust: exact; background-color: white; cursor: text; font-family: Helvetica, arial, sans-serif; font-size: 18px; margin: 20px 0px 10px; padding: 0px; position: relative;">
NuGet Packages</h3>
<div style="-webkit-print-color-adjust: exact; background-color: white; font-family: Helvetica, arial, sans-serif; font-size: 14px; line-height: 22px; margin-bottom: 15px; margin-top: 15px;">
To build our control we need to add the NControl libraries using the NuGet package manager included in Xamarin Studio (I'll skip this part from this blog post) - make sure you install the NuGet package <a href="https://www.nuget.org/packages/NControl/" style="-webkit-print-color-adjust: exact; color: #4183c4;">NControl</a> in the Android, iOS and Shared PCL project.</div>
<div style="-webkit-print-color-adjust: exact; background-color: white; font-family: Helvetica, arial, sans-serif; font-size: 14px; line-height: 22px; margin-bottom: 15px; margin-top: 15px;">
Make sure you add the correct initialization of the library:</div>
<h4 id="toc_3" style="-webkit-font-smoothing: antialiased; -webkit-print-color-adjust: exact; background-color: white; cursor: text; font-family: Helvetica, arial, sans-serif; font-size: 16px; margin: 20px 0px 10px; padding: 0px; position: relative;">
Android</h4>
<div style="-webkit-print-color-adjust: exact; background-color: white; font-family: Helvetica, arial, sans-serif; font-size: 14px; line-height: 22px; margin-bottom: 15px; margin-top: 15px;">
In your <code style="-webkit-print-color-adjust: exact; background-color: #f8f8f8; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(234, 234, 234); margin: 0px 2px; padding: 0px 5px; white-space: nowrap;">MainActivity.cs</code> file:</div>
<pre class=" language-csharp" style="-webkit-hyphens: none; -webkit-print-color-adjust: exact; background-color: #f5f2f0; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(204, 204, 204); direction: ltr; font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace; font-size: 13px; line-height: 1.5; margin-bottom: 0.5em; margin-top: 0.5em; overflow: auto; padding: 1em; tab-size: 4; text-shadow: white 0px 1px; word-break: normal;"><code class=" language-csharp" style="-webkit-hyphens: none; -webkit-print-color-adjust: exact; background-color: transparent; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: none; direction: ltr; font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace; line-height: 1.5; margin: 0px; padding: 0px; tab-size: 4; text-shadow: white 0px 1px; word-break: normal; word-spacing: normal;"><span class="token keyword" style="-webkit-print-color-adjust: exact; color: #0077aa;">protected</span> <span class="token keyword" style="-webkit-print-color-adjust: exact; color: #0077aa;">override</span> <span class="token keyword" style="-webkit-print-color-adjust: exact; color: #0077aa;">void</span> OnCreate <span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">(</span>Bundle bundle<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">)</span>
<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">{</span>
<span class="token keyword" style="-webkit-print-color-adjust: exact; color: #0077aa;">base</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">.</span>OnCreate <span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">(</span>bundle<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">)</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">;</span>
<span class="token keyword" style="-webkit-print-color-adjust: exact; color: #0077aa;">global</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">:</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">:</span>Xamarin<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">.</span>Forms<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">.</span>Forms<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">.</span>Init <span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">(</span><span class="token keyword" style="-webkit-print-color-adjust: exact; color: #0077aa;">this</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">,</span> bundle<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">)</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">;</span>
NControlViewRenderer<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">.</span>Init <span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">(</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">)</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">;</span>
LoadApplication <span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">(</span><span class="token keyword" style="-webkit-print-color-adjust: exact; color: #0077aa;">new</span> <span class="token class-name" style="-webkit-print-color-adjust: exact;">App</span> <span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">(</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">)</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">)</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">;</span>
<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">}</span></code></pre>
<h4 id="toc_4" style="-webkit-font-smoothing: antialiased; -webkit-print-color-adjust: exact; background-color: white; cursor: text; font-family: Helvetica, arial, sans-serif; font-size: 16px; margin: 20px 0px 10px; padding: 0px; position: relative;">
iOS</h4>
<div style="-webkit-print-color-adjust: exact; background-color: white; font-family: Helvetica, arial, sans-serif; font-size: 14px; line-height: 22px; margin-bottom: 15px; margin-top: 15px;">
In your <code style="-webkit-print-color-adjust: exact; background-color: #f8f8f8; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(234, 234, 234); margin: 0px 2px; padding: 0px 5px; white-space: nowrap;">AppDelegate.cs</code> file</div>
<pre class=" language-csharp" style="-webkit-hyphens: none; -webkit-print-color-adjust: exact; background-color: #f5f2f0; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(204, 204, 204); direction: ltr; font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace; font-size: 13px; line-height: 1.5; margin-bottom: 0.5em; margin-top: 0.5em; overflow: auto; padding: 1em; tab-size: 4; text-shadow: white 0px 1px; word-break: normal;"><code class=" language-csharp" style="-webkit-hyphens: none; -webkit-print-color-adjust: exact; background-color: transparent; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: none; direction: ltr; font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace; line-height: 1.5; margin: 0px; padding: 0px; tab-size: 4; text-shadow: white 0px 1px; word-break: normal; word-spacing: normal;"><span class="token keyword" style="-webkit-print-color-adjust: exact; color: #0077aa;">public</span> <span class="token keyword" style="-webkit-print-color-adjust: exact; color: #0077aa;">override</span> <span class="token keyword" style="-webkit-print-color-adjust: exact; color: #0077aa;">bool</span> FinishedLaunching <span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">(</span>UIApplication app<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">,</span> NSDictionary options<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">)</span>
<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">{</span>
<span class="token keyword" style="-webkit-print-color-adjust: exact; color: #0077aa;">global</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">:</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">:</span>Xamarin<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">.</span>Forms<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">.</span>Forms<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">.</span>Init <span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">(</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">)</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">;</span>
NControlViewRenderer<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">.</span>Init <span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">(</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">)</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">;</span>
LoadApplication <span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">(</span><span class="token keyword" style="-webkit-print-color-adjust: exact; color: #0077aa;">new</span> <span class="token class-name" style="-webkit-print-color-adjust: exact;">App</span> <span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">(</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">)</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">)</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">;</span>
<span class="token keyword" style="-webkit-print-color-adjust: exact; color: #0077aa;">return</span> <span class="token keyword" style="-webkit-print-color-adjust: exact; color: #0077aa;">base</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">.</span>FinishedLaunching <span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">(</span>app<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">,</span> options<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">)</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">;</span>
<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">}</span></code></pre>
<blockquote style="-webkit-print-color-adjust: exact; background-color: white; border-left-color: rgb(221, 221, 221); border-left-style: solid; border-left-width: 4px; color: #777777; font-family: Helvetica, arial, sans-serif; font-size: 14px; line-height: 22px; margin: 15px 0px; padding: 0px 15px;">
<div style="-webkit-print-color-adjust: exact;">
Use the <code style="-webkit-print-color-adjust: exact; background-color: #f8f8f8; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(234, 234, 234); margin: 0px 2px; padding: 0px 5px; white-space: nowrap;">ALT+ENTER</code> keyboard shortcut to get Xamarin Studio to insert the correct using statements for the new lines you've added.</div>
</blockquote>
<h2 id="toc_5" style="-webkit-font-smoothing: antialiased; -webkit-print-color-adjust: exact; background-color: white; border-bottom-color: rgb(204, 204, 204); border-bottom-style: solid; border-bottom-width: 1px; cursor: text; font-family: Helvetica, arial, sans-serif; font-size: 24px; margin: 20px 0px 10px; padding: 0px; position: relative;">
Create a new Control</h2>
<div style="-webkit-print-color-adjust: exact; background-color: white; font-family: Helvetica, arial, sans-serif; font-size: 14px; line-height: 22px; margin-bottom: 15px; margin-top: 15px;">
Add a new class to your shared PCL project called ImageViewer.cs. This is the starting point for our container control. Make sure it inherits from NControlView:</div>
<pre class=" language-csharp" style="-webkit-hyphens: none; -webkit-print-color-adjust: exact; background-color: #f5f2f0; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(204, 204, 204); direction: ltr; font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace; font-size: 13px; line-height: 1.5; margin-bottom: 0.5em; margin-top: 0.5em; overflow: auto; padding: 1em; tab-size: 4; text-shadow: white 0px 1px; word-break: normal;"><code class=" language-csharp" style="-webkit-hyphens: none; -webkit-print-color-adjust: exact; background-color: transparent; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: none; direction: ltr; font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace; line-height: 1.5; margin: 0px; padding: 0px; tab-size: 4; text-shadow: white 0px 1px; word-break: normal; word-spacing: normal;"><span class="token keyword" style="-webkit-print-color-adjust: exact; color: #0077aa;">using</span> System<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">;</span>
<span class="token keyword" style="-webkit-print-color-adjust: exact; color: #0077aa;">using</span> NControl<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">.</span>Abstractions<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">;</span>
<span class="token keyword" style="-webkit-print-color-adjust: exact; color: #0077aa;">using</span> Xamarin<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">.</span>Forms<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">;</span>
<span class="token keyword" style="-webkit-print-color-adjust: exact; color: #0077aa;">using</span> System<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">.</span>Linq<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">;</span>
<span class="token keyword" style="-webkit-print-color-adjust: exact; color: #0077aa;">namespace</span> DraggableImageTest
<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">{</span>
<span class="token keyword" style="-webkit-print-color-adjust: exact; color: #0077aa;">public</span> <span class="token keyword" style="-webkit-print-color-adjust: exact; color: #0077aa;">class</span> <span class="token class-name" style="-webkit-print-color-adjust: exact;">ImageViewer</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">:</span> ContentView
<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">{</span>
<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">}</span>
<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">}</span></code></pre>
<h2 id="toc_6" style="-webkit-font-smoothing: antialiased; -webkit-print-color-adjust: exact; background-color: white; border-bottom-color: rgb(204, 204, 204); border-bottom-style: solid; border-bottom-width: 1px; cursor: text; font-family: Helvetica, arial, sans-serif; font-size: 24px; margin: 20px 0px 10px; padding: 0px; position: relative;">
Adding a Bindable Property</h2>
<div style="-webkit-print-color-adjust: exact; background-color: white; font-family: Helvetica, arial, sans-serif; font-size: 14px; line-height: 22px; margin-bottom: 15px; margin-top: 15px;">
Next up we need to give our control a property that can be bound to a view model to display images in the file <code style="-webkit-print-color-adjust: exact; background-color: #f8f8f8; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(234, 234, 234); margin: 0px 2px; padding: 0px 5px; white-space: nowrap;">ImageViewer.cs</code>:</div>
<pre class=" language-csharp" style="-webkit-hyphens: none; -webkit-print-color-adjust: exact; background-color: #f5f2f0; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(204, 204, 204); direction: ltr; font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace; font-size: 13px; line-height: 1.5; margin-bottom: 0.5em; margin-top: 0.5em; overflow: auto; padding: 1em; tab-size: 4; text-shadow: white 0px 1px; word-break: normal;"><code class=" language-csharp" style="-webkit-hyphens: none; -webkit-print-color-adjust: exact; background-color: transparent; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: none; direction: ltr; font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace; line-height: 1.5; margin: 0px; padding: 0px; tab-size: 4; text-shadow: white 0px 1px; word-break: normal; word-spacing: normal;"><span class="token keyword" style="-webkit-print-color-adjust: exact; color: #0077aa;">public</span> <span class="token keyword" style="-webkit-print-color-adjust: exact; color: #0077aa;">static</span> BindableProperty SourceProperty <span class="token operator" style="-webkit-print-color-adjust: exact; background-color: rgba(255, 255, 255, 0.498039); background-position: initial initial; background-repeat: initial initial; color: #a67f59;">=</span>
BindableProperty<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">.</span>Create<span class="token operator" style="-webkit-print-color-adjust: exact; background-color: rgba(255, 255, 255, 0.498039); background-position: initial initial; background-repeat: initial initial; color: #a67f59;"><</span>ImageViewer<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">,</span> ImageSource<span class="token operator" style="-webkit-print-color-adjust: exact; background-color: rgba(255, 255, 255, 0.498039); background-position: initial initial; background-repeat: initial initial; color: #a67f59;">></span> <span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">(</span>p <span class="token operator" style="-webkit-print-color-adjust: exact; background-color: rgba(255, 255, 255, 0.498039); background-position: initial initial; background-repeat: initial initial; color: #a67f59;">=</span><span class="token operator" style="-webkit-print-color-adjust: exact; background-color: rgba(255, 255, 255, 0.498039); background-position: initial initial; background-repeat: initial initial; color: #a67f59;">></span> p<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">.</span>Source<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">,</span> <span class="token keyword" style="-webkit-print-color-adjust: exact; color: #0077aa;">null</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">,</span>
BindingMode<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">.</span>TwoWay<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">,</span> propertyChanged<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">:</span> <span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">(</span>bindable<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">,</span> oldValue<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">,</span> newValue<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">)</span> <span class="token operator" style="-webkit-print-color-adjust: exact; background-color: rgba(255, 255, 255, 0.498039); background-position: initial initial; background-repeat: initial initial; color: #a67f59;">=</span><span class="token operator" style="-webkit-print-color-adjust: exact; background-color: rgba(255, 255, 255, 0.498039); background-position: initial initial; background-repeat: initial initial; color: #a67f59;">></span> <span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">{</span>
<span class="token keyword" style="-webkit-print-color-adjust: exact; color: #0077aa;">var</span> ctrl <span class="token operator" style="-webkit-print-color-adjust: exact; background-color: rgba(255, 255, 255, 0.498039); background-position: initial initial; background-repeat: initial initial; color: #a67f59;">=</span> <span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">(</span>ImageViewer<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">)</span>bindable<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">;</span>
ctrl<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">.</span>Source <span class="token operator" style="-webkit-print-color-adjust: exact; background-color: rgba(255, 255, 255, 0.498039); background-position: initial initial; background-repeat: initial initial; color: #a67f59;">=</span> newValue<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">;</span>
<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">}</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">)</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">;</span>
<span class="token keyword" style="-webkit-print-color-adjust: exact; color: #0077aa;">public</span> ImageSource Source <span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">{</span>
<span class="token keyword" style="-webkit-print-color-adjust: exact; color: #0077aa;">get</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">{</span> <span class="token keyword" style="-webkit-print-color-adjust: exact; color: #0077aa;">return</span> <span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">(</span>ImageSource<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">)</span>GetValue <span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">(</span>SourceProperty<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">)</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">;</span> <span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">}</span>
<span class="token keyword" style="-webkit-print-color-adjust: exact; color: #0077aa;">set</span> <span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">{</span>
SetValue <span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">(</span>SourceProperty<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">,</span> <span class="token keyword" style="-webkit-print-color-adjust: exact; color: #0077aa;">value</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">)</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">;</span>
<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">}</span>
<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">}</span></code></pre>
<h2 id="toc_7" style="-webkit-font-smoothing: antialiased; -webkit-print-color-adjust: exact; background-color: white; border-bottom-color: rgb(204, 204, 204); border-bottom-style: solid; border-bottom-width: 1px; cursor: text; font-family: Helvetica, arial, sans-serif; font-size: 24px; margin: 20px 0px 10px; padding: 0px; position: relative;">
Adding a Test Image</h2>
<div style="-webkit-print-color-adjust: exact; background-color: white; font-family: Helvetica, arial, sans-serif; font-size: 14px; line-height: 22px; margin-bottom: 15px; margin-top: 15px;">
No lets add an image for testing! Find your favourite image and add it to the PCL project. Right-click on the file and set <code style="-webkit-print-color-adjust: exact; background-color: #f8f8f8; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(234, 234, 234); margin: 0px 2px; padding: 0px 5px; white-space: nowrap;">Build Action</code>to <code style="-webkit-print-color-adjust: exact; background-color: #f8f8f8; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(234, 234, 234); margin: 0px 2px; padding: 0px 5px; white-space: nowrap;">EmbeddedResource</code>. This way the image will be included in the assembly as a resource you can load during runtime.</div>
<div style="-webkit-print-color-adjust: exact; background-color: white; font-family: Helvetica, arial, sans-serif; font-size: 14px; line-height: 22px; margin-bottom: 15px; margin-top: 15px;">
To be able to inspect and retreive a resource from our assembly we need to add the <code style="-webkit-print-color-adjust: exact; background-color: #f8f8f8; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(234, 234, 234); margin: 0px 2px; padding: 0px 5px; white-space: nowrap;">System.Reflection</code> namespace to our using list:</div>
<pre class=" language-csharp" style="-webkit-hyphens: none; -webkit-print-color-adjust: exact; background-color: #f5f2f0; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(204, 204, 204); direction: ltr; font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace; font-size: 13px; line-height: 1.5; margin-bottom: 0.5em; margin-top: 0.5em; overflow: auto; padding: 1em; tab-size: 4; text-shadow: white 0px 1px; word-break: normal;"><code class=" language-csharp" style="-webkit-hyphens: none; -webkit-print-color-adjust: exact; background-color: transparent; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: none; direction: ltr; font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace; line-height: 1.5; margin: 0px; padding: 0px; tab-size: 4; text-shadow: white 0px 1px; word-break: normal; word-spacing: normal;"><span class="token keyword" style="-webkit-print-color-adjust: exact; color: #0077aa;">using</span> System<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">.</span>Reflection<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">;</span></code></pre>
<div style="-webkit-print-color-adjust: exact; background-color: white; font-family: Helvetica, arial, sans-serif; font-size: 14px; line-height: 22px; margin-bottom: 15px; margin-top: 15px;">
Now lets update our main page to show our control. Open the startup file in your project (usually the csharp file in your PCL project with the same name as the project itself):</div>
<pre class=" language-csharp" style="-webkit-hyphens: none; -webkit-print-color-adjust: exact; background-color: #f5f2f0; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(204, 204, 204); direction: ltr; font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace; font-size: 13px; line-height: 1.5; margin-bottom: 0.5em; margin-top: 0.5em; overflow: auto; padding: 1em; tab-size: 4; text-shadow: white 0px 1px; word-break: normal;"><code class=" language-csharp" style="-webkit-hyphens: none; -webkit-print-color-adjust: exact; background-color: transparent; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: none; direction: ltr; font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace; line-height: 1.5; margin: 0px; padding: 0px; tab-size: 4; text-shadow: white 0px 1px; word-break: normal; word-spacing: normal;"><span class="token keyword" style="-webkit-print-color-adjust: exact; color: #0077aa;">public</span> App <span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">(</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">)</span>
<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">{</span>
<span class="token comment" spellcheck="true" style="-webkit-print-color-adjust: exact; color: slategrey;">// The root page of your application</span>
MainPage <span class="token operator" style="-webkit-print-color-adjust: exact; background-color: rgba(255, 255, 255, 0.498039); background-position: initial initial; background-repeat: initial initial; color: #a67f59;">=</span> <span class="token keyword" style="-webkit-print-color-adjust: exact; color: #0077aa;">new</span> <span class="token class-name" style="-webkit-print-color-adjust: exact;">ContentPage</span> <span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">{</span>
Content <span class="token operator" style="-webkit-print-color-adjust: exact; background-color: rgba(255, 255, 255, 0.498039); background-position: initial initial; background-repeat: initial initial; color: #a67f59;">=</span> <span class="token keyword" style="-webkit-print-color-adjust: exact; color: #0077aa;">new</span> <span class="token class-name" style="-webkit-print-color-adjust: exact;">StackLayout</span> <span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">{</span>
VerticalOptions <span class="token operator" style="-webkit-print-color-adjust: exact; background-color: rgba(255, 255, 255, 0.498039); background-position: initial initial; background-repeat: initial initial; color: #a67f59;">=</span> LayoutOptions<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">.</span>Center<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">,</span>
Children <span class="token operator" style="-webkit-print-color-adjust: exact; background-color: rgba(255, 255, 255, 0.498039); background-position: initial initial; background-repeat: initial initial; color: #a67f59;">=</span> <span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">{</span>
<span class="token keyword" style="-webkit-print-color-adjust: exact; color: #0077aa;">new</span> <span class="token class-name" style="-webkit-print-color-adjust: exact;">Label</span> <span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">{</span>
XAlign <span class="token operator" style="-webkit-print-color-adjust: exact; background-color: rgba(255, 255, 255, 0.498039); background-position: initial initial; background-repeat: initial initial; color: #a67f59;">=</span> TextAlignment<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">.</span>Center<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">,</span>
Text <span class="token operator" style="-webkit-print-color-adjust: exact; background-color: rgba(255, 255, 255, 0.498039); background-position: initial initial; background-repeat: initial initial; color: #a67f59;">=</span> <span class="token string" style="-webkit-print-color-adjust: exact; color: #669900;">"Image Container:"</span>
<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">}</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">,</span>
<span class="token keyword" style="-webkit-print-color-adjust: exact; color: #0077aa;">new</span> <span class="token class-name" style="-webkit-print-color-adjust: exact;">ContentView</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">{</span>
BackgroundColor <span class="token operator" style="-webkit-print-color-adjust: exact; background-color: rgba(255, 255, 255, 0.498039); background-position: initial initial; background-repeat: initial initial; color: #a67f59;">=</span> Color<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">.</span>Gray<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">,</span>
Padding <span class="token operator" style="-webkit-print-color-adjust: exact; background-color: rgba(255, 255, 255, 0.498039); background-position: initial initial; background-repeat: initial initial; color: #a67f59;">=</span> <span class="token number" style="-webkit-print-color-adjust: exact; color: #990055;">25</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">,</span>
HeightRequest <span class="token operator" style="-webkit-print-color-adjust: exact; background-color: rgba(255, 255, 255, 0.498039); background-position: initial initial; background-repeat: initial initial; color: #a67f59;">=</span> <span class="token number" style="-webkit-print-color-adjust: exact; color: #990055;">200</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">,</span>
Content <span class="token operator" style="-webkit-print-color-adjust: exact; background-color: rgba(255, 255, 255, 0.498039); background-position: initial initial; background-repeat: initial initial; color: #a67f59;">=</span> <span class="token keyword" style="-webkit-print-color-adjust: exact; color: #0077aa;">new</span> <span class="token class-name" style="-webkit-print-color-adjust: exact;">ImageViewer</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">{</span>
Source <span class="token operator" style="-webkit-print-color-adjust: exact; background-color: rgba(255, 255, 255, 0.498039); background-position: initial initial; background-repeat: initial initial; color: #a67f59;">=</span> ImageSource<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">.</span><span class="token function" style="-webkit-print-color-adjust: exact; color: #dd4a68;">FromStream</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">(</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">(</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">)</span> <span class="token operator" style="-webkit-print-color-adjust: exact; background-color: rgba(255, 255, 255, 0.498039); background-position: initial initial; background-repeat: initial initial; color: #a67f59;">=</span><span class="token operator" style="-webkit-print-color-adjust: exact; background-color: rgba(255, 255, 255, 0.498039); background-position: initial initial; background-repeat: initial initial; color: #a67f59;">></span> <span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">{</span>
<span class="token keyword" style="-webkit-print-color-adjust: exact; color: #0077aa;">var</span> assembly <span class="token operator" style="-webkit-print-color-adjust: exact; background-color: rgba(255, 255, 255, 0.498039); background-position: initial initial; background-repeat: initial initial; color: #a67f59;">=</span> <span class="token keyword" style="-webkit-print-color-adjust: exact; color: #0077aa;">this</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">.</span><span class="token function" style="-webkit-print-color-adjust: exact; color: #dd4a68;">GetType</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">(</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">)</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">.</span><span class="token function" style="-webkit-print-color-adjust: exact; color: #dd4a68;">GetTypeInfo</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">(</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">)</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">.</span>Assembly<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">;</span>
<span class="token keyword" style="-webkit-print-color-adjust: exact; color: #0077aa;">return</span> assembly<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">.</span>GetManifestResourceStream <span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">(</span><span class="token string" style="-webkit-print-color-adjust: exact; color: #669900;">"Your namespace.Your image filename"</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">)</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">;</span>
<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">}</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">)</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">,</span>
<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">}</span>
<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">}</span>
<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">}</span>
<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">}</span>
<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">}</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">;</span>
<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">}</span></code></pre>
<div style="-webkit-print-color-adjust: exact; background-color: white; font-family: Helvetica, arial, sans-serif; font-size: 14px; line-height: 22px; margin-bottom: 15px; margin-top: 15px;">
As you can see we're wrapping the image viewer in a <code style="-webkit-print-color-adjust: exact; background-color: #f8f8f8; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(234, 234, 234); margin: 0px 2px; padding: 0px 5px; white-space: nowrap;">ContentView</code> to enable some padding and color to make our control stand out. </div>
<blockquote style="-webkit-print-color-adjust: exact; background-color: white; border-left-color: rgb(221, 221, 221); border-left-style: solid; border-left-width: 4px; color: #777777; font-family: Helvetica, arial, sans-serif; font-size: 14px; line-height: 22px; margin: 15px 0px; padding: 0px 15px;">
<div style="-webkit-print-color-adjust: exact;">
Make sure you update the line with the code <code style="-webkit-print-color-adjust: exact; background-color: #f8f8f8; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(234, 234, 234); margin: 0px 2px; padding: 0px 5px; white-space: nowrap;">return assembly.GetManifestResourceStream ("Your namespace.Your image filename")</code> with your own namespace and filename.</div>
</blockquote>
<h2 id="toc_8" style="-webkit-font-smoothing: antialiased; -webkit-print-color-adjust: exact; background-color: white; border-bottom-color: rgb(204, 204, 204); border-bottom-style: solid; border-bottom-width: 1px; cursor: text; font-family: Helvetica, arial, sans-serif; font-size: 24px; margin: 20px 0px 10px; padding: 0px; position: relative;">
Add Inner Image Control</h2>
<div style="-webkit-print-color-adjust: exact; background-color: white; font-family: Helvetica, arial, sans-serif; font-size: 14px; line-height: 22px; margin-bottom: 15px; margin-top: 15px;">
To display an image and be able to move and scale it, we'll add an inner Image control in our ImageViewer control. Declare a private field in your <code style="-webkit-print-color-adjust: exact; background-color: #f8f8f8; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(234, 234, 234); margin: 0px 2px; padding: 0px 5px; white-space: nowrap;">ImageViewer</code> class:</div>
<pre class=" language-csharp" style="-webkit-hyphens: none; -webkit-print-color-adjust: exact; background-color: #f5f2f0; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(204, 204, 204); direction: ltr; font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace; font-size: 13px; line-height: 1.5; margin-bottom: 0.5em; margin-top: 0.5em; overflow: auto; padding: 1em; tab-size: 4; text-shadow: white 0px 1px; word-break: normal;"><code class=" language-csharp" style="-webkit-hyphens: none; -webkit-print-color-adjust: exact; background-color: transparent; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: none; direction: ltr; font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace; line-height: 1.5; margin: 0px; padding: 0px; tab-size: 4; text-shadow: white 0px 1px; word-break: normal; word-spacing: normal;"><span class="token keyword" style="-webkit-print-color-adjust: exact; color: #0077aa;">private</span> Image _image<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">;</span></code></pre>
<div style="-webkit-print-color-adjust: exact; background-color: white; font-family: Helvetica, arial, sans-serif; font-size: 14px; line-height: 22px; margin-bottom: 15px; margin-top: 15px;">
In the ImageViewer constructor we'll instantiate the Image view:</div>
<pre class=" language-csharp" style="-webkit-hyphens: none; -webkit-print-color-adjust: exact; background-color: #f5f2f0; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(204, 204, 204); direction: ltr; font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace; font-size: 13px; line-height: 1.5; margin-bottom: 0.5em; margin-top: 0.5em; overflow: auto; padding: 1em; tab-size: 4; text-shadow: white 0px 1px; word-break: normal;"><code class=" language-csharp" style="-webkit-hyphens: none; -webkit-print-color-adjust: exact; background-color: transparent; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: none; direction: ltr; font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace; line-height: 1.5; margin: 0px; padding: 0px; tab-size: 4; text-shadow: white 0px 1px; word-break: normal; word-spacing: normal;"><span class="token keyword" style="-webkit-print-color-adjust: exact; color: #0077aa;">public</span> ImageViewer <span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">(</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">)</span>
<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">{</span>
IsClippedToBounds <span class="token operator" style="-webkit-print-color-adjust: exact; background-color: rgba(255, 255, 255, 0.498039); background-position: initial initial; background-repeat: initial initial; color: #a67f59;">=</span> <span class="token keyword" style="-webkit-print-color-adjust: exact; color: #0077aa;">true</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">;</span>
_image <span class="token operator" style="-webkit-print-color-adjust: exact; background-color: rgba(255, 255, 255, 0.498039); background-position: initial initial; background-repeat: initial initial; color: #a67f59;">=</span> <span class="token keyword" style="-webkit-print-color-adjust: exact; color: #0077aa;">new</span> <span class="token class-name" style="-webkit-print-color-adjust: exact;">Image</span> <span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">(</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">)</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">;</span>
_image<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">.</span>Scale <span class="token operator" style="-webkit-print-color-adjust: exact; background-color: rgba(255, 255, 255, 0.498039); background-position: initial initial; background-repeat: initial initial; color: #a67f59;">=</span> <span class="token number" style="-webkit-print-color-adjust: exact; color: #990055;">2.0</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">;</span>
_image<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">.</span>InputTransparent <span class="token operator" style="-webkit-print-color-adjust: exact; background-color: rgba(255, 255, 255, 0.498039); background-position: initial initial; background-repeat: initial initial; color: #a67f59;">=</span> <span class="token keyword" style="-webkit-print-color-adjust: exact; color: #0077aa;">true</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">;</span>
Content <span class="token operator" style="-webkit-print-color-adjust: exact; background-color: rgba(255, 255, 255, 0.498039); background-position: initial initial; background-repeat: initial initial; color: #a67f59;">=</span> _image<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">;</span>
<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">}</span></code></pre>
<blockquote style="-webkit-print-color-adjust: exact; background-color: white; border-left-color: rgb(221, 221, 221); border-left-style: solid; border-left-width: 4px; color: #777777; font-family: Helvetica, arial, sans-serif; font-size: 14px; line-height: 22px; margin: 15px 0px; padding: 0px 15px;">
<div style="-webkit-print-color-adjust: exact;">
The key to get the displayed image to scale and pan inside our viewport is to set the <code style="-webkit-print-color-adjust: exact; background-color: #f8f8f8; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(234, 234, 234); margin: 0px 2px; padding: 0px 5px; white-space: nowrap;">IsClippedToBounds</code> property of the ImageViewer control to true to hide everything outside our control's bounds.</div>
</blockquote>
<div style="-webkit-print-color-adjust: exact; background-color: white; font-family: Helvetica, arial, sans-serif; font-size: 14px; line-height: 22px; margin-bottom: 15px; margin-top: 15px;">
Update the setter for the Source property to update the Image view:</div>
<pre class=" language-csharp" style="-webkit-hyphens: none; -webkit-print-color-adjust: exact; background-color: #f5f2f0; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(204, 204, 204); direction: ltr; font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace; font-size: 13px; line-height: 1.5; margin-bottom: 0.5em; margin-top: 0.5em; overflow: auto; padding: 1em; tab-size: 4; text-shadow: white 0px 1px; word-break: normal;"><code class=" language-csharp" style="-webkit-hyphens: none; -webkit-print-color-adjust: exact; background-color: transparent; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: none; direction: ltr; font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace; line-height: 1.5; margin: 0px; padding: 0px; tab-size: 4; text-shadow: white 0px 1px; word-break: normal; word-spacing: normal;"><span class="token keyword" style="-webkit-print-color-adjust: exact; color: #0077aa;">public</span> ImageSource Source <span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">{</span>
<span class="token keyword" style="-webkit-print-color-adjust: exact; color: #0077aa;">get</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">{</span> <span class="token keyword" style="-webkit-print-color-adjust: exact; color: #0077aa;">return</span> <span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">(</span>ImageSource<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">)</span>GetValue <span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">(</span>SourceProperty<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">)</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">;</span> <span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">}</span>
<span class="token keyword" style="-webkit-print-color-adjust: exact; color: #0077aa;">set</span> <span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">{</span>
SetValue <span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">(</span>SourceProperty<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">,</span> <span class="token keyword" style="-webkit-print-color-adjust: exact; color: #0077aa;">value</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">)</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">;</span>
_image<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">.</span>Source <span class="token operator" style="-webkit-print-color-adjust: exact; background-color: rgba(255, 255, 255, 0.498039); background-position: initial initial; background-repeat: initial initial; color: #a67f59;">=</span> <span class="token keyword" style="-webkit-print-color-adjust: exact; color: #0077aa;">value</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">;</span>
<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">}</span>
<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">}</span></code></pre>
<div style="-webkit-print-color-adjust: exact; background-color: white; font-family: Helvetica, arial, sans-serif; font-size: 14px; line-height: 22px; margin-bottom: 15px; margin-top: 15px;">
Now you should be able to run the app and see if it shows your image zoomed in and inside your control's bounds.</div>
<h2 id="toc_9" style="-webkit-font-smoothing: antialiased; -webkit-print-color-adjust: exact; background-color: white; border-bottom-color: rgb(204, 204, 204); border-bottom-style: solid; border-bottom-width: 1px; cursor: text; font-family: Helvetica, arial, sans-serif; font-size: 24px; margin: 20px 0px 10px; padding: 0px; position: relative;">
Add Panning</h2>
<div style="-webkit-print-color-adjust: exact; background-color: white; font-family: Helvetica, arial, sans-serif; font-size: 14px; line-height: 22px; margin-bottom: 15px; margin-top: 15px;">
NControlView has support for touch handling, and as an exercise we'll add simple panning to our ImageViewer control.</div>
<div style="-webkit-print-color-adjust: exact; background-color: white; font-family: Helvetica, arial, sans-serif; font-size: 14px; line-height: 22px; margin-bottom: 15px; margin-top: 15px;">
Add a new field in the ImageViewer class that we can use to calculate deltas when handling touches:</div>
<pre class=" language-csharp" style="-webkit-hyphens: none; -webkit-print-color-adjust: exact; background-color: #f5f2f0; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(204, 204, 204); direction: ltr; font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace; font-size: 13px; line-height: 1.5; margin-bottom: 0.5em; margin-top: 0.5em; overflow: auto; padding: 1em; tab-size: 4; text-shadow: white 0px 1px; word-break: normal;"><code class=" language-csharp" style="-webkit-hyphens: none; -webkit-print-color-adjust: exact; background-color: transparent; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: none; direction: ltr; font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace; line-height: 1.5; margin: 0px; padding: 0px; tab-size: 4; text-shadow: white 0px 1px; word-break: normal; word-spacing: normal;"><span class="token keyword" style="-webkit-print-color-adjust: exact; color: #0077aa;">private</span> NGraphics<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">.</span>Point _startPoint<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">;</span></code></pre>
<div style="-webkit-print-color-adjust: exact; background-color: white; font-family: Helvetica, arial, sans-serif; font-size: 14px; line-height: 22px; margin-bottom: 15px; margin-top: 15px;">
Now override the <code style="-webkit-print-color-adjust: exact; background-color: #f8f8f8; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(234, 234, 234); margin: 0px 2px; padding: 0px 5px; white-space: nowrap;">TouchesBegan</code> method in the ImageViewer class to begin handling touches:</div>
<pre class=" language-csharp" style="-webkit-hyphens: none; -webkit-print-color-adjust: exact; background-color: #f5f2f0; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(204, 204, 204); direction: ltr; font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace; font-size: 13px; line-height: 1.5; margin-bottom: 0.5em; margin-top: 0.5em; overflow: auto; padding: 1em; tab-size: 4; text-shadow: white 0px 1px; word-break: normal;"><code class=" language-csharp" style="-webkit-hyphens: none; -webkit-print-color-adjust: exact; background-color: transparent; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: none; direction: ltr; font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace; line-height: 1.5; margin: 0px; padding: 0px; tab-size: 4; text-shadow: white 0px 1px; word-break: normal; word-spacing: normal;"><span class="token keyword" style="-webkit-print-color-adjust: exact; color: #0077aa;">public</span> <span class="token keyword" style="-webkit-print-color-adjust: exact; color: #0077aa;">override</span> <span class="token keyword" style="-webkit-print-color-adjust: exact; color: #0077aa;">bool</span> TouchesBegan <span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">(</span>System<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">.</span>Collections<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">.</span>Generic<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">.</span>IEnumerable<span class="token operator" style="-webkit-print-color-adjust: exact; background-color: rgba(255, 255, 255, 0.498039); background-position: initial initial; background-repeat: initial initial; color: #a67f59;"><</span>NGraphics<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">.</span>Point<span class="token operator" style="-webkit-print-color-adjust: exact; background-color: rgba(255, 255, 255, 0.498039); background-position: initial initial; background-repeat: initial initial; color: #a67f59;">></span> points<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">)</span>
<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">{</span>
_startPoint <span class="token operator" style="-webkit-print-color-adjust: exact; background-color: rgba(255, 255, 255, 0.498039); background-position: initial initial; background-repeat: initial initial; color: #a67f59;">=</span> points<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">.</span>FirstOrDefault <span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">(</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">)</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">;</span>
_startPoint<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">.</span>X <span class="token operator" style="-webkit-print-color-adjust: exact; background-color: rgba(255, 255, 255, 0.498039); background-position: initial initial; background-repeat: initial initial; color: #a67f59;">-</span><span class="token operator" style="-webkit-print-color-adjust: exact; background-color: rgba(255, 255, 255, 0.498039); background-position: initial initial; background-repeat: initial initial; color: #a67f59;">=</span> _image<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">.</span>TranslationX<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">;</span>
_startPoint<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">.</span>Y <span class="token operator" style="-webkit-print-color-adjust: exact; background-color: rgba(255, 255, 255, 0.498039); background-position: initial initial; background-repeat: initial initial; color: #a67f59;">-</span><span class="token operator" style="-webkit-print-color-adjust: exact; background-color: rgba(255, 255, 255, 0.498039); background-position: initial initial; background-repeat: initial initial; color: #a67f59;">=</span> _image<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">.</span>TranslationY<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">;</span>
<span class="token keyword" style="-webkit-print-color-adjust: exact; color: #0077aa;">return</span> <span class="token keyword" style="-webkit-print-color-adjust: exact; color: #0077aa;">true</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">;</span>
<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">}</span></code></pre>
<div style="-webkit-print-color-adjust: exact; background-color: white; font-family: Helvetica, arial, sans-serif; font-size: 14px; line-height: 22px; margin-bottom: 15px; margin-top: 15px;">
First of all we'll save the location when touches starts. Next we add the current translation for the image to be able to pan multiple times. Remember to return true in the TouchesBegan event to tell NControlView that you have handled the touch.</div>
<div style="-webkit-print-color-adjust: exact; background-color: white; font-family: Helvetica, arial, sans-serif; font-size: 14px; line-height: 22px; margin-bottom: 15px; margin-top: 15px;">
When touches moves on the screen, we'll just calculate the delta and update the image's translation:</div>
<pre class=" language-csharp" style="-webkit-hyphens: none; -webkit-print-color-adjust: exact; background-color: #f5f2f0; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(204, 204, 204); direction: ltr; font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace; font-size: 13px; line-height: 1.5; margin-bottom: 0.5em; margin-top: 0.5em; overflow: auto; padding: 1em; tab-size: 4; text-shadow: white 0px 1px; word-break: normal;"><code class=" language-csharp" style="-webkit-hyphens: none; -webkit-print-color-adjust: exact; background-color: transparent; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: none; direction: ltr; font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace; line-height: 1.5; margin: 0px; padding: 0px; tab-size: 4; text-shadow: white 0px 1px; word-break: normal; word-spacing: normal;"><span class="token keyword" style="-webkit-print-color-adjust: exact; color: #0077aa;">public</span> <span class="token keyword" style="-webkit-print-color-adjust: exact; color: #0077aa;">override</span> <span class="token keyword" style="-webkit-print-color-adjust: exact; color: #0077aa;">bool</span> TouchesMoved <span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">(</span>System<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">.</span>Collections<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">.</span>Generic<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">.</span>IEnumerable<span class="token operator" style="-webkit-print-color-adjust: exact; background-color: rgba(255, 255, 255, 0.498039); background-position: initial initial; background-repeat: initial initial; color: #a67f59;"><</span>NGraphics<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">.</span>Point<span class="token operator" style="-webkit-print-color-adjust: exact; background-color: rgba(255, 255, 255, 0.498039); background-position: initial initial; background-repeat: initial initial; color: #a67f59;">></span> points<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">)</span>
<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">{</span>
<span class="token keyword" style="-webkit-print-color-adjust: exact; color: #0077aa;">var</span> newPoint <span class="token operator" style="-webkit-print-color-adjust: exact; background-color: rgba(255, 255, 255, 0.498039); background-position: initial initial; background-repeat: initial initial; color: #a67f59;">=</span> points<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">.</span>FirstOrDefault <span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">(</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">)</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">;</span>
<span class="token keyword" style="-webkit-print-color-adjust: exact; color: #0077aa;">var</span> diff <span class="token operator" style="-webkit-print-color-adjust: exact; background-color: rgba(255, 255, 255, 0.498039); background-position: initial initial; background-repeat: initial initial; color: #a67f59;">=</span> <span class="token keyword" style="-webkit-print-color-adjust: exact; color: #0077aa;">new</span> <span class="token class-name" style="-webkit-print-color-adjust: exact;">NGraphics<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">.</span>Point</span> <span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">(</span>newPoint<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">.</span>X <span class="token operator" style="-webkit-print-color-adjust: exact; background-color: rgba(255, 255, 255, 0.498039); background-position: initial initial; background-repeat: initial initial; color: #a67f59;">-</span> _startPoint<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">.</span>X<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">,</span> newPoint<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">.</span>Y <span class="token operator" style="-webkit-print-color-adjust: exact; background-color: rgba(255, 255, 255, 0.498039); background-position: initial initial; background-repeat: initial initial; color: #a67f59;">-</span> _startPoint<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">.</span>Y<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">)</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">;</span>
_image<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">.</span>TranslationX <span class="token operator" style="-webkit-print-color-adjust: exact; background-color: rgba(255, 255, 255, 0.498039); background-position: initial initial; background-repeat: initial initial; color: #a67f59;">=</span> diff<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">.</span>X<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">;</span>
_image<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">.</span>TranslationY <span class="token operator" style="-webkit-print-color-adjust: exact; background-color: rgba(255, 255, 255, 0.498039); background-position: initial initial; background-repeat: initial initial; color: #a67f59;">=</span> diff<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">.</span>Y<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">;</span>
<span class="token keyword" style="-webkit-print-color-adjust: exact; color: #0077aa;">return</span> <span class="token keyword" style="-webkit-print-color-adjust: exact; color: #0077aa;">true</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">;</span>
<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">}</span></code></pre>
<div style="-webkit-print-color-adjust: exact; background-color: white; font-family: Helvetica, arial, sans-serif; font-size: 14px; line-height: 22px; margin-bottom: 15px; margin-top: 15px;">
Read the current location, calculate the diff and update the image's translation. Easy?</div>
<div style="-webkit-print-color-adjust: exact; background-color: white; font-family: Helvetica, arial, sans-serif; font-size: 14px; line-height: 22px; margin-bottom: 15px; margin-top: 15px;">
Lastly we'll add TouchesCancelled and TouchesEnded as well:</div>
<pre class=" language-csharp" style="-webkit-hyphens: none; -webkit-print-color-adjust: exact; background-color: #f5f2f0; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(204, 204, 204); direction: ltr; font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace; font-size: 13px; line-height: 1.5; margin-bottom: 0.5em; margin-top: 0.5em; overflow: auto; padding: 1em; tab-size: 4; text-shadow: white 0px 1px; word-break: normal;"><code class=" language-csharp" style="-webkit-hyphens: none; -webkit-print-color-adjust: exact; background-color: transparent; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: none; direction: ltr; font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace; line-height: 1.5; margin: 0px; padding: 0px; tab-size: 4; text-shadow: white 0px 1px; word-break: normal; word-spacing: normal;"><span class="token keyword" style="-webkit-print-color-adjust: exact; color: #0077aa;">public</span> <span class="token keyword" style="-webkit-print-color-adjust: exact; color: #0077aa;">override</span> <span class="token keyword" style="-webkit-print-color-adjust: exact; color: #0077aa;">bool</span> TouchesCancelled <span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">(</span>System<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">.</span>Collections<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">.</span>Generic<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">.</span>IEnumerable<span class="token operator" style="-webkit-print-color-adjust: exact; background-color: rgba(255, 255, 255, 0.498039); background-position: initial initial; background-repeat: initial initial; color: #a67f59;"><</span>NGraphics<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">.</span>Point<span class="token operator" style="-webkit-print-color-adjust: exact; background-color: rgba(255, 255, 255, 0.498039); background-position: initial initial; background-repeat: initial initial; color: #a67f59;">></span> points<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">)</span>
<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">{</span>
<span class="token keyword" style="-webkit-print-color-adjust: exact; color: #0077aa;">return</span> <span class="token keyword" style="-webkit-print-color-adjust: exact; color: #0077aa;">true</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">;</span>
<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">}</span>
<span class="token keyword" style="-webkit-print-color-adjust: exact; color: #0077aa;">public</span> <span class="token keyword" style="-webkit-print-color-adjust: exact; color: #0077aa;">override</span> <span class="token keyword" style="-webkit-print-color-adjust: exact; color: #0077aa;">bool</span> TouchesEnded <span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">(</span>System<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">.</span>Collections<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">.</span>Generic<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">.</span>IEnumerable<span class="token operator" style="-webkit-print-color-adjust: exact; background-color: rgba(255, 255, 255, 0.498039); background-position: initial initial; background-repeat: initial initial; color: #a67f59;"><</span>NGraphics<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">.</span>Point<span class="token operator" style="-webkit-print-color-adjust: exact; background-color: rgba(255, 255, 255, 0.498039); background-position: initial initial; background-repeat: initial initial; color: #a67f59;">></span> points<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">)</span>
<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">{</span>
<span class="token keyword" style="-webkit-print-color-adjust: exact; color: #0077aa;">return</span> <span class="token keyword" style="-webkit-print-color-adjust: exact; color: #0077aa;">true</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">;</span>
<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">}</span></code></pre>
<div style="-webkit-print-color-adjust: exact; background-color: white; font-family: Helvetica, arial, sans-serif; font-size: 14px; line-height: 22px; margin-bottom: 15px; margin-top: 15px;">
Run the app and see if you can pan the image around.</div>
<h2 id="toc_10" style="-webkit-font-smoothing: antialiased; -webkit-print-color-adjust: exact; background-color: white; border-bottom-color: rgb(204, 204, 204); border-bottom-style: solid; border-bottom-width: 1px; cursor: text; font-family: Helvetica, arial, sans-serif; font-size: 24px; margin: 20px 0px 10px; padding: 0px; position: relative;">
Next Step</h2>
<div style="-webkit-print-color-adjust: exact; background-color: white; font-family: Helvetica, arial, sans-serif; font-size: 14px; line-height: 22px; margin-bottom: 15px; margin-top: 15px;">
The next step would be to create some kind of Gesture class where we can abstract away the inner logic of gestures to be able to implement zooming by pitching and double/tripple tapping to zoom in/out.</div>
<h2 id="toc_11" style="-webkit-font-smoothing: antialiased; -webkit-print-color-adjust: exact; background-color: white; border-bottom-color: rgb(204, 204, 204); border-bottom-style: solid; border-bottom-width: 1px; cursor: text; font-family: Helvetica, arial, sans-serif; font-size: 24px; margin: 20px 0px 10px; padding: 0px; position: relative;">
Code</h2>
<div style="-webkit-print-color-adjust: exact; background-color: white; font-family: Helvetica, arial, sans-serif; font-size: 14px; line-height: 22px; margin-bottom: 15px; margin-top: 15px;">
Download the code here: <a href="https://github.com/chrfalch/ImageViewTester" style="-webkit-print-color-adjust: exact; color: #4183c4;">https://github.com/chrfalch/ImageViewTester</a></div>
Christian F.http://www.blogger.com/profile/02353730979008422628noreply@blogger.com0tag:blogger.com,1999:blog-6714064.post-43742170815692942312015-09-01T01:55:00.000-07:002015-09-01T01:55:10.728-07:00Playing Sound in Xamarin.Forms<div style="-webkit-print-color-adjust: exact; background-color: white; color: #737373; font-family: 'Helvetica Neue', Helvetica, 'Hiragino Sans GB', Arial, sans-serif; font-size: 13px; line-height: 18px; margin-bottom: 9px; padding: 0px;">
<h1 id="toc_0" style="-webkit-font-smoothing: antialiased; -webkit-print-color-adjust: exact; background-color: white; cursor: text; font-family: Helvetica, arial, sans-serif; font-size: 28px; margin-bottom: 10px; margin-left: 0px; margin-right: 0px; margin-top: 0px !important; padding: 0px; position: relative;">
Background</h1>
<h1 id="toc_0" style="-webkit-font-smoothing: antialiased; -webkit-print-color-adjust: exact; background-color: white; cursor: text; font-family: Helvetica, arial, sans-serif; font-size: 28px; margin-bottom: 10px; margin-left: 0px; margin-right: 0px; margin-top: 0px !important; padding: 0px; position: relative;">
<div style="-webkit-print-color-adjust: exact; font-size: 14px; font-weight: normal; line-height: 22px; margin-bottom: 15px; margin-top: 15px;">
Xamarin.Forms does not have built-in way of playing sound, but it is easy to implement this using platform specific code on Android and iOS. This blog post describes how to build a project that implements a sound playing service with Xamarin.Forms.</div>
<div style="-webkit-print-color-adjust: exact; font-size: 14px; font-weight: normal; line-height: 22px; margin-bottom: 15px; margin-top: 15px;">
We'll begin this walkthrough with a new project in Xamarin Studio using the <em style="-webkit-print-color-adjust: exact;">Cross Platform App - Blank Xamarin.Forms App</em> template as a starting point. </div>
</h1>
<h2 id="toc_1" style="-webkit-font-smoothing: antialiased; -webkit-print-color-adjust: exact; background-color: white; border-bottom-color: rgb(204, 204, 204); border-bottom-style: solid; border-bottom-width: 1px; cursor: text; font-family: Helvetica, arial, sans-serif; font-size: 24px; margin: 20px 0px 10px; padding: 0px; position: relative;">
Code</h2>
<h1 style="-webkit-font-smoothing: antialiased; -webkit-print-color-adjust: exact; background-color: white; cursor: text; font-family: Helvetica, arial, sans-serif; font-size: 28px; margin-bottom: 10px; margin-left: 0px; margin-right: 0px; margin-top: 0px !important; padding: 0px; position: relative;">
<div style="-webkit-print-color-adjust: exact; font-size: 14px; font-weight: normal; line-height: 22px; margin-bottom: 15px; margin-top: 15px;">
First of all we'll have to define the interface that should be implemented in our platform projects. Add a new interface to the Forms project in your solution called ISoundProvider:</div>
<pre class=" language-csharp" style="-webkit-hyphens: none; -webkit-print-color-adjust: exact; background-color: #f5f2f0; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(204, 204, 204); direction: ltr; font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace; font-size: 13px; font-weight: normal; line-height: 1.5; margin-bottom: 0.5em; margin-top: 0.5em; overflow: auto; padding: 1em; tab-size: 4; text-shadow: white 0px 1px; word-break: normal;"><code class=" language-csharp" style="-webkit-hyphens: none; -webkit-print-color-adjust: exact; background-color: transparent; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: none; direction: ltr; font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace; line-height: 1.5; margin: 0px; padding: 0px; tab-size: 4; text-shadow: white 0px 1px; word-break: normal; word-spacing: normal;"><span class="token keyword" style="-webkit-print-color-adjust: exact; color: #0077aa;">public</span> <span class="token keyword" style="-webkit-print-color-adjust: exact; color: #0077aa;">interface</span> <span class="token class-name" style="-webkit-print-color-adjust: exact;">ISoundProvider</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">{</span>
<span class="token keyword" style="-webkit-print-color-adjust: exact; color: #0077aa;">public</span> Task <span class="token function" style="-webkit-print-color-adjust: exact; color: #dd4a68;">PlaySoundAsync</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">(</span><span class="token keyword" style="-webkit-print-color-adjust: exact; color: #0077aa;">string</span> filename<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">)</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">;</span>
<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">}</span></code></pre>
<blockquote style="-webkit-print-color-adjust: exact; border-left-color: rgb(221, 221, 221); border-left-style: solid; border-left-width: 4px; color: #777777; font-size: 14px; font-weight: normal; line-height: 22px; margin: 15px 0px; padding: 0px 15px;">
<div style="-webkit-print-color-adjust: exact;">
Remember that you can press <code style="-webkit-print-color-adjust: exact; background-color: #f8f8f8; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(234, 234, 234); margin: 0px 2px; padding: 0px 5px; white-space: nowrap;">ALT+ENTER</code> on classes that the Xamarin Studio editor doesn't know to bring up the refactoring dropdown that automatically inserts the correct using statements in your source file.*</div>
</blockquote>
<div style="-webkit-print-color-adjust: exact; font-size: 14px; font-weight: normal; line-height: 22px; margin-bottom: 15px; margin-top: 15px;">
Next lets create the abstraction class that will be used in the Xamarin.Forms app to play sound in our Forms project:</div>
<pre class=" language-csharp" style="-webkit-hyphens: none; -webkit-print-color-adjust: exact; background-color: #f5f2f0; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(204, 204, 204); direction: ltr; font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace; font-size: 13px; font-weight: normal; line-height: 1.5; margin-bottom: 0.5em; margin-top: 0.5em; overflow: auto; padding: 1em; tab-size: 4; text-shadow: white 0px 1px; word-break: normal;"><code class=" language-csharp" style="-webkit-hyphens: none; -webkit-print-color-adjust: exact; background-color: transparent; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: none; direction: ltr; font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace; line-height: 1.5; margin: 0px; padding: 0px; tab-size: 4; text-shadow: white 0px 1px; word-break: normal; word-spacing: normal;"><span class="token keyword" style="-webkit-print-color-adjust: exact; color: #0077aa;">public</span> <span class="token keyword" style="-webkit-print-color-adjust: exact; color: #0077aa;">class</span> <span class="token class-name" style="-webkit-print-color-adjust: exact;">SoundService</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">{</span>
<span class="token keyword" style="-webkit-print-color-adjust: exact; color: #0077aa;">private</span> <span class="token keyword" style="-webkit-print-color-adjust: exact; color: #0077aa;">readonly</span> ISoundProvider _soundProvider<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">;</span>
<span class="token keyword" style="-webkit-print-color-adjust: exact; color: #0077aa;">public</span> <span class="token function" style="-webkit-print-color-adjust: exact; color: #dd4a68;">SoundService</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">(</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">)</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">{</span>
<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">}</span>
<span class="token keyword" style="-webkit-print-color-adjust: exact; color: #0077aa;">public</span> <span class="token keyword" style="-webkit-print-color-adjust: exact; color: #0077aa;">async</span> Task <span class="token function" style="-webkit-print-color-adjust: exact; color: #dd4a68;">PlaySoundAsync</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">(</span><span class="token keyword" style="-webkit-print-color-adjust: exact; color: #0077aa;">string</span> filename<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">)</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">{</span>
<span class="token keyword" style="-webkit-print-color-adjust: exact; color: #0077aa;">return</span> _soundProvider<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">.</span><span class="token function" style="-webkit-print-color-adjust: exact; color: #dd4a68;">PlaySoundAsync</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">(</span>filename<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">)</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">;</span>
<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">}</span>
<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">}</span></code></pre>
<div style="-webkit-print-color-adjust: exact; font-size: 14px; font-weight: normal; line-height: 22px; margin-bottom: 15px; margin-top: 15px;">
We'll get back to how you look up the platform implementation to get an instance that you can assign to the <code style="-webkit-print-color-adjust: exact; background-color: #f8f8f8; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(234, 234, 234); margin: 0px 2px; padding: 0px 5px; white-space: nowrap;">_soundProvider</code>member.</div>
<div style="-webkit-print-color-adjust: exact; font-size: 14px; font-weight: normal; line-height: 22px; margin-bottom: 15px; margin-top: 15px;">
Now we should be ready to create the platform specific providers!</div>
</h1>
<h3 id="toc_2" style="-webkit-font-smoothing: antialiased; -webkit-print-color-adjust: exact; background-color: white; cursor: text; font-family: Helvetica, arial, sans-serif; font-size: 18px; margin: 20px 0px 10px; padding: 0px; position: relative;">
Android</h3>
<h1 style="-webkit-font-smoothing: antialiased; -webkit-print-color-adjust: exact; background-color: white; cursor: text; font-family: Helvetica, arial, sans-serif; font-size: 28px; margin-bottom: 10px; margin-left: 0px; margin-right: 0px; margin-top: 0px !important; padding: 0px; position: relative;">
<div style="-webkit-print-color-adjust: exact; font-size: 14px; font-weight: normal; line-height: 22px; margin-bottom: 15px; margin-top: 15px;">
Lets start with Android first - add the following code to your Droid project in a file called <code style="-webkit-print-color-adjust: exact; background-color: #f8f8f8; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(234, 234, 234); margin: 0px 2px; padding: 0px 5px; white-space: nowrap;">AndroidSoundProvider.cs</code>:</div>
<pre class=" language-csharp" style="-webkit-hyphens: none; -webkit-print-color-adjust: exact; background-color: #f5f2f0; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(204, 204, 204); direction: ltr; font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace; font-size: 13px; font-weight: normal; line-height: 1.5; margin-bottom: 0.5em; margin-top: 0.5em; overflow: auto; padding: 1em; tab-size: 4; text-shadow: white 0px 1px; word-break: normal;"><code class=" language-csharp" style="-webkit-hyphens: none; -webkit-print-color-adjust: exact; background-color: transparent; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: none; direction: ltr; font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace; line-height: 1.5; margin: 0px; padding: 0px; tab-size: 4; text-shadow: white 0px 1px; word-break: normal; word-spacing: normal;"><span class="token keyword" style="-webkit-print-color-adjust: exact; color: #0077aa;">public</span> <span class="token keyword" style="-webkit-print-color-adjust: exact; color: #0077aa;">class</span> <span class="token class-name" style="-webkit-print-color-adjust: exact;">AndroidSoundProvider</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">:</span> ISoundProvider
<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">{</span>
<span class="token keyword" style="-webkit-print-color-adjust: exact; color: #0077aa;">public</span> Task PlaySoundAsync <span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">(</span><span class="token keyword" style="-webkit-print-color-adjust: exact; color: #0077aa;">string</span> filename<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">)</span>
<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">{</span>
<span class="token comment" spellcheck="true" style="-webkit-print-color-adjust: exact; color: slategrey;">// Create media player</span>
<span class="token keyword" style="-webkit-print-color-adjust: exact; color: #0077aa;">var</span> player <span class="token operator" style="-webkit-print-color-adjust: exact; background-color: rgba(255, 255, 255, 0.498039); background-position: initial initial; background-repeat: initial initial; color: #a67f59;">=</span> <span class="token keyword" style="-webkit-print-color-adjust: exact; color: #0077aa;">new</span> <span class="token class-name" style="-webkit-print-color-adjust: exact;">MediaPlayer</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">(</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">)</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">;</span>
<span class="token comment" spellcheck="true" style="-webkit-print-color-adjust: exact; color: slategrey;">// Create task completion source to support async/await</span>
<span class="token keyword" style="-webkit-print-color-adjust: exact; color: #0077aa;">var</span> tcs <span class="token operator" style="-webkit-print-color-adjust: exact; background-color: rgba(255, 255, 255, 0.498039); background-position: initial initial; background-repeat: initial initial; color: #a67f59;">=</span> <span class="token keyword" style="-webkit-print-color-adjust: exact; color: #0077aa;">new</span> <span class="token class-name" style="-webkit-print-color-adjust: exact;">TaskCompletionSource</span><span class="token operator" style="-webkit-print-color-adjust: exact; background-color: rgba(255, 255, 255, 0.498039); background-position: initial initial; background-repeat: initial initial; color: #a67f59;"><</span><span class="token keyword" style="-webkit-print-color-adjust: exact; color: #0077aa;">bool</span><span class="token operator" style="-webkit-print-color-adjust: exact; background-color: rgba(255, 255, 255, 0.498039); background-position: initial initial; background-repeat: initial initial; color: #a67f59;">></span> <span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">(</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">)</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">;</span>
<span class="token comment" spellcheck="true" style="-webkit-print-color-adjust: exact; color: slategrey;">// Open the resource</span>
<span class="token keyword" style="-webkit-print-color-adjust: exact; color: #0077aa;">var</span> fd <span class="token operator" style="-webkit-print-color-adjust: exact; background-color: rgba(255, 255, 255, 0.498039); background-position: initial initial; background-repeat: initial initial; color: #a67f59;">=</span> Xamarin<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">.</span>Forms<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">.</span>Forms<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">.</span>Context<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">.</span>Assets<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">.</span>OpenFd <span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">(</span>filename<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">)</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">;</span>
<span class="token comment" spellcheck="true" style="-webkit-print-color-adjust: exact; color: slategrey;">// Hook up some events</span>
player<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">.</span>Prepared <span class="token operator" style="-webkit-print-color-adjust: exact; background-color: rgba(255, 255, 255, 0.498039); background-position: initial initial; background-repeat: initial initial; color: #a67f59;">+</span><span class="token operator" style="-webkit-print-color-adjust: exact; background-color: rgba(255, 255, 255, 0.498039); background-position: initial initial; background-repeat: initial initial; color: #a67f59;">=</span> <span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">(</span>s<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">,</span> e<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">)</span> <span class="token operator" style="-webkit-print-color-adjust: exact; background-color: rgba(255, 255, 255, 0.498039); background-position: initial initial; background-repeat: initial initial; color: #a67f59;">=</span><span class="token operator" style="-webkit-print-color-adjust: exact; background-color: rgba(255, 255, 255, 0.498039); background-position: initial initial; background-repeat: initial initial; color: #a67f59;">></span> <span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">{</span>
player<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">.</span><span class="token function" style="-webkit-print-color-adjust: exact; color: #dd4a68;">Start</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">(</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">)</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">;</span>
<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">}</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">;</span>
player<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">.</span>Completion <span class="token operator" style="-webkit-print-color-adjust: exact; background-color: rgba(255, 255, 255, 0.498039); background-position: initial initial; background-repeat: initial initial; color: #a67f59;">+</span><span class="token operator" style="-webkit-print-color-adjust: exact; background-color: rgba(255, 255, 255, 0.498039); background-position: initial initial; background-repeat: initial initial; color: #a67f59;">=</span> <span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">(</span>sender<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">,</span> e<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">)</span> <span class="token operator" style="-webkit-print-color-adjust: exact; background-color: rgba(255, 255, 255, 0.498039); background-position: initial initial; background-repeat: initial initial; color: #a67f59;">=</span><span class="token operator" style="-webkit-print-color-adjust: exact; background-color: rgba(255, 255, 255, 0.498039); background-position: initial initial; background-repeat: initial initial; color: #a67f59;">></span> <span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">{</span>
tcs<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">.</span><span class="token function" style="-webkit-print-color-adjust: exact; color: #dd4a68;">SetResult</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">(</span><span class="token keyword" style="-webkit-print-color-adjust: exact; color: #0077aa;">true</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">)</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">;</span>
<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">}</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">;</span>
<span class="token comment" spellcheck="true" style="-webkit-print-color-adjust: exact; color: slategrey;">// Start playing</span>
player<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">.</span>SetDataSource <span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">(</span>fd<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">.</span>FileDescriptor<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">)</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">;</span> player<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">.</span>Prepare <span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">(</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">)</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">;</span>
<span class="token keyword" style="-webkit-print-color-adjust: exact; color: #0077aa;">return</span> tcs<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">.</span>Task<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">;</span>
<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">}</span>
<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">}</span></code></pre>
<div style="-webkit-print-color-adjust: exact; font-size: 14px; font-weight: normal; line-height: 22px; margin-bottom: 15px; margin-top: 15px;">
As you can see we're using the async/await pattern in our little app to make it possible to play a sound and wait for it to return. This is done by creating a <code style="-webkit-print-color-adjust: exact; background-color: #f8f8f8; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(234, 234, 234); margin: 0px 2px; padding: 0px 5px; white-space: nowrap;">TaskCompletionSource</code> that can be used to signal back to the caller that we are done playing our sound. </div>
<div style="-webkit-print-color-adjust: exact; font-size: 14px; font-weight: normal; line-height: 22px; margin-bottom: 15px; margin-top: 15px;">
Since we'll be adding the sound file as an asset to our Android project, we're using the asset system in Android to load the file. After we've hooked up some events to be able mark the task as completed we'll set the data source and ask the player to prepare before we return the awaitable task object.</div>
</h1>
<h3 id="toc_3" style="-webkit-font-smoothing: antialiased; -webkit-print-color-adjust: exact; background-color: white; cursor: text; font-family: Helvetica, arial, sans-serif; font-size: 18px; margin: 20px 0px 10px; padding: 0px; position: relative;">
iOS</h3>
<h1 style="-webkit-font-smoothing: antialiased; -webkit-print-color-adjust: exact; background-color: white; cursor: text; font-family: Helvetica, arial, sans-serif; font-size: 28px; margin-bottom: 10px; margin-left: 0px; margin-right: 0px; margin-top: 0px !important; padding: 0px; position: relative;">
<div style="-webkit-print-color-adjust: exact; font-size: 14px; font-weight: normal; line-height: 22px; margin-bottom: 15px; margin-top: 15px;">
Next we'll create the iOS provider:</div>
<pre class=" language-csharp" style="-webkit-hyphens: none; -webkit-print-color-adjust: exact; background-color: #f5f2f0; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(204, 204, 204); direction: ltr; font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace; font-size: 13px; font-weight: normal; line-height: 1.5; margin-bottom: 0.5em; margin-top: 0.5em; overflow: auto; padding: 1em; tab-size: 4; text-shadow: white 0px 1px; word-break: normal;"><code class=" language-csharp" style="-webkit-hyphens: none; -webkit-print-color-adjust: exact; background-color: transparent; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: none; direction: ltr; font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace; line-height: 1.5; margin: 0px; padding: 0px; tab-size: 4; text-shadow: white 0px 1px; word-break: normal; word-spacing: normal;"><span class="token keyword" style="-webkit-print-color-adjust: exact; color: #0077aa;">public</span> <span class="token keyword" style="-webkit-print-color-adjust: exact; color: #0077aa;">class</span> <span class="token class-name" style="-webkit-print-color-adjust: exact;">TouchSoundProvider</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">:</span> NSObject<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">,</span> ISoundProvider
<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">{</span>
<span class="token keyword" style="-webkit-print-color-adjust: exact; color: #0077aa;">private</span> AVAudioPlayer _player<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">;</span>
<span class="token keyword" style="-webkit-print-color-adjust: exact; color: #0077aa;">public</span> Task PlaySoundAsync <span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">(</span><span class="token keyword" style="-webkit-print-color-adjust: exact; color: #0077aa;">string</span> filename<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">)</span>
<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">{</span>
<span class="token keyword" style="-webkit-print-color-adjust: exact; color: #0077aa;">var</span> tcs <span class="token operator" style="-webkit-print-color-adjust: exact; background-color: rgba(255, 255, 255, 0.498039); background-position: initial initial; background-repeat: initial initial; color: #a67f59;">=</span> <span class="token keyword" style="-webkit-print-color-adjust: exact; color: #0077aa;">new</span> <span class="token class-name" style="-webkit-print-color-adjust: exact;">TaskCompletionSource</span><span class="token operator" style="-webkit-print-color-adjust: exact; background-color: rgba(255, 255, 255, 0.498039); background-position: initial initial; background-repeat: initial initial; color: #a67f59;"><</span><span class="token keyword" style="-webkit-print-color-adjust: exact; color: #0077aa;">bool</span><span class="token operator" style="-webkit-print-color-adjust: exact; background-color: rgba(255, 255, 255, 0.498039); background-position: initial initial; background-repeat: initial initial; color: #a67f59;">></span> <span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">(</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">)</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">;</span>
<span class="token keyword" style="-webkit-print-color-adjust: exact; color: #0077aa;">string</span> path <span class="token operator" style="-webkit-print-color-adjust: exact; background-color: rgba(255, 255, 255, 0.498039); background-position: initial initial; background-repeat: initial initial; color: #a67f59;">=</span> NSBundle<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">.</span>MainBundle<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">.</span><span class="token function" style="-webkit-print-color-adjust: exact; color: #dd4a68;">PathForResource</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">(</span>Path<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">.</span><span class="token function" style="-webkit-print-color-adjust: exact; color: #dd4a68;">GetFileNameWithoutExtension</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">(</span>filename<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">)</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">,</span>
Path<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">.</span><span class="token function" style="-webkit-print-color-adjust: exact; color: #dd4a68;">GetExtension</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">(</span>filename<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">)</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">)</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">;</span>
<span class="token keyword" style="-webkit-print-color-adjust: exact; color: #0077aa;">var</span> url <span class="token operator" style="-webkit-print-color-adjust: exact; background-color: rgba(255, 255, 255, 0.498039); background-position: initial initial; background-repeat: initial initial; color: #a67f59;">=</span> NSUrl<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">.</span>FromString <span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">(</span>path<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">)</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">;</span>
_player <span class="token operator" style="-webkit-print-color-adjust: exact; background-color: rgba(255, 255, 255, 0.498039); background-position: initial initial; background-repeat: initial initial; color: #a67f59;">=</span> AVAudioPlayer<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">.</span><span class="token function" style="-webkit-print-color-adjust: exact; color: #dd4a68;">FromUrl</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">(</span>url<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">)</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">;</span>
_player<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">.</span>FinishedPlaying <span class="token operator" style="-webkit-print-color-adjust: exact; background-color: rgba(255, 255, 255, 0.498039); background-position: initial initial; background-repeat: initial initial; color: #a67f59;">+</span><span class="token operator" style="-webkit-print-color-adjust: exact; background-color: rgba(255, 255, 255, 0.498039); background-position: initial initial; background-repeat: initial initial; color: #a67f59;">=</span> <span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">(</span><span class="token keyword" style="-webkit-print-color-adjust: exact; color: #0077aa;">object</span> sender<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">,</span> AVStatusEventArgs e<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">)</span> <span class="token operator" style="-webkit-print-color-adjust: exact; background-color: rgba(255, 255, 255, 0.498039); background-position: initial initial; background-repeat: initial initial; color: #a67f59;">=</span><span class="token operator" style="-webkit-print-color-adjust: exact; background-color: rgba(255, 255, 255, 0.498039); background-position: initial initial; background-repeat: initial initial; color: #a67f59;">></span> <span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">{</span>
_player <span class="token operator" style="-webkit-print-color-adjust: exact; background-color: rgba(255, 255, 255, 0.498039); background-position: initial initial; background-repeat: initial initial; color: #a67f59;">=</span> <span class="token keyword" style="-webkit-print-color-adjust: exact; color: #0077aa;">null</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">;</span>
tcs<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">.</span><span class="token function" style="-webkit-print-color-adjust: exact; color: #dd4a68;">SetResult</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">(</span><span class="token keyword" style="-webkit-print-color-adjust: exact; color: #0077aa;">true</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">)</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">;</span>
<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">}</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">;</span>
_player<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">.</span><span class="token function" style="-webkit-print-color-adjust: exact; color: #dd4a68;">Play</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">(</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">)</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">;</span>
<span class="token keyword" style="-webkit-print-color-adjust: exact; color: #0077aa;">return</span> tcs<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">.</span>Task<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">;</span>
<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">}</span>
<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">}</span></code></pre>
<div style="-webkit-print-color-adjust: exact; font-size: 14px; font-weight: normal; line-height: 22px; margin-bottom: 15px; margin-top: 15px;">
This code is as you can see almost identical to the code on Android, except that we're using the iOS Frameworks to play the sound andthe iOS resource system to load the sound file.</div>
</h1>
<h3 id="toc_4" style="-webkit-font-smoothing: antialiased; -webkit-print-color-adjust: exact; background-color: white; cursor: text; font-family: Helvetica, arial, sans-serif; font-size: 18px; margin: 20px 0px 10px; padding: 0px; position: relative;">
Connecting the Dots</h3>
<h1 style="-webkit-font-smoothing: antialiased; -webkit-print-color-adjust: exact; background-color: white; cursor: text; font-family: Helvetica, arial, sans-serif; font-size: 28px; margin-bottom: 10px; margin-left: 0px; margin-right: 0px; margin-top: 0px !important; padding: 0px; position: relative;">
<div style="-webkit-print-color-adjust: exact; font-size: 14px; font-weight: normal; line-height: 22px; margin-bottom: 15px; margin-top: 15px;">
Now we need to tie these classes together. The abstract <code style="-webkit-print-color-adjust: exact; background-color: #f8f8f8; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(234, 234, 234); margin: 0px 2px; padding: 0px 5px; white-space: nowrap;">SoundService</code> class does not yet know about our platform specific implementations. In Xamarin.Forms we have access to a simple dependency service that helps us make platform specific classes defined by interfaces available through a lookup mechanism. </div>
<div style="-webkit-print-color-adjust: exact; font-size: 14px; font-weight: normal; line-height: 22px; margin-bottom: 15px; margin-top: 15px;">
To tell the dependency service that we have an implementations of the <code style="-webkit-print-color-adjust: exact; background-color: #f8f8f8; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(234, 234, 234); margin: 0px 2px; padding: 0px 5px; white-space: nowrap;">ISoundProvider</code> interface we add an assembly attribute to the classes in our platform projects:</div>
<div style="-webkit-print-color-adjust: exact; font-size: 14px; font-weight: normal; line-height: 22px; margin-bottom: 15px; margin-top: 15px;">
Add the following assembly attributes to Android implementations (above the namespace line):</div>
<div style="-webkit-print-color-adjust: exact; font-size: 14px; font-weight: normal; line-height: 22px; margin-bottom: 15px; margin-top: 15px;">
<code style="-webkit-print-color-adjust: exact; background-color: #f8f8f8; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(234, 234, 234); margin: 0px 2px; padding: 0px 5px; white-space: nowrap;">[assembly: Dependency (typeof (AndroidSoundProvider))]</code></div>
<div style="-webkit-print-color-adjust: exact; font-size: 14px; font-weight: normal; line-height: 22px; margin-bottom: 15px; margin-top: 15px;">
and to the iOS implementation:</div>
<div style="-webkit-print-color-adjust: exact; font-size: 14px; font-weight: normal; line-height: 22px; margin-bottom: 15px; margin-top: 15px;">
<code style="-webkit-print-color-adjust: exact; background-color: #f8f8f8; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(234, 234, 234); margin: 0px 2px; padding: 0px 5px; white-space: nowrap;">[assembly: Dependency (typeof (TouchSoundProvider))]</code></div>
<div style="-webkit-print-color-adjust: exact; font-size: 14px; font-weight: normal; line-height: 22px; margin-bottom: 15px; margin-top: 15px;">
Now we should be ready to use the classes through the dependecy service in Xamarin.Forms. Update the abstraction class constructor to:</div>
<pre class=" language-none" style="-webkit-hyphens: none; -webkit-print-color-adjust: exact; background-color: #f5f2f0; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(204, 204, 204); direction: ltr; font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace; font-size: 13px; font-weight: normal; line-height: 1.5; margin-bottom: 0.5em; margin-top: 0.5em; overflow: auto; padding: 1em; tab-size: 4; text-shadow: white 0px 1px; word-break: normal;"><code class=" language-none" style="-webkit-hyphens: none; -webkit-print-color-adjust: exact; background-color: transparent; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: none; direction: ltr; font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace; line-height: 1.5; margin: 0px; padding: 0px; tab-size: 4; text-shadow: white 0px 1px; word-break: normal; word-spacing: normal;">public SoundService(){
_soundProvider = DependencyService.Get<isoundprovider>();
}</isoundprovider></code></pre>
<blockquote style="-webkit-print-color-adjust: exact; border-left-color: rgb(221, 221, 221); border-left-style: solid; border-left-width: 4px; color: #777777; font-size: 14px; font-weight: normal; line-height: 22px; margin: 15px 0px; padding: 0px 15px;">
<div style="-webkit-print-color-adjust: exact;">
You can read more about the Xamarin Forms Dependency Service here: <a href="https://developer.xamarin.com/guides/cross-platform/xamarin-forms/dependency-service/" style="-webkit-print-color-adjust: exact; color: #4183c4;">https://developer.xamarin.com/guides/cross-platform/xamarin-forms/dependency-service/</a></div>
</blockquote>
</h1>
<h3 id="toc_5" style="-webkit-font-smoothing: antialiased; -webkit-print-color-adjust: exact; background-color: white; cursor: text; font-family: Helvetica, arial, sans-serif; font-size: 18px; margin: 20px 0px 10px; padding: 0px; position: relative;">
Adding the Sound Resources</h3>
<h1 style="-webkit-font-smoothing: antialiased; -webkit-print-color-adjust: exact; background-color: white; cursor: text; font-family: Helvetica, arial, sans-serif; font-size: 28px; margin-bottom: 10px; margin-left: 0px; margin-right: 0px; margin-top: 0px !important; padding: 0px; position: relative;">
<div style="-webkit-print-color-adjust: exact; font-size: 14px; font-weight: normal; line-height: 22px; margin-bottom: 15px; margin-top: 15px;">
There are different ways of adding the sound resources - in this sample I've decided to add them as native resources to the platform projects. </div>
<div style="-webkit-print-color-adjust: exact; font-size: 14px; font-weight: normal; line-height: 22px; margin-bottom: 15px; margin-top: 15px;">
On iOS you can add your sound file to the Resources folder - this will make the file a Bundle Resource (right-click on the sound file and ensure its build action is set to Bundle Resource). </div>
<div style="-webkit-print-color-adjust: exact; font-size: 14px; font-weight: normal; line-height: 22px; margin-bottom: 15px; margin-top: 15px;">
In your Android project you'll add the sound file to the Asset folder and right-click and set the build action to AndroidAsset.</div>
</h1>
<h3 id="toc_6" style="-webkit-font-smoothing: antialiased; -webkit-print-color-adjust: exact; background-color: white; cursor: text; font-family: Helvetica, arial, sans-serif; font-size: 18px; margin: 20px 0px 10px; padding: 0px; position: relative;">
Add a Button to Play the Sound</h3>
<h1 style="-webkit-font-smoothing: antialiased; -webkit-print-color-adjust: exact; background-color: white; cursor: text; font-family: Helvetica, arial, sans-serif; font-size: 28px; margin-bottom: 10px; margin-left: 0px; margin-right: 0px; margin-top: 0px !important; padding: 0px; position: relative;">
<div style="-webkit-print-color-adjust: exact; font-size: 14px; font-weight: normal; line-height: 22px; margin-bottom: 15px; margin-top: 15px;">
In your Forms project you can now add a button that lets you play the sound you added (in this example it is called <code style="-webkit-print-color-adjust: exact; background-color: #f8f8f8; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(234, 234, 234); margin: 0px 2px; padding: 0px 5px; white-space: nowrap;">sound.mp3</code>). Update your <code style="-webkit-print-color-adjust: exact; background-color: #f8f8f8; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(234, 234, 234); margin: 0px 2px; padding: 0px 5px; white-space: nowrap;">App</code> class' constructor to:</div>
<pre class=" language-csharp" style="-webkit-hyphens: none; -webkit-print-color-adjust: exact; background-color: #f5f2f0; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(204, 204, 204); direction: ltr; font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace; font-size: 13px; font-weight: normal; line-height: 1.5; margin-bottom: 0.5em; margin-top: 0.5em; overflow: auto; padding: 1em; tab-size: 4; text-shadow: white 0px 1px; word-break: normal;"><code class=" language-csharp" style="-webkit-hyphens: none; -webkit-print-color-adjust: exact; background-color: transparent; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: none; direction: ltr; font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace; line-height: 1.5; margin: 0px; padding: 0px; tab-size: 4; text-shadow: white 0px 1px; word-break: normal; word-spacing: normal;"><span class="token keyword" style="-webkit-print-color-adjust: exact; color: #0077aa;">public</span> App <span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">(</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">)</span>
<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">{</span>
<span class="token comment" spellcheck="true" style="-webkit-print-color-adjust: exact; color: slategrey;">// The root page of your application</span>
MainPage <span class="token operator" style="-webkit-print-color-adjust: exact; background-color: rgba(255, 255, 255, 0.498039); background-position: initial initial; background-repeat: initial initial; color: #a67f59;">=</span> <span class="token keyword" style="-webkit-print-color-adjust: exact; color: #0077aa;">new</span> <span class="token class-name" style="-webkit-print-color-adjust: exact;">ContentPage</span> <span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">{</span>
Content <span class="token operator" style="-webkit-print-color-adjust: exact; background-color: rgba(255, 255, 255, 0.498039); background-position: initial initial; background-repeat: initial initial; color: #a67f59;">=</span> <span class="token keyword" style="-webkit-print-color-adjust: exact; color: #0077aa;">new</span> <span class="token class-name" style="-webkit-print-color-adjust: exact;">StackLayout</span> <span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">{</span>
VerticalOptions <span class="token operator" style="-webkit-print-color-adjust: exact; background-color: rgba(255, 255, 255, 0.498039); background-position: initial initial; background-repeat: initial initial; color: #a67f59;">=</span> LayoutOptions<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">.</span>Center<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">,</span>
Children <span class="token operator" style="-webkit-print-color-adjust: exact; background-color: rgba(255, 255, 255, 0.498039); background-position: initial initial; background-repeat: initial initial; color: #a67f59;">=</span> <span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">{</span>
<span class="token keyword" style="-webkit-print-color-adjust: exact; color: #0077aa;">new</span> <span class="token class-name" style="-webkit-print-color-adjust: exact;">Label</span> <span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">{</span>
XAlign <span class="token operator" style="-webkit-print-color-adjust: exact; background-color: rgba(255, 255, 255, 0.498039); background-position: initial initial; background-repeat: initial initial; color: #a67f59;">=</span> TextAlignment<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">.</span>Center<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">,</span>
Text <span class="token operator" style="-webkit-print-color-adjust: exact; background-color: rgba(255, 255, 255, 0.498039); background-position: initial initial; background-repeat: initial initial; color: #a67f59;">=</span> <span class="token string" style="-webkit-print-color-adjust: exact; color: #669900;">"Click to play a sound!"</span>
<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">}</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">,</span>
<span class="token keyword" style="-webkit-print-color-adjust: exact; color: #0077aa;">new</span> <span class="token class-name" style="-webkit-print-color-adjust: exact;">Button</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">{</span>
Text <span class="token operator" style="-webkit-print-color-adjust: exact; background-color: rgba(255, 255, 255, 0.498039); background-position: initial initial; background-repeat: initial initial; color: #a67f59;">=</span> <span class="token string" style="-webkit-print-color-adjust: exact; color: #669900;">"Play"</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">,</span>
Command <span class="token operator" style="-webkit-print-color-adjust: exact; background-color: rgba(255, 255, 255, 0.498039); background-position: initial initial; background-repeat: initial initial; color: #a67f59;">=</span> <span class="token keyword" style="-webkit-print-color-adjust: exact; color: #0077aa;">new</span> <span class="token class-name" style="-webkit-print-color-adjust: exact;">Command</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">(</span><span class="token keyword" style="-webkit-print-color-adjust: exact; color: #0077aa;">async</span> <span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">(</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">)</span> <span class="token operator" style="-webkit-print-color-adjust: exact; background-color: rgba(255, 255, 255, 0.498039); background-position: initial initial; background-repeat: initial initial; color: #a67f59;">=</span><span class="token operator" style="-webkit-print-color-adjust: exact; background-color: rgba(255, 255, 255, 0.498039); background-position: initial initial; background-repeat: initial initial; color: #a67f59;">></span> <span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">{</span>
<span class="token keyword" style="-webkit-print-color-adjust: exact; color: #0077aa;">var</span> soundService <span class="token operator" style="-webkit-print-color-adjust: exact; background-color: rgba(255, 255, 255, 0.498039); background-position: initial initial; background-repeat: initial initial; color: #a67f59;">=</span> <span class="token keyword" style="-webkit-print-color-adjust: exact; color: #0077aa;">new</span> <span class="token class-name" style="-webkit-print-color-adjust: exact;">SoundService</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">(</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">)</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">;</span>
<span class="token keyword" style="-webkit-print-color-adjust: exact; color: #0077aa;">await</span> soundService<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">.</span><span class="token function" style="-webkit-print-color-adjust: exact; color: #dd4a68;">PlaySoundAsync</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">(</span><span class="token string" style="-webkit-print-color-adjust: exact; color: #669900;">"sound.mp3"</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">)</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">;</span>
<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">}</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">)</span>
<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">}</span>
<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">}</span>
<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">}</span>
<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">}</span><span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">;</span>
<span class="token punctuation" style="-webkit-print-color-adjust: exact; color: #999999;">}</span></code></pre>
<div style="-webkit-print-color-adjust: exact; font-size: 14px; font-weight: normal; line-height: 22px; margin-bottom: 15px; margin-top: 15px;">
Notice how the code uses a <code style="-webkit-print-color-adjust: exact; background-color: #f8f8f8; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(234, 234, 234); margin: 0px 2px; padding: 0px 5px; white-space: nowrap;">Command</code> to execute when the user taps the button, and how the command object supports the async/await pattern that we've already implemented in our code.</div>
<div style="-webkit-print-color-adjust: exact; font-size: 14px; font-weight: normal; line-height: 22px; margin-bottom: 15px; margin-top: 15px;">
Now run and test your apps - they should play your sound when you tap the play button!</div>
<div style="-webkit-print-color-adjust: exact; font-size: 14px; font-weight: normal; line-height: 22px; margin-bottom: 15px; margin-top: 15px;">
Full code can be downloaded from <a href="http://github.com/chrfalch/SoundPlayer" style="-webkit-print-color-adjust: exact; color: #4183c4;">Github</a>.</div>
</h1>
</div>
Christian F.http://www.blogger.com/profile/02353730979008422628noreply@blogger.com2tag:blogger.com,1999:blog-6714064.post-87797197490190141182015-08-21T02:40:00.000-07:002015-08-28T04:44:33.720-07:00Xamarin.Forms - Choosing the right architecture<div style="border: 0px; color: #4e5758; font-family: 'WeblySleek UI', 'Segoe UI', 'Helvetica Neue', Arial, sans-serif; font-size: 16px; line-height: 25px; margin-bottom: 0.8em; outline: 0px; padding: 0px; vertical-align: baseline;">
One of the biggest issues with writing cross platform apps using Xamarin.Forms is that it is hard to know where to start and how to establish good patterns that are scalable enough to support the full app lifecycle from development to maintenance and new feature requests.<br />
<br />
This blog post is based on some of the experiences I've had working with on different cross platform apps with Xamarin.Forms.<br />
<br />
One of the biggest problems when writing cross platform code that should work on multiple platforms is that you have to choose an architecture and some patterns and stick with them to avoid ending up with code that is hard to maintain and hard to extend with new features.<br />
<br />
The architecture and patterns you choose needs to be easy to understand and extensible enough to support future features.<br />
<br />
<b>Patterns</b><br />
My most important principle is to build n app based on loose coupling through dependency injection and then to use the service locator, messaging bus and mvvm patterns to implement the functionality and user experience.<br />
<br />
Combining this with unit testing enables me to develop new features quickly while keeping manual testing to a minimum.</div>
<div style="border: 0px; color: #4e5758; font-family: 'WeblySleek UI', 'Segoe UI', 'Helvetica Neue', Arial, sans-serif; font-size: 16px; line-height: 25px; margin-bottom: 0.8em; outline: 0px; padding: 0px; vertical-align: baseline;">
<span style="color: #4e5758; font-family: 'WeblySleek UI', 'Segoe UI', 'Helvetica Neue', Arial, sans-serif;">I'm using </span><a href="https://github.com/grumpydev/TinyIoC" rel="nofollow" style="border: 0px; color: #186ac1; font-family: inherit; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline;">TinyIoC</a><span style="color: #4e5758; font-family: 'WeblySleek UI', 'Segoe UI', 'Helvetica Neue', Arial, sans-serif;"> for both dependency injection and as our service locator container and Xamarin.Forms' MessagingCenter as my message bus.</span></div>
<div>
<span style="color: #4e5758; font-family: 'WeblySleek UI', 'Segoe UI', 'Helvetica Neue', Arial, sans-serif; font-size: 16px; line-height: 25px;">All dependencies on these components are abstracted through interfaces so that they can be swapped out if necessary.</span><span style="color: #4e5758; font-family: 'WeblySleek UI', 'Segoe UI', 'Helvetica Neue', Arial, sans-serif; font-size: 16px; line-height: 25px;"><br /></span><br />
<ul style="border: 0px; color: #4e5758; font-family: 'WeblySleek UI', 'Segoe UI', 'Helvetica Neue', Arial, sans-serif; font-size: 16px; line-height: 25px; list-style: circle; margin: 1em 0px 1em 3em; outline: 0px; padding: 0px; vertical-align: baseline;">
</ul>
<div style="border: 0px; color: #4e5758; font-family: 'WeblySleek UI', 'Segoe UI', 'Helvetica Neue', Arial, sans-serif; font-size: 16px; line-height: 25px; margin-bottom: 0.8em; outline: 0px; padding: 0px; vertical-align: baseline;">
<strong style="border: 0px; font-family: inherit; margin: 0px; padding: 0px;">Services for business logic</strong><br />
<span style="border: 0px; font-family: inherit; margin: 0px; padding: 0px;">As a rule of thumb I always write my business logic in service classes that can be configured and injected in my view models. These classes are also testable using a unit testing framework like </span><a href="http://www.nunit.org/" rel="nofollow" style="border: 0px; color: #186ac1; font-family: inherit; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline;">NUnit</a>.</div>
<ul style="border: 0px; color: #4e5758; font-family: 'WeblySleek UI', 'Segoe UI', 'Helvetica Neue', Arial, sans-serif; font-size: 16px; line-height: 25px; list-style: circle; margin: 1em 0px 1em 3em; outline: 0px; padding: 0px; vertical-align: baseline;">
</ul>
<div style="border: 0px; color: #4e5758; font-family: 'WeblySleek UI', 'Segoe UI', 'Helvetica Neue', Arial, sans-serif; font-size: 16px; line-height: 25px; margin-bottom: 0.8em; outline: 0px; padding: 0px; vertical-align: baseline;">
<strong style="border: 0px; font-family: inherit; margin: 0px; padding: 0px;">Server communication</strong><br />
Its common to have a dependency on a cloud service. Such a service is often exposed as a REST based API that can be accessed over HTTPS. Usually I wrap services like this into simple client classes that can communicate with the server and that can be used by my services (never use clients directly in your view models!).<br />
<br />
To accomplish this I use the <a href="https://www.nuget.org/packages/Microsoft.Net.Http" rel="nofollow" style="border: 0px; color: #186ac1; font-family: inherit; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline;">HttpClient</a> library from Microsoft with the <a href="https://github.com/paulcbetts/ModernHttpClient" rel="nofollow" style="border: 0px; color: #186ac1; font-family: inherit; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline;">modernhttpclient</a> NuGet package to get native speed and performance. For serialization I use <a href="http://www.newtonsoft.com/json" rel="nofollow" style="border: 0px; color: #186ac1; font-family: inherit; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline;">Newtonsoft Json</a>.</div>
<ul style="border: 0px; color: #4e5758; font-family: 'WeblySleek UI', 'Segoe UI', 'Helvetica Neue', Arial, sans-serif; font-size: 16px; line-height: 25px; list-style: circle; margin: 1em 0px 1em 3em; outline: 0px; padding: 0px; vertical-align: baseline;">
</ul>
<div style="border: 0px; color: #4e5758; font-family: 'WeblySleek UI', 'Segoe UI', 'Helvetica Neue', Arial, sans-serif; font-size: 16px; line-height: 25px; margin-bottom: 0.8em; outline: 0px; padding: 0px; vertical-align: baseline;">
<strong style="border: 0px; font-family: inherit; margin: 0px; padding: 0px;">Persistence</strong><br />
If you have the need for local storage there are many options. I'm using <a href="https://github.com/praeclarum/sqlite-net" rel="nofollow" style="border: 0px; color: #186ac1; font-family: inherit; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline;">SQLite.Net</a>/<a href="https://github.com/oysteinkrog/SQLite.Net-PCL" rel="nofollow" style="border: 0px; color: #186ac1; font-family: inherit; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline;">SQLite.Net Async</a> since it gives me full async/await support and a nice little ORM that can be used with c# classes. For simple storage needs you can always use a file based library.</div>
<div style="border: 0px; color: #4e5758; font-family: 'WeblySleek UI', 'Segoe UI', 'Helvetica Neue', Arial, sans-serif; font-size: 16px; line-height: 25px; margin-bottom: 0.8em; outline: 0px; padding: 0px; vertical-align: baseline;">
<strong style="border: 0px; font-family: inherit; margin: 0px; padding: 0px;">Localization</strong><br />
I'm using regular resx files for localization - these work as expected under Xamarin Studio. (you might need to create the localization project in Visual Studio, I've had some issues creating them in Xamarin.Studio - this might have changed by now).</div>
<ul style="border: 0px; color: #4e5758; font-family: 'WeblySleek UI', 'Segoe UI', 'Helvetica Neue', Arial, sans-serif; font-size: 16px; line-height: 25px; list-style: circle; margin: 1em 0px 1em 3em; outline: 0px; padding: 0px; vertical-align: baseline;">
</ul>
<div style="border: 0px; color: #4e5758; font-family: 'WeblySleek UI', 'Segoe UI', 'Helvetica Neue', Arial, sans-serif; font-size: 16px; line-height: 25px; margin-bottom: 0.8em; outline: 0px; padding: 0px; vertical-align: baseline;">
<strong style="border: 0px; font-family: inherit; margin: 0px; padding: 0px;">Binding it all together with Mvvm</strong><br />
<span style="border: 0px; font-family: inherit; margin: 0px; padding: 0px;">The <a href="https://en.wikipedia.org/wiki/Model_View_ViewModel">mvvm</a> pattern is my default choice for wiring up the business logic and the user interface in my apps. U</span>sing ViewModels that transforms data from my services to properties and commands in my view models makes it really easy to get the user experience right. Xamarin.Forms views supports data binding to the view model's properties and commands.</div>
<ul style="border: 0px; color: #4e5758; font-family: 'WeblySleek UI', 'Segoe UI', 'Helvetica Neue', Arial, sans-serif; font-size: 16px; line-height: 25px; list-style: circle; margin: 1em 0px 1em 3em; outline: 0px; padding: 0px; vertical-align: baseline;">
</ul>
<div style="border: 0px; color: #4e5758; font-family: 'WeblySleek UI', 'Segoe UI', 'Helvetica Neue', Arial, sans-serif; font-size: 16px; line-height: 25px; margin-bottom: 0.8em; outline: 0px; padding: 0px; vertical-align: baseline;">
<span style="border: 0px; font-family: inherit; font-style: oblique; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline;">There are several good Mvvm frameworks out there that can be recommended - I suggest you choose a small and simple one with source code.</span></div>
<div style="border: 0px; color: #4e5758; font-family: 'WeblySleek UI', 'Segoe UI', 'Helvetica Neue', Arial, sans-serif; font-size: 16px; line-height: 25px; margin-bottom: 0.8em; outline: 0px; padding: 0px; vertical-align: baseline;">
<strong style="border: 0px; font-family: inherit; margin: 0px; padding: 0px;">Custom UX</strong><br />
I almost always have the need for some custom UX in all the apps I'm working on. In Xamarin.Forms you have some excellent extension points called custom renderers that act as bindings between the abstracted and native user elements.<br />
<br />
If I have smaller needs like drawing some shapes and/or lines I usually add the <a href="https://github.com/chrfalch/NControl" rel="nofollow" style="border: 0px; color: #186ac1; font-family: inherit; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline;">NControl</a> library to my project. It lets me create custom controls using the <a href="https://github.com/praeclarum/NGraphics">NGraphics</a> abstraction layer. The NControls library is written and maintained by me, you can read more about it in a blog post <a href="http://chrfalch.blogspot.no/2015/03/ncontrol-cross-platform-custom-controls.html">here</a>.</div>
<ul style="border: 0px; color: #4e5758; font-family: 'WeblySleek UI', 'Segoe UI', 'Helvetica Neue', Arial, sans-serif; font-size: 16px; line-height: 25px; list-style: circle; margin: 1em 0px 1em 3em; outline: 0px; padding: 0px; vertical-align: baseline;">
</ul>
<div>
<span style="color: #4e5758; font-family: WeblySleek UI, Segoe UI, Helvetica Neue, Arial, sans-serif;"><span style="line-height: 25px;"><b>Analytics</b></span></span></div>
<div>
<span style="color: #4e5758; font-family: WeblySleek UI, Segoe UI, Helvetica Neue, Arial, sans-serif;"><span style="line-height: 25px;">To get knowledge about what your app's users are doing, you should use some kind of library for app analytics. If you can find a library that also handles exceptions and crash reports, you will thank yourself for being wise at an early stage - having stack traces and exception reports from your user's crashes helps finding solutions to strange errors. </span></span><br />
<span style="color: #4e5758; font-family: WeblySleek UI, Segoe UI, Helvetica Neue, Arial, sans-serif;"><span style="line-height: 25px;"><br /></span></span>
<span style="color: #4e5758; font-family: WeblySleek UI, Segoe UI, Helvetica Neue, Arial, sans-serif;"><span style="line-height: 25px;">Remember to create an abstraction layer for tracking and error reporting so that you can plug in your own favorite library.</span></span></div>
<div>
<span style="color: #4e5758; font-family: WeblySleek UI, Segoe UI, Helvetica Neue, Arial, sans-serif;"><span style="line-height: 25px;"><br /></span></span></div>
<div style="border: 0px; color: #4e5758; font-family: 'WeblySleek UI', 'Segoe UI', 'Helvetica Neue', Arial, sans-serif; font-size: 16px; line-height: 25px; margin-bottom: 0.8em; outline: 0px; padding: 0px; vertical-align: baseline;">
<strong style="border: 0px; font-family: inherit; margin: 0px; padding: 0px;">General tips</strong></div>
<ul style="border: 0px; color: #4e5758; font-family: 'WeblySleek UI', 'Segoe UI', 'Helvetica Neue', Arial, sans-serif; font-size: 16px; line-height: 25px; list-style: circle; margin: 1em 0px 0px 3em; outline: 0px; padding: 0px; vertical-align: baseline;">
<li style="border: 0px; font-family: inherit; list-style: disc !important; margin: 5px 0px; outline: 0px; padding: 0px; vertical-align: baseline;">Try to keep the level of customization at a minimum - it is expensive and time consuming and adds to your maintenance costs</li>
<li style="border: 0px; font-family: inherit; list-style: disc !important; margin: 5px 0px; outline: 0px; padding: 0px; vertical-align: baseline;">Follow your patterns - don't be tempted to write business logic in your view models or views</li>
<li style="border: 0px; font-family: inherit; list-style: disc !important; margin: 5px 0px; outline: 0px; padding: 0px; vertical-align: baseline;">Refactor often</li>
</ul>
<span style="color: #4e5758; font-family: 'WeblySleek UI', 'Segoe UI', 'Helvetica Neue', Arial, sans-serif; font-size: 16px; line-height: 25px;"><div>
<span style="color: #4e5758; font-family: 'WeblySleek UI', 'Segoe UI', 'Helvetica Neue', Arial, sans-serif; font-size: 16px; line-height: 25px;"><br /></span></div>
Know your platforms - nothing beats having the knowledge about how stuff works on the underlying platforms when it comes to building new functionality and maintaining the old features.</span><ul style="border: 0px; color: #4e5758; font-family: 'WeblySleek UI', 'Segoe UI', 'Helvetica Neue', Arial, sans-serif; font-size: 16px; line-height: 25px; list-style: circle; margin: 1em 0px 0px 3em; outline: 0px; padding: 0px; vertical-align: baseline;">
</ul>
</div>
Christian F.http://www.blogger.com/profile/02353730979008422628noreply@blogger.com0tag:blogger.com,1999:blog-6714064.post-11115575655846885702015-03-22T23:33:00.000-07:002015-03-23T02:07:53.091-07:00NControl - Cross Platform Custom Controls for Xamarin.Forms<b>NControl</b> is a Xamarin.Forms wrapper control built around the <a href="https://github.com/praeclarum/NGraphics">NGraphics</a> library enabling developers to create custom controls without the need for custom renderers.<br />
<br />
The project is hosted on <a href="https://github.com/chrfalch/NControl">Github</a> and is distributed under the MIT license.<br />
<a href="https://www.blogger.com/blogger.g?blogID=6714064" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><br /></a>
The library contains the NControlView class where real custom cross-platform drawing can be performed without the need for native implementations thanks to the <a href="https://github.com/praeclarum/NGraphics">NGraphics</a> library. NControlView can be used both to do custom drawing and to create complex custom controls.<br />
<br />
<b>Supported Platforms:</b><br />
The library currently supports native renderers for the following platforms:<br />
<ul>
<li>Android</li>
<li>iOS Unified</li>
</ul>
A Windows Phone edition of the control is planned for a later release.<br />
<br />
<b>Installation</b>:<br />
Install in your iOS, Android and Forms project using <a href="https://www.nuget.org/packages/NControl/">this</a> package from Nuget.<br />
<br />
Remember to to add calls to <code style="background-color: rgba(0, 0, 0, 0.0392157); border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; box-sizing: border-box; color: #333333; font-size: 14px; margin: 0px; padding: 0.2em 0px;">NControlViewRenderer.Init()</code>after <code style="background-color: rgba(0, 0, 0, 0.0392157); border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; box-sizing: border-box; color: #333333; font-size: 14px; margin: 0px; padding: 0.2em 0px;">Forms.Init()</code> in your AppDelegate and in your MainActivity.<br />
<br />
<b>Example Usage:</b><br />
In your Xamarin.Forms project, add a new NControlView element to your page in the constructor and provide a drawing function where your custom drawing is performed:<br />
<br />
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"> Content = new NControlView {</span><br />
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"> DrawingFunction = (canvas, rect) => {</span><br />
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"> canvas.DrawLine(rect.Left, rect.Top, rect.Width, rect.Height, NGraphics.Colors.Red);</span><br />
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"> canvas.DrawLine(rect.Width, rect.Top, rect.Left, rect.Height, NGraphics.Colors.Yellow);</span><br />
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"> }</span><br />
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"> };</span><br />
<br />
<b>Subclassing:</b><br />
You can also create a subclass of the NControlView class and override its Draw function to add your own custom drawing:<br />
<br />
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;">public class MyControl: NControlView</span><br />
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;">{</span><br />
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"> public override void Draw(NGraphics.ICanvas canvas, NGraphics.Rect rect)</span><br />
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"> {</span><br />
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"> canvas.DrawLine(rect.Left, rect.Top, rect.Width, rect.Height, NGraphics.Colors.Red);</span><br />
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"> canvas.DrawLine(rect.Width, rect.Top, rect.Left, rect.Height, NGraphics.Colors.Yellow);</span><br />
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"> }</span><br />
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;">}</span><br />
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"><br /></span>
<b>Complex Controls:</b><br />
NControlView supports containing other controls since it inherits from the ContentView class. Building composite controls is as simple as setting the Content property of your subclassed control:<br />
<br />
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;">public class MyControl: NControlView</span><br />
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;">{</span><br />
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"> public MyControl()</span><br />
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"> {</span><br />
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"> Content = new Label {BackgroundColor = Xamarin.Forms.Color.Transparent};</span><br />
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"> }</span><br />
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"><br /></span>
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"> public override void Draw(NGraphics.ICanvas canvas, NGraphics.Rect rect)</span><br />
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"> {</span><br />
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"> canvas.DrawLine(rect.Left, rect.Top, rect.Width, rect.Height, NGraphics.Colors.Red);</span><br />
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"> canvas.DrawLine(rect.Width, rect.Top, rect.Left, rect.Height, NGraphics.Colors.Yellow);</span><br />
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"> }</span><br />
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;">}</span><br />
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"><br /></span>
Now your custom control will have a label that can draw text in the control. Remember that you can set the Content property to point to anything as long as it is a VisualElement. This means that you can add layouts containing other controls as well as a single control.<br />
<br />
<b>Invalidation:</b><br />
If you need to invalide the control when a property has changed, call the Invalidate() function to redraw your control:<br />
<br />
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;">public class MyControl: NControlView</span><br />
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;">{</span><br />
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"> public MyControl()</span><br />
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"> {</span><br />
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"> Content = new Label {BackgroundColor = Xamarin.Forms.Color.Transparent};</span><br />
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"> }</span><br />
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"><br /></span>
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"> public string Text { </span><br />
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"> get </span><br />
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"> { </span><br />
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"> return (Content as Label).Text; </span><br />
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"> }</span><br />
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"> set </span><br />
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"> { </span><br />
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"> (Content as Label).Text = value;</span><br />
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"> Invalidate();</span><br />
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"> }</span><br />
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"> }</span><br />
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"><br /></span>
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"> public override void Draw(NGraphics.ICanvas canvas, NGraphics.Rect rect)</span><br />
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"> {</span><br />
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"> canvas.DrawLine(rect.Left, rect.Top, rect.Width, rect.Height, NGraphics.Colors.Red);</span><br />
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"> canvas.DrawLine(rect.Width, rect.Top, rect.Left, rect.Height, NGraphics.Colors.Yellow);</span><br />
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"> }</span><br />
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;">}</span><br />
<br />
<b>Touch events</b><br />
The NControlView class also handles touch events - look at the CircularButtonControl for an example of how this can be used.<br />
<br />
<b>Demo controls</b><br />
The demo solution contains a few different controls based on the NControlView class:<br />
<br />
</span><br />
<ul><span style="background-color: white; color: #333333; font-size: 16px; line-height: 25px;">
<li>RoundedCornerControl</li>
<li>CircularButtonControl</li>
<li>ProgressControl</li>
</span></ul>
<span style="background-color: white; color: #333333; font-size: 16px; line-height: 25px;">
<br />
The ProgressControl and the CircularButtonControl both internally uses the FontAwsomeLabel to display glyphs from the Font Awesome Icon font.<br />
<br />
<b>Notes</b><br />
Note that the ProgressControl and the CircularButtonControl contains animations to make the user experience more alive. The demo solution also uses animation to add some eye candy to the demo itself.</span>Christian F.http://www.blogger.com/profile/02353730979008422628noreply@blogger.com0tag:blogger.com,1999:blog-6714064.post-3200285915108572452010-06-11T00:19:00.001-07:002010-06-11T05:23:49.788-07:00Transforms and upgradesUpgrading shall not be easy. In our installer we are using an MST file to configure the server connection for our clients so that they shouldn't need setting this up manually.<div><br /></div><div>The transform file path is entered in the Setup.exe MSI Command Line Arguments in Installshield. Everything ok so far.</div><div><br /></div><div>But when upgrading to a newer version where the server configuration has changed, we'd love the installer to detect changes in the MST file and upgrade the client's configuration when upgrading. The problem now is that the installer uses a cached version of the MST file, and therefore the new configuration wont be applied!</div><div><br /></div><div>I'll get back when or if I find a solution to this problem.</div>Christian F.http://www.blogger.com/profile/02353730979008422628noreply@blogger.com0tag:blogger.com,1999:blog-6714064.post-85446596978009966032010-06-07T00:51:00.000-07:002010-06-11T00:13:10.995-07:00Upgrades, uninstall and major versions<div>While I was trying to make the new client installer uninstall previous versions of our software, I ran into a few issues that took a while to solve.<div><br /></div><div>First and foremost, the previous installer (custom-built) didn't contain an upgrade code (which uniqely identifies a product across versions) that I could use in my new MSI installer's upgrade table to make sure it was uninstalled. This was simple, just create a custom action that reads the uninstall information from the registry and runs the uninstall string if it exists for your product.</div><div><br /></div><div>Next I tried to tell Windows installer to remove two additional products that were installed using MSI installers. I used the upgrade table with the upgrade codes from the two products I wanted to uninstall. </div><div><br /></div><div>When running the installer, only one of the products were removed, and the log told me that the other one was skipped because it was installed in a different context (machine, not for this user only). </div><div><br /></div><div>When I removed the product that successfully was uninstalled and reran the installation, the product that was previously skipped was uninstalled! This baffled me, and I tried a lot of different solutions until I finally had to revert to a rather dirty solution.</div><div><br /></div><div>First of all, this is whats happening when you are uninstalling previous products:</div><div><ol><li>When the installer runs the <a href="http://msdn.microsoft.com/en-us/library/aa368600(VS.85).aspx">FindRelatedProducts </a>action, it looks in the Upgrade table to find what products it should search for. If it finds a product installed (using the UpgradeCode in the Upgrade table), it sets the value of the property (actionprop column) for the product in the Upgrade table to the Product code (installed version of product)</li><li>The uninstallation happens in the <a href="http://msdn.microsoft.com/en-us/library/aa371197(VS.85).aspx">RemoveExistingProducts </a>action which uninstalls those products marked for uninstallation (from the FindRelatedProducts action)</li></ol><div>The problem in my case was that the FindRelatedProducts action skipped one of the products, so I had to include a small vbscript that was run before the RemoveExistingProducts action that found the product code for the product I wanted to remove and updated the according property so that it would be uninstalled:</div></div><div><br /></div><div><div>set oWI = CreateObject("WindowsInstaller.Installer")</div><div>set related = oWI.RelatedProducts("YOUR_UPGRADECODE_HERE") </div><div>if related.Count = 1 then</div><div> Property("ACTIONPROPERTY_NAME_HERE") = related.Item(0) </div><div>end if</div></div><div><br /></div><div>Forcing the product code to be set solved the issue I had even though I never found out what was wrong with the FindRelatedProducts action not picking up both products.</div><div><br /></div></div>Christian F.http://www.blogger.com/profile/02353730979008422628noreply@blogger.com0tag:blogger.com,1999:blog-6714064.post-49653338780528233902010-02-23T05:51:00.000-08:002010-03-05T11:16:23.680-08:00Extract COM information during build time causes Installshiled to hangInstallShield uses a tool to extract COM information (spying on the registry) called IsRegSpy.exe. It is trying to register COM libraries and watching what happens in the registry to capture all the keys and values written during registration.<br /><br />After adding some our own internal libraries I noticed that the IDE startet to hang when extracting COM information from the components in the setup project. After inspecting what was happening using ProcExplorer from Microsoft (http://www.sysinternals.com) I saw that the IDE spawned IsRegSpy.exe but IsRegSpy.exe never seemed to return.<br /><br />After digging back and forth for a while, I tried to extract the COM information from within the InstallShield IDE to avoid getting this error each time we built the project. The same thing happened, the IDE launched IsRegSpy.exe and stopped responding.<br /><br />I tried killing IsRegSpy.exe from within ProcExplorer, and noticed that InstallShield managed to add the correct COM information to the IDE! It also turned off the "Extract COM at build" setting for the component! Doing this for all COM components in the Setup project I managed to get past the problem of hanging the IDE when building.<br /><br />EDIT: The last paragraph was obviously written in a very optimistic tone.. Some of the information was saved, some was not. My final solution was to export the registry hives before and after registering the dlls and then diffing the output...Christian F.http://www.blogger.com/profile/02353730979008422628noreply@blogger.com0tag:blogger.com,1999:blog-6714064.post-16149074429649225282010-02-17T05:59:00.000-08:002010-03-16T02:00:20.026-07:00LocalizationSeems to be rather easy using InstallShield. There are several different options to choose from. You can add all the languages you want to support to your installation, or you can build seperate installations for each language.<br /><br />NOTE: The language of the installer itself and the language your application is set up to run in are not the same.<br /><br />I chose to build sepearate deployment packages for each language our application is using. The reasoning behind this is that each language component weights in at around 10 megs which could be a problem to distribute to remote users when updating or servicing the application.<br /><br />Using different releases and configurations under the Media/Releases node gives me the opportuntity to build more than one setup.exe from my project. I have also integrated the build of each setup into our build system using some custom code for spawning Install Shield.<br /><br />To get automatic resolving of which features that should go into which of my language dependant distributions, I have set the languages property for these features to a specific language (not Language Independent). When setting a release configuration 's data languages, ui languages and default language to a given language, only those features with either the same language as the configuration (or language independent) will be included in the setup!Christian F.http://www.blogger.com/profile/02353730979008422628noreply@blogger.com0tag:blogger.com,1999:blog-6714064.post-16241353867968355112010-02-17T05:46:00.001-08:002010-02-17T23:59:47.091-08:00Transforms and Setup.exeWhen starting out with the deployment project, I tried to define some areas where I had to do some research to be certain that we had a solution that was scalable and easy to maintain.<br /><br />One of the first issues I ran into was the need for using transforms to change some property values in the MSI package. The background for this requirement is that our app is a typical client/server-based application where our clients perform a server installation where they customize the installation against their database setup and file locations etc.<br /><br />The cusomization performed in the server setup must be replicated into the client setup so that end users shouldn't have to select odbc connections or file locations upon installation.<br /><br />The first issue here is how we can make the Server Setup process modify the client installer so that it depolys the client package with the predefined settings. To make this work, we've decided to use transform files.<br /><br />A transform file is a simple msi database that contains tables just like another msi file. It is used to override values in the msi file it is transforming.<br /><br />Creating a transform (.mft) file is simple using InstallShield. Just select new project and choose the Transform project template. InstallShield will ask you to provide the msi-file for which you are creating a transform, so you have to have it built already.<br /><br />After creating the transform file, add it to your installation project under the support file section. You can now tell setup.exe to run it by providing command lines to the msi file in the setup.exe package. Select your setup release in InstallShield (this post is about transforms, so if you only have an msi project, please stop reading..) and switch to the Setup.exe tab. In the MSI Command Line Arguments property, enter TRANSFORMS=<span style="font-style: italic;">name of your mst file</span>.<br /><br />When we're ready to start generating our own transformation files that lives outside setup.exe, we can remove the transformation file from our setup project and provide it alongside the setup itself.Christian F.http://www.blogger.com/profile/02353730979008422628noreply@blogger.com0tag:blogger.com,1999:blog-6714064.post-19879609210642017552010-02-17T05:44:00.000-08:002010-02-18T00:00:02.739-08:00Welcome back...I'm currently working on a new MSI-based installer for our main product, and since I tend to forget how I solve the different parts of building an installation from the last time I built one, I've decided to document some of the more important solutions I find here.Christian F.http://www.blogger.com/profile/02353730979008422628noreply@blogger.com0tag:blogger.com,1999:blog-6714064.post-63945715099469072212008-08-05T00:33:00.000-07:002008-08-05T01:03:51.153-07:00Process.WaitForExit() never completesIt's been over a year since the last time I blogged.... Sorry for that, but it's been a busy year. I've decided to pick up again and try to post some tech-related random thoughts once in a while.<br /><br />Today I just wanted to share a bug I found that might be interesting for some of you.<br /><br />I had a small function that started a process and waited for it to finish it's work. The code looked something like this:<br /><br /><span style="font-family:courier new;">Process P = new Process();</span><br /><span style="font-family:courier new;">P.StartInfo.UseShellExecute = false;<br />P.StartInfo.RedirectStandardOutput = true;<br />P.StartInfo.RedirectStandardError = true;<br />P.StartInfo.FileName = pathToProgram;</span><br /><span style="font-family:courier new;">P.StartInfo.Arguments = programArguments;<br />P.Start();</span><br /><span style="font-family:courier new;">P.WaitForExit();</span><br /><span style="font-family:courier new;">P.Close();<br /></span><br />Since the process sometimes takes a while to finish, I wanted to be able to watch what was going on, so I decided to read from stderr/stdinput to see if something went wrong. To do this, I made sure that the RedirectStandardError properties of the process was set to true (see code above), and inserted the following line to check if the application had encountered any errors:<br /><br /><span style="font-family:courier new;">P.WaitForExit();<br /><strong>string err = P.StandardError.ReadToEnd(); </strong></span><br /><span style="font-family:courier new;">P.Close();</span><br /><br />After this code had been used for a while, I noticed that once in a while the application was hanging when performing the above process. The problem only occured when a lot of data was written to standarderror.<br /><br />I debugged the problem, and found out that omitting reading from StandardError removed the problem. I thought that this seemed like a strange problem, and continued to search for a solution.<br /><br />After reading the documentation, I finally came up with the information that revealed the problem. The following remark in the msdn library for the <a href="http://msdn.microsoft.com/en-us/library/system.diagnostics.processstartinfo.redirectstandarderror(VS.71).aspx">RedirectStandardError</a> property says:<br /><br /><em>"The </em><em>Process</em><em> component communicates with a child process using a pipe. If a child process writes enough data to the pipe to fill the buffer, the child will block until the parent reads the data from the pipe. This can cause deadlock if your application is reading all output to standard error and standard output, for example, using the following C# code."</em><br /><em></em><br />So instead of asking the process to fill the buffer and wait for me to empty it so that the call to WaitForExit() would block, reading the contents of the buffer (P.StandardError.ReadToEnd()) before calling WaitForExit() solved the problem and made the solution a success.<br /><br />Conclusion: Read the documentation. And make sure you read the remarks.Christian F.http://www.blogger.com/profile/02353730979008422628noreply@blogger.com0tag:blogger.com,1999:blog-6714064.post-76632449639730993262007-08-01T02:25:00.001-07:002007-08-01T02:25:23.030-07:00Vista and Visual Studio 2003 again..<p>After the computer-switch I had to set up Vista for devlopment with Visual Studio 2003 again, and was a bit disappointed by my <a href="http://chrfalch.blogspot.com/2007/06/they-said-it-couldn-be-done.html" target="_blank">last post about the topic</a> - I hadn't written anything at all about how I actually set up IIS 7.0 to be able to debug and run .Net 1.1 applications! So here it is.. the short version:</p> <ul> <li>Register .Net 1.1 ASP.NET by running the following program. The -i parameter tells the utility to install support for ASP.NET 1.1 under IIS: Windows\Microsoft.NET\Framework\v1.1.4322\aspnet_regiis.exeaspnet_regiis.exe -i</li> <li>Change the application pool to one using the .Net framework 1.1 for the application you want to debug and run</li></ul> <p>I also enabled .Net development and CGI in the additional windows components the "Windows functions" control panel applet.</p>Christian F.http://www.blogger.com/profile/02353730979008422628noreply@blogger.com0tag:blogger.com,1999:blog-6714064.post-6392938413662151582007-08-01T02:17:00.001-07:002007-08-01T02:29:04.796-07:00Vista OEM - Network Troubles<p>Since I'm usually sitting at my desk developing new and interesting stuff for my company, using a slow (but cool :-) old Tablet PC wasn't the best way to be an effective developer. </p> <p>Last week I got myself a new PC that will sit at my desk at work. It's a fast and brand new dual core computer with loads of memory, a big harddrive and a DirectX 10-based video card. I choose Windows Vista Business, since I've been quite happy with the way Vista has been working on my Tablet PC.</p> <p>The only problem came when I was about to check in some source code to subversion. TortoiseSVN complained with a message saying it couldn't move a file in the repository. The repository is located on a network share and accessed by a small group of programmers. </p> <p>I searched all over to see if this was a common problem with subversion, but found nothing. Then I noticed that I couldn't rename files on the network, and started to search for similar reports on the net. At last I found <a href="http://forums.microsoft.com/TechNet/ShowPost.aspx?PostID=1210644&SiteID=17" target="_blank">this</a> post, which helped me fix the issue. </p> <p>So why the OEM troubles heading? Read the above post - the bug has to do with something missing in the OEM version of Vista. </p>Christian F.http://www.blogger.com/profile/02353730979008422628noreply@blogger.com0tag:blogger.com,1999:blog-6714064.post-65701807648795879862007-06-27T06:05:00.001-07:002007-06-27T06:10:32.850-07:00Kids and programming<p>After reading <a href="http://www.hanselman.com/">Scott Hanselman's</a> <a href="http://www.hanselman.com/blog/TeachingChildrenAndKidsToProgramTheOldSchoolWay.aspx">article</a> about how to teach kids computer programming, I once more decided to try to get my children interested in the topic that has brought me so much fun and joy.</p><br /><p>The kids are now around 11 years old, and all enjoys playing games, doing homework and surf the web on their computers. They are creative, and can spend an evening creating images in MS Paint or making a presentation in Powerpoint. </p><br /><p>I've previously tried to get them interested in programming using tools like <a href="http://www.kidsprogramminglanguage.com/">KPL</a>, but the big problem was learning the syntax. They're not yet able to learn enough statements or commands to express themselves and solve abstract problems in a textual programming language.<br /></p><p>I went along and grabbed a copy of <a href="http://www.mit.edu/">MIT</a>'s <a href="http://scratch.mit.edu/">Scratch</a>, which is a graphical tool for building small 2D games and animations:</p><br /><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh3gaysrnUVUAMSuR7kxCbvy7spWrJQoxdRmVwLLXu7mSt38nn2-6edT8Zy6s94__p1GwkZTzTLes5vIaMm1p-v4vF4rhh8YEPth6b06oEyuRckmUjBzWCGhkrbqZ1RePEk9LLA/s1600-h/scracth.jpg"><img id="BLOGGER_PHOTO_ID_5080730576697132066" style="CURSOR: hand" alt="" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh3gaysrnUVUAMSuR7kxCbvy7spWrJQoxdRmVwLLXu7mSt38nn2-6edT8Zy6s94__p1GwkZTzTLes5vIaMm1p-v4vF4rhh8YEPth6b06oEyuRckmUjBzWCGhkrbqZ1RePEk9LLA/s320/scracth.jpg" border="0" /></a><br /><br /><p>Scratch uses a visual representation of statemements, variables and control blocks, and this really worked out for them. They quickly learned how to set up a small loop that tested for collisions with other objects, and that could send messages to all the other sprites making interesting things happen (like getting the sun to appear in the sky) </p><br /><p>Allthough it is not possible to build fully fledged games in Scratch, it seems like a great tool to learn the basics of programming like I once learned on my <a href="http://www.vintage-computer.com/dragon32.shtml">Dragon 32</a> from my father (yes, we still have the old Dragon, allthough we haven't booted it up for a while).</p>Christian F.http://www.blogger.com/profile/02353730979008422628noreply@blogger.com0tag:blogger.com,1999:blog-6714064.post-30181781802468874102007-06-08T05:58:00.001-07:002007-06-08T05:58:31.683-07:00They said it couldn't be done.. :-)<p>Development in Visual Studio 2003 on Microsoft Vista.</p> <p>It is <a href="http://www.google.com/search?q=%22visual+studio+2003%22+vista">said</a> <a href="http://msdn2.microsoft.com/en-us/vstudio/aa948854.aspx">that</a> it is <a href="http://weblogs.asp.net/pwilson/archive/2006/09/27/Vista-will-NOT-support-Developers.aspx">not</a> <a href="http://searchvb.techtarget.com/originalContent/0,289142,sid8_gci1219838,00.html">possible</a> to use Visual Studio 2003 in Microsoft Vista, and as I have written about earlier on, I set out on a small journey to find out how far I could get into using it on my Tecra M4.</p> <p>Here is the current list:</p> <ul> <li>Installed .Net Framework 1.1 - OK</li> <li>Installed Visual Studio 2003 on Vista - OK</li> <li>Been able to compile and build my projects under 2003 - OK</li> <li>Debug web-based applications with Visual Studio 2003 and IIS 7.0 - OK</li> <li><a href="http://chrfalch.blogspot.com/2006/05/edit-and-continue-in-vs-2003.html#links">Edit and continue</a> in Visual Studio 2003 - OK</li></ul> <p>The only thing I know I will have problems with is developing plain web applications (you know the project type APS.Net Web Application), but since I don't use them, I wont cry either..!</p>Christian F.http://www.blogger.com/profile/02353730979008422628noreply@blogger.com0tag:blogger.com,1999:blog-6714064.post-57956773969843148802007-06-04T12:54:00.001-07:002007-06-04T12:54:33.700-07:00My Venture into Vista Land<p>Phew! It takes a lot of time to install all the drivers and software one needs when reinstalling a computer... </p> <p>As I wrote earlier on, I was eager to see if I could get Visual Studio 2003 up and running on Windows Vista. As some people say, it shouldn't be possible. This made me think that Vista might have some functionality that could prohibit programs from even installing, but this was not the case. Visual Studio 2003 installed in a much more clean way than the latest Visual Studio Orcas Beta (for testing out Silverlight development). Installing the Orcas beta (ok, I know it's Beta) went wrong almost ten times before I finally succeeded. </p> <p>But now I have a brand new Vista installation working with all the tools I need to do my job. And it feels good. And since I'm kinda geeky, I must admit that I've turned off the Aero effects and reverted back to the old Win2K-look... But it's all in the details, isn't it?</p>Christian F.http://www.blogger.com/profile/02353730979008422628noreply@blogger.com0tag:blogger.com,1999:blog-6714064.post-72482624199160799552007-06-04T06:41:00.001-07:002007-06-04T06:41:46.340-07:00Converting myself and my Tecra to Vista<p>Since my Toshiba Tecra M4 has been working for ages without being treated with a fresh install, I finally decided that it was time to:</p> <ol> <li>Perform a fresh install, since the machine had become a bit slow and sluggish</li> <li>See if I could try a Vista install and check if I could trick Visual Studio 2003 into running on Vista.</li> <li>If section two failed, install Windows XP and pretend I didn't listen to any of the 2 million other developers out there telling me that this wouldn't work.</li></ol> <p>So, after a while of thinking and planning, I went ahead:</p> <ol> <li>Identifyed all the files on my computer that needed to be backed up</li> <li>Backed up all the files that I found to an external harddrive</li> <li>Double checked and tripple checked the above sections</li> <li>Downloaded and collected all the necessary drivers and software from Toshiba and others</li> <li>Installed Windows Vista</li></ol> <p>This all went well, except for the face that I got rather ill in the middle of the process due to an allergic reaction. This was of course a bit bad, sitting with a computer with no OS and no software.. </p> <p>In my next post I'll tell you how it went after I got the OS up and running!</p>Christian F.http://www.blogger.com/profile/02353730979008422628noreply@blogger.com0tag:blogger.com,1999:blog-6714064.post-68823942961663101322007-05-31T11:59:00.000-07:002007-05-31T12:04:29.922-07:00New Tech impresses meRead about Microsoft Surface today, which looks like a very interesting and fun platform to play with.<br /><br />The concept is using multitouch (more than one pointer on the screen, just like what Steve Jobs showed with the iPhone) on a big touch screen to navigate a delicious user interface built with WPF. In addition, a system utilizing invisible ink to tag devices like cameras and smartphones, is used to make Surface interact with devices and objects from the real world.<br /><br />Microsoft says that the hardware will be kind of expensive (in the $5K-$10K range). What I really would like to see is Microsoft Surface running on a TabletPC with lots of cpu and memory. That would be a nice way of using my Toshiba Tecra M4...!Christian F.http://www.blogger.com/profile/02353730979008422628noreply@blogger.com0tag:blogger.com,1999:blog-6714064.post-44364560558091651142007-05-20T23:44:00.000-07:002007-05-20T23:46:32.167-07:00Link to PopFlySome of my readers have pointed out that I didn't include a link to PopFly yesterday. Sorry :-) Here it is:<br /><br />http://www.popfly.com<br /><br />And here is the link to the video presentation on <a href="http://channel9.msdn.com/">Channel9</a>:<br /><br />http://channel9.msdn.com/showpost.aspx?postid=308460Christian F.http://www.blogger.com/profile/02353730979008422628noreply@blogger.com0tag:blogger.com,1999:blog-6714064.post-62572207303669215232007-05-19T10:21:00.000-07:002007-05-19T10:24:06.019-07:00Popfly!Just read about PopFly from Microsoft, which seems to be a really cool solution for building mashups and sharing them afterwords. The whole thing is built on Silverlight, which is also what I am currently installing on my computer..Christian F.http://www.blogger.com/profile/02353730979008422628noreply@blogger.com0tag:blogger.com,1999:blog-6714064.post-68704713535201403242007-05-09T10:04:00.000-07:002007-05-09T10:11:29.072-07:00Facebook is a cool hypeappI finally decided to join some of the social networks out there, and went for both <a href="http://www.linkedin.com">linkedin</a> an <a href="http://www.facebook.com">facebook</a>.<br /><br />Facebook has definitely been giving me most joy out of the two, but I suspect that Linkedn will probably give me more bang for the bucks if I'd really need it sometime in the future.<br /><br />I really look forward to see if people will still enjoy writing on each other's walls and keep on connecting with long lost friends and classmates six months from now.<br /><br />I really need to stay on Facebook for the nex months to see for myself :-) Anyway, without the hype there wouldn't have been any fun! Hope the hype stays.Christian F.http://www.blogger.com/profile/02353730979008422628noreply@blogger.com0tag:blogger.com,1999:blog-6714064.post-80697092371128950232007-05-07T09:31:00.000-07:002007-05-07T09:35:08.434-07:00Multitasking and the joy of Media CenterI'm currently doing some serious multitasking on my new HTCP.<br /><br />The kids are watching children's tv while I'm reading my RSS feeds (and blogging). All on the same screen (thanks to NRK not sending in widescreen), thanks to our LCD flatscreen. And the kids aren't complaining about my thin Firefox window taking up approx. 1/3 of the screen.Christian F.http://www.blogger.com/profile/02353730979008422628noreply@blogger.com0tag:blogger.com,1999:blog-6714064.post-8592066595343525712007-05-01T02:02:00.000-07:002007-05-01T02:10:22.055-07:00My new HTCPI've been working a lot the past few days to get my new <a href="http://chrfalch.blogspot.com/2007/04/finally-i-got-my-self-htpc.html">HTCP</a> up and running. Everything seemed to work perfect, except that I couldn't get any live TV. I tried everything from reinstalling Windows Media Center (which took a while and wasn't as easy as other Windows installations) to opening up the computer making sure there were no faulty connections anywhere. I also installed a couple of alternative applications for watching TV hoping that my channels would magically appear.<br /><br />The solution was to borrow another TV-card and insert it into the computer. This is a small and tight <a href="http://www.gigabyte.com.tw/Products/DigitalHome/Products_Spec.aspx?ProductID=2236&ProductName=H663">PC</a>, so inserting the slightly bigger PVR 500 card (originally a PVR 150) was a tight fit. But when booting up the machine the new card was immediately recognized, and all my channels were instantly found!<br /><br />Since my HTPC was bought used from the internet (norwegian site <a href="http://www.finn.no">finn.no</a>), I was a bit skeptic to what I could achieve in return for the faulty card. I contacted the seller, who was a real gentleman and was promised a direct return on the card. Thanks!<br /><br />Now I'm of to watch some recorded TV shows!Christian F.http://www.blogger.com/profile/02353730979008422628noreply@blogger.com0tag:blogger.com,1999:blog-6714064.post-40697935652450378172007-04-26T01:17:00.000-07:002007-04-26T01:23:56.905-07:00Finally I got my self a HTPC!After having tried to use cheap components for running a <a href="http://chrfalch.blogspot.com/2005/12/music-media-technology.html">media center setup</a> for a couple of years, I finally decided to give myself a little pre-birthday present. I bought a used HTPC originally manufactured from <a href="http://www.komplett.no/k/ci.asp?sku=10269">komplett.no</a> (in Norwegian) today! The HTPC is running Media Center XP (switching to Vista soon.. maybe..?), and has an external power supply which I hope will help keep the noise down. I'm picking it up later today, so my old DSM-320 will be up for sales now. Anyone interested? No? Hello..?Christian F.http://www.blogger.com/profile/02353730979008422628noreply@blogger.com0tag:blogger.com,1999:blog-6714064.post-1747983472797688852007-04-25T06:53:00.000-07:002007-04-25T13:21:06.163-07:00This will be nice (Javascript intellisense and debugging)Happy to read that Javascript intellisense and debugging will be available in the next version of Microsoft Visual Studio!<http: com="" webdevtools="" archive="" 2007="" 03="" 02="" aspx=""><http: com="" webdevtools="" archive="" 2007="" 03="" 09="" aspx=""><br /><br /><a href="http://weblogs.asp.net/scottgu/archive/2007/04/24/javascript-intellisense-in-visual-studio-orcas.aspx">Read more over at Scott G's blog.</a><br /><br />Thanks :-) And I'm looking forward to start using it!</http:></http:>Christian F.http://www.blogger.com/profile/02353730979008422628noreply@blogger.com0