<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>Confessions of a coder</title>
	<atom:link href="http://peteohanlon.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://peteohanlon.wordpress.com</link>
	<description>Confessions of a WPF lover</description>
	<lastBuildDate>Wed, 28 Sep 2011 09:20:33 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='peteohanlon.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://s2.wp.com/i/buttonw-com.png</url>
		<title>Confessions of a coder</title>
		<link>http://peteohanlon.wordpress.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://peteohanlon.wordpress.com/osd.xml" title="Confessions of a coder" />
	<atom:link rel='hub' href='http://peteohanlon.wordpress.com/?pushpress=hub'/>
		<item>
		<title>MoXAML goes Codeplex</title>
		<link>http://peteohanlon.wordpress.com/2011/09/15/moxaml-goes-codeplex/</link>
		<comments>http://peteohanlon.wordpress.com/2011/09/15/moxaml-goes-codeplex/#comments</comments>
		<pubDate>Thu, 15 Sep 2011 01:06:35 +0000</pubDate>
		<dc:creator>peteohanlon</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://peteohanlon.wordpress.com/?p=397</guid>
		<description><![CDATA[One of the commonest questions I&#8217;ve been asked about MoXAML was whether or not I would be maintaining it in a repository of some description. While I&#8217;ve not been against the idea, I just haven&#8217;t got around to doing it. Well, that is I hadn&#8217;t got around to doing it. I am pleased to announce [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=peteohanlon.wordpress.com&amp;blog=1230283&amp;post=397&amp;subd=peteohanlon&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>One of the commonest questions I&#8217;ve been asked about MoXAML was whether or not I would be maintaining it in a repository of some description. While I&#8217;ve not been against the idea, I just haven&#8217;t got around to doing it. Well, that is I hadn&#8217;t got around to doing it. I am pleased to announce that MoXAML is now open source and is available on CodePlex at <a href="http://moxaml.codeplex.com/">http://moxaml.codeplex.com/</a>.</p>
<p>By putting MoXAML on CodePlex, it is going to be easier for me to maintain the whole setup/installation package and I&#8217;m toying with an idea on how to automatically pull down updates to MoXAML &#8211; these are architectural ideas only, no code has been written, it&#8217;s just notes and diagrams so far.</p>
<p>Anyway, sorry for not posting something &#8220;witty&#8221; or silly &#8211; this post&#8217;s relatively normal for me. Abnormal service will resume shortly.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/peteohanlon.wordpress.com/397/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/peteohanlon.wordpress.com/397/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/peteohanlon.wordpress.com/397/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/peteohanlon.wordpress.com/397/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/peteohanlon.wordpress.com/397/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/peteohanlon.wordpress.com/397/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/peteohanlon.wordpress.com/397/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/peteohanlon.wordpress.com/397/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/peteohanlon.wordpress.com/397/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/peteohanlon.wordpress.com/397/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/peteohanlon.wordpress.com/397/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/peteohanlon.wordpress.com/397/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/peteohanlon.wordpress.com/397/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/peteohanlon.wordpress.com/397/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=peteohanlon.wordpress.com&amp;blog=1230283&amp;post=397&amp;subd=peteohanlon&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://peteohanlon.wordpress.com/2011/09/15/moxaml-goes-codeplex/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/b13854c10ce07efee2062f13d9334cba?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">Pete O'Hanlon</media:title>
		</media:content>
	</item>
		<item>
		<title>Adding to MoXAML.</title>
		<link>http://peteohanlon.wordpress.com/2011/09/13/adding-to-moxaml/</link>
		<comments>http://peteohanlon.wordpress.com/2011/09/13/adding-to-moxaml/#comments</comments>
		<pubDate>Tue, 13 Sep 2011 21:15:09 +0000</pubDate>
		<dc:creator>peteohanlon</dc:creator>
				<category><![CDATA[MoXAML]]></category>
		<category><![CDATA[Windows Presentation Foundation]]></category>
		<category><![CDATA[MoXAMLPowerToys]]></category>

		<guid isPermaLink="false">http://peteohanlon.wordpress.com/?p=391</guid>
		<description><![CDATA[In my last post, I talked about the enhancements and new architecture I have put into place for the new version of MoXAML Power Toys. I also mentioned that I&#8217;d talk about adding a new command. Well, in this post I&#8217;m going to cover how I coded the Scrubber command that&#8217;s available in the new [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=peteohanlon.wordpress.com&amp;blog=1230283&amp;post=391&amp;subd=peteohanlon&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>In my last post, I talked about the enhancements and new architecture I have put into place for the new version of <a href="http://peteohanlon.wordpress.com/moxaml-power-toys/" target="_blank">MoXAML Power Toys</a>. I also mentioned that I&#8217;d talk about adding a new command. Well, in this post I&#8217;m going to cover how I coded the Scrubber command that&#8217;s available in the new version.</p>
<p>One of the first things I did was break the Scrubber options from the actual Scrubber command. By doing this, the user no longer needs to set the options every time they need to run Scrubber. So, I created a traditional model for the options which could be used by the Scrubber commands and the Scrubber options dialog. This model looks like this:</p>
<pre class="brush: csharp;">
using System.ComponentModel;
using System.IO;
using System.IO.IsolatedStorage;
using System.Linq;

namespace MoXAML.Scrubber.Model
{
    public class ScrubberOptionsModel : INotifyPropertyChanged
    {
        private const string FILENAME = &quot;MoXAMLSettings.dat&quot;;

        private int _attributeCountTolerance = 3;
        private bool _reorderAttributes = true;
        private bool _reducePrecision = true;
        private int _precision = 3;
        private bool _removeCommonDefaults = true;
        private bool _forceLineMinimum = true;
        private int _spaceCount = 2;
        private bool _convertTabsToSpaces = true;

        public ScrubberOptionsModel()
        {
            LoadModel();
        }

        public bool ConvertTabsToSpaces
        {
            get
            {
                return _convertTabsToSpaces;
            }
            set
            {
                if (_convertTabsToSpaces == value) return;
                _convertTabsToSpaces = value;
                OnChanged(&quot;ConvertTabsToSpaces&quot;);
            }
        }

        public int SpaceCount
        {
            get
            {
                return _spaceCount;
            }
            set
            {
                if (_spaceCount == value) return;
                _spaceCount = value;
                OnChanged(&quot;SpaceCount&quot;);
            }
        }

        public bool ForceLineMinimum
        {
            get
            {
                return _forceLineMinimum;
            }
            set
            {
                if (_forceLineMinimum == value) return;
                _forceLineMinimum = value;
                OnChanged(&quot;ForceLineMinimum&quot;);
            }
        }

        public bool RemoveCommonDefaults
        {
            get
            {
                return _removeCommonDefaults;
            }
            set
            {
                if (_removeCommonDefaults == value) return;
                _removeCommonDefaults = value;
                OnChanged(&quot;RemoveCommonDefaults&quot;);
            }
        }

        public int Precision
        {
            get
            {
                return _precision;
            }
            set
            {
                if (_precision == value) return;
                _precision = value;
                OnChanged(&quot;Precision&quot;);
            }
        }

        public bool ReducePrecision
        {
            get
            {
                return _reducePrecision;
            }
            set
            {
                if (_reducePrecision == value) return;
                _reducePrecision = value;
                OnChanged(&quot;ReducePrecision&quot;);
            }
        }

        public bool ReorderAttributes
        {
            get
            {
                return _reorderAttributes;
            }
            set
            {
                if (_reorderAttributes == value) return;
                _reorderAttributes = value;
                OnChanged(&quot;ReorderAttributes&quot;);
            }
        }

        public int AttributeCountTolerance
        {
            get { return _attributeCountTolerance; }
            set
            {
                if (_attributeCountTolerance == value) return;
                _attributeCountTolerance = value;
                OnChanged(&quot;AttributeCountTolerance&quot;);
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        private void OnChanged(string propertyName)
        {
            var handler = PropertyChanged;
            if (handler == null) return;
            handler(this, new PropertyChangedEventArgs(propertyName));
        }

        private void LoadModel()
        {
            using (IsolatedStorageFile file = IsolatedStorageFile.GetUserStoreForAssembly())
            {
                if (file.GetFileNames(FILENAME).Count() == 0) return;

                using (IsolatedStorageFileStream stream = new IsolatedStorageFileStream(FILENAME, System.IO.FileMode.Open, file))
                {
                    using (StreamReader sr = new StreamReader(stream))
                    {
                        _attributeCountTolerance = ConvertInt(sr.ReadLine());
                        _reorderAttributes = ConvertBool(sr.ReadLine());
                        _reducePrecision = ConvertBool(sr.ReadLine());
                        _precision = ConvertInt(sr.ReadLine());
                        _removeCommonDefaults = ConvertBool(sr.ReadLine());
                        _forceLineMinimum = ConvertBool(sr.ReadLine());
                        _spaceCount = ConvertInt(sr.ReadLine());
                        _convertTabsToSpaces = ConvertBool(sr.ReadLine());
                    }
                }
            }
        }

        public void SaveModel()
        {
            using (IsolatedStorageFile file = IsolatedStorageFile.GetUserStoreForAssembly())
            {
                using (IsolatedStorageFileStream stream = new IsolatedStorageFileStream(FILENAME, System.IO.FileMode.Create, file))
                {
                    using (StreamWriter sr = new StreamWriter(stream))
                    {
                        sr.WriteLine(_attributeCountTolerance);
                        sr.WriteLine(_reorderAttributes);
                        sr.WriteLine(_reducePrecision);
                        sr.WriteLine(_precision);
                        sr.WriteLine(_removeCommonDefaults);
                        sr.WriteLine(_forceLineMinimum);
                        sr.WriteLine(_spaceCount);
                        sr.WriteLine(_convertTabsToSpaces);
                    }
                }
            }
        }

        private int ConvertInt(string value)
        {
            int retVal = 0;
            if (int.TryParse(value, out retVal))
            {
                return retVal;
            }
            return 0;
        }

        private bool ConvertBool(string value)
        {
            bool retVal = false;
            if (bool.TryParse(value, out retVal))
            {
                return retVal;
            }
            return false;
        }
    }
}
</pre>
<p>As you can see, there&#8217;s nothing remarkable about it. It&#8217;s a straightforward model implementation, and there&#8217;s nothing special about using this inside MoXAML (the point I&#8217;m making here is that you can mix and match your MoXAML implementation with standard .NET code).</p>
<p>OK Pete, let&#8217;s have a look at actually hooking this into MoXAML. Well, as I mentioned in the MoXAML page, I wanted to have two versions of Scrubber, one for the current file and one for the project files. In order to do this, it made sense to pull the core Scrubber functionality into a base class which the actual commands would hook into:</p>
<pre class="brush: csharp;">
using MoXAML.Infrastructure;
using MoXAML.Scrubber.Model;
using System.IO;
using System.Xml;
using System.Collections.Generic;
using System;
namespace MoXAML.Scrubber
{
    public partial class ScrubberCommandBase : CommandBase
    {
        private ScrubberOptionsModel _model;
        public ScrubberCommandBase() : base()
        {
            _model = new ScrubberOptionsModel();
        }

        protected void ParseFile(string file)
        {
            string text = File.ReadAllText(file);
            text = Perform(text);
            File.WriteAllText(file, text);
        }

        private string Perform(string text)
        {
            text = Indent(text);
            return ReducePrecision(text);
        }

        private string IndentString
        {
            get
            {
                if (_model.ConvertTabsToSpaces)
                {
                    string spaces = string.Empty;
                    spaces = spaces.PadRight(_model.SpaceCount, ' ');

                    return spaces;
                }
                else
                {
                    return &quot;\t&quot;;
                }
            }
        }

        private string ReducePrecision(string s)
        {
            string old = s;

            if (_model.ReducePrecision)
            {
                int begin = 0;
                int end = 0;

                while (true)
                {
                    begin = old.IndexOf('.', begin);
                    if (begin == -1) break;

                    // get past the period
                    begin++;

                    for (int i = 0; i &amp;lt; _model.Precision; i++)
                    {
                        if (old[begin] &amp;gt;= '0' &amp;&amp; old[begin] &amp;lt;= '9') begin++;
                    }

                    end = begin;

                    while (end &amp;lt; old.Length &amp;&amp; old[end] &amp;gt;= '0' &amp;&amp; old[end] &amp;lt;= '9') end++;

                    old = old.Substring(0, begin) + old.Substring(end, old.Length - end);

                    begin++;
                }
            }

            return old;
        }

        public string Indent(string s)
        {
            string result;

            s = s.Replace(&quot;&amp;&quot;, &quot;¬¬&quot;);
            using (MemoryStream ms = new MemoryStream(s.Length))
            {
                using (StreamWriter sw = new StreamWriter(ms))
                {
                    sw.Write(s);
                    sw.Flush();

                    ms.Seek(0, SeekOrigin.Begin);

                    using (StreamReader reader = new StreamReader(ms))
                    {
                        XmlReaderSettings settings = new XmlReaderSettings();
                        settings.CheckCharacters = false;
                        settings.ConformanceLevel = ConformanceLevel.Auto;
                        //XmlReader xmlReader = XmlReader.Create(reader.BaseStream, settings);
                        XmlTextReader xmlReader = new XmlTextReader(reader.BaseStream);
                        xmlReader.Normalization = false;
                        xmlReader.Read();
                        xmlReader.Normalization = false;

                        string str = &quot;&quot;;

                        while (!xmlReader.EOF)
                        {
                            string xml;
                            int num;
                            int num6;
                            int num7;
                            int num8;

                            switch (xmlReader.NodeType)
                            {
                                case XmlNodeType.Element:
                                    xml = &quot;&quot;;
                                    num = 0;
                                    goto Element;

                                case XmlNodeType.Text:
                                    {
                                        string str4 = xmlReader.Value.Replace(&quot;&amp;&quot;, &quot;&amp;amp;&quot;).Replace(&quot;&amp;lt;&quot;, &quot;&amp;lt;&quot;).Replace(&quot;&amp;gt;&quot;, &quot;&amp;gt;&quot;).Replace(&quot;\&quot;&quot;, &quot;&amp;quot;&quot;);
                                        str = str + str4;
                                        xmlReader.Read();
                                        continue;
                                    }
                                case XmlNodeType.ProcessingInstruction:
                                    xml = &quot;&quot;;
                                    num7 = 0;
                                    goto ProcessingInstruction;

                                case XmlNodeType.Comment:
                                    xml = &quot;&quot;;
                                    num8 = 0;
                                    goto Comment;

                                case XmlNodeType.Whitespace:
                                    {
                                        xmlReader.Read();
                                        continue;
                                    }
                                case XmlNodeType.EndElement:
                                    xml = &quot;&quot;;
                                    num6 = 0;
                                    goto EndElement;

                                default:
                                    goto Other;
                            }

                        Label_00C0:
                            xml = xml + IndentString;
                            num++;

                        Element:
                            if (num &amp;lt; xmlReader.Depth)
                            {
                                goto Label_00C0;
                            }

                            string elementName = xmlReader.Name;

                            string str5 = str;
                            str = str5 + &quot;\r\n&quot; + xml + &quot;&amp;lt;&quot; + xmlReader.Name;
                            bool isEmptyElement = xmlReader.IsEmptyElement;

                            if (xmlReader.HasAttributes)
                            {
                                // construct an array of the attributes that we reorder later on
                                List&amp;lt;AttributeValuePair&amp;gt; attributes = new List&amp;lt;AttributeValuePair&amp;gt;(xmlReader.AttributeCount);

                                for (int k = 0; k &amp;lt; xmlReader.AttributeCount; k++)
                                {
                                    xmlReader.MoveToAttribute(k);

                                    string value = xmlReader.Value;

                                    if (_model.RemoveCommonDefaults)
                                    {
                                        if (!AttributeValuePair.IsCommonDefault(elementName, xmlReader.Name, value))
                                        {
                                            attributes.Add(new AttributeValuePair(elementName, xmlReader.Name, value));
                                        }
                                    }
                                    else
                                    {
                                        attributes.Add(new AttributeValuePair(elementName, xmlReader.Name, value));
                                    }
                                }

                                if (_model.ReorderAttributes)
                                {
                                    attributes.Sort();
                                }

                                xml = &quot;&quot;;
                                string str3 = &quot;&quot;;
                                int depth = xmlReader.Depth;

                                //str3 = str3 + IndentString;

                                for (int j = 0; j &amp;lt; depth; j++)
                                {
                                    xml = xml + IndentString;
                                }

                                foreach (AttributeValuePair a in attributes)
                                {
                                    string str7 = str;

                                    if (attributes.Count &amp;gt; _model.AttributeCountTolerance &amp;&amp; !AttributeValuePair.ForceNoLineBreaks(elementName))
                                    {
                                        // break up attributes into different lines
                                        str = str7 + &quot;\r\n&quot; + xml + str3 + a.Name + &quot;=\&quot;&quot; + a.Value + &quot;\&quot;&quot;;
                                    }
                                    else
                                    {
                                        // attributes on one line
                                        str = str7 + &quot; &quot; + a.Name + &quot;=\&quot;&quot; + a.Value + &quot;\&quot;&quot;;
                                    }
                                }

                            }
                            if (isEmptyElement)
                            {
                                str = str + &quot;/&quot;;
                            }
                            str = str + &quot;&amp;gt;&quot;;
                            xmlReader.Read();
                            continue;
                        Label_02F4:
                            xml = xml + IndentString;
                            num6++;
                        EndElement:
                            if (num6 &amp;lt; xmlReader.Depth)
                            {
                                goto Label_02F4;
                            }
                            string str8 = str;
                            str = str8 + &quot;\r\n&quot; + xml + &quot;&amp;lt;/&quot; + xmlReader.Name + &quot;&amp;gt;&quot;;
                            xmlReader.Read();
                            continue;
                        Label_037A:
                            xml = xml + &quot;    &quot;;
                            num7++;
                        ProcessingInstruction:
                            if (num7 &amp;lt; xmlReader.Depth)
                            {
                                goto Label_037A;
                            }
                            string str9 = str;
                            str = str9 + &quot;\r\n&quot; + xml + &quot;&amp;lt;?Mapping &quot; + xmlReader.Value + &quot; ?&amp;gt;&quot;;
                            xmlReader.Read();
                            continue;

                        Comment:

                            if (num8 &amp;lt; xmlReader.Depth)
                            {
                                xml = xml + IndentString;
                                num8++;
                            }
                            str = str + &quot;\r\n&quot; + xml + &quot;&amp;lt;!--&quot; + xmlReader.Value + &quot;--&amp;gt;&quot;;

                            xmlReader.Read();
                            continue;

                        Other:
                            xmlReader.Read();
                        }

                        xmlReader.Close();

                        result = str;
                    }
                }
            }
            return result.Replace(&quot;¬¬&quot;, &quot;&amp;&quot;);

        }

        private class AttributeValuePair : IComparable
        {
            public string Name = &quot;&quot;;
            public string Value = &quot;&quot;;
            public AttributeType AttributeType = AttributeType.Other;

            public AttributeValuePair(string elementname, string name, string value)
            {
                Name = name;
                Value = value;

                // compute the AttributeType
                if (name.StartsWith(&quot;xmlns&quot;))
                {
                    AttributeType = AttributeType.Namespace;

                }
                else
                {
                    switch (name)
                    {
                        case &quot;Key&quot;:
                        case &quot;x:Key&quot;:
                            AttributeType = AttributeType.Key;
                            break;

                        case &quot;Name&quot;:
                        case &quot;x:Name&quot;:
                            AttributeType = AttributeType.Name;
                            break;

                        case &quot;x:Class&quot;:
                            AttributeType = AttributeType.Class;
                            break;

                        case &quot;Canvas.Top&quot;:
                        case &quot;Canvas.Left&quot;:
                        case &quot;Canvas.Bottom&quot;:
                        case &quot;Canvas.Right&quot;:
                        case &quot;Grid.Row&quot;:
                        case &quot;Grid.RowSpan&quot;:
                        case &quot;Grid.Column&quot;:
                        case &quot;Grid.ColumnSpan&quot;:
                            AttributeType = AttributeType.AttachedLayout;
                            break;

                        case &quot;Width&quot;:
                        case &quot;Height&quot;:
                        case &quot;MaxWidth&quot;:
                        case &quot;MinWidth&quot;:
                        case &quot;MinHeight&quot;:
                        case &quot;MaxHeight&quot;:
                            AttributeType = AttributeType.CoreLayout;
                            break;

                        case &quot;Margin&quot;:
                        case &quot;VerticalAlignment&quot;:
                        case &quot;HorizontalAlignment&quot;:
                        case &quot;Panel.ZIndex&quot;:
                            AttributeType = AttributeType.StandardLayout;
                            break;

                        case &quot;mc:Ignorable&quot;:
                        case &quot;d:IsDataSource&quot;:
                        case &quot;d:LayoutOverrides&quot;:
                        case &quot;d:IsStaticText&quot;:

                            AttributeType = AttributeType.BlendGoo;
                            break;

                        default:
                            AttributeType = AttributeType.Other;
                            break;
                    }
                }
            }

            #region IComparable Members

            public int CompareTo(object obj)
            {
                AttributeValuePair other = obj as AttributeValuePair;

                if (other != null)
                {
                    if (this.AttributeType == other.AttributeType)
                    {
                        // some common special cases where we want things to be out of the normal order

                        if (this.Name.Equals(&quot;StartPoint&quot;) &amp;&amp; other.Name.Equals(&quot;EndPoint&quot;)) return -1;
                        if (this.Name.Equals(&quot;EndPoint&quot;) &amp;&amp; other.Name.Equals(&quot;StartPoint&quot;)) return 1;

                        if (this.Name.Equals(&quot;Width&quot;) &amp;&amp; other.Name.Equals(&quot;Height&quot;)) return -1;
                        if (this.Name.Equals(&quot;Height&quot;) &amp;&amp; other.Name.Equals(&quot;Width&quot;)) return 1;

                        if (this.Name.Equals(&quot;Offset&quot;) &amp;&amp; other.Name.Equals(&quot;Color&quot;)) return -1;
                        if (this.Name.Equals(&quot;Color&quot;) &amp;&amp; other.Name.Equals(&quot;Offset&quot;)) return 1;

                        if (this.Name.Equals(&quot;TargetName&quot;) &amp;&amp; other.Name.Equals(&quot;Property&quot;)) return -1;
                        if (this.Name.Equals(&quot;Property&quot;) &amp;&amp; other.Name.Equals(&quot;TargetName&quot;)) return 1;

                        return Name.CompareTo(other.Name);
                    }
                    else
                    {
                        return this.AttributeType.CompareTo(other.AttributeType);
                    }
                }

                return 0;
            }

            public static bool IsCommonDefault(string elementname, string name, string value)
            {

                if (
                    (name == &quot;HorizontalAlignment&quot; &amp;&amp; value == &quot;Stretch&quot;) ||
                    (name == &quot;VerticalAlignment&quot; &amp;&amp; value == &quot;Stretch&quot;) ||
                    (name == &quot;Margin&quot; &amp;&amp; value == &quot;0&quot;) ||
                    (name == &quot;Margin&quot; &amp;&amp; value == &quot;0,0,0,0&quot;) ||
                    (name == &quot;Opacity&quot; &amp;&amp; value == &quot;1&quot;) ||
                    (name == &quot;FontWeight&quot; &amp;&amp; value == &quot;{x:Null}&quot;) ||
                    (name == &quot;Background&quot; &amp;&amp; value == &quot;{x:Null}&quot;) ||
                    (name == &quot;Stroke&quot; &amp;&amp; value == &quot;{x:Null}&quot;) ||
                    (name == &quot;Fill&quot; &amp;&amp; value == &quot;{x:Null}&quot;) ||
                    (name == &quot;Visibility&quot; &amp;&amp; value == &quot;Visible&quot;) ||
                    (name == &quot;Grid.RowSpan&quot; &amp;&amp; value == &quot;1&quot;) ||
                    (name == &quot;Grid.ColumnSpan&quot; &amp;&amp; value == &quot;1&quot;) ||
                    (name == &quot;BasedOn&quot; &amp;&amp; value == &quot;{x:Null}&quot;) ||
                    (elementname != &quot;ColumnDefinition&quot; &amp;&amp; elementname != &quot;RowDefinition&quot; &amp;&amp; name == &quot;Width&quot; &amp;&amp; value == &quot;Auto&quot;) ||
                    (elementname != &quot;ColumnDefinition&quot; &amp;&amp; elementname != &quot;RowDefinition&quot; &amp;&amp; name == &quot;Height&quot; &amp;&amp; value == &quot;Auto&quot;)

                    )
                {
                    return true;
                }

                return false;
            }

            public static bool ForceNoLineBreaks(string elementname)
            {
                if (
                    (elementname == &quot;RadialGradientBrush&quot;) ||
                    (elementname == &quot;GradientStop&quot;) ||
                    (elementname == &quot;LinearGradientBrush&quot;) ||
                    (elementname == &quot;ScaleTransfom&quot;) ||
                    (elementname == &quot;SkewTransform&quot;) ||
                    (elementname == &quot;RotateTransform&quot;) ||
                    (elementname == &quot;TranslateTransform&quot;) ||
                    (elementname == &quot;Trigger&quot;) ||
                    (elementname == &quot;Setter&quot;)
                    )
                {
                    return true;
                }
                else
                {
                    return false;
                }

            }

            #endregion
        }

        // note that these are declared in priority order for easy sorting
        private enum AttributeType
        {
            Key = 10,
            Name = 20,
            Class = 30,
            Namespace = 40,
            CoreLayout = 50,
            AttachedLayout = 60,
            StandardLayout = 70,
            Other = 1000,
            BlendGoo = 2000
        }
    }
}
</pre>
<p>I appreciate that this is a long listing, but don&#8217;t worry about what&#8217;s going on inside. To hook into the MoXAML plugin architecture, only one line in there is really important:to be picked up</p>
<pre class="brush: csharp;">
public partial class ScrubberCommandBase : CommandBase
</pre>
<p>By inheriting from CommandBase, MoXAML picks the command up because CommandBase implements ICommandBase. The cunning thing about MoXAML is that it uses MEF which allows you to mark interfaces so that any implementations of the interface will automatically be picked up. Well, we have most of the infrastructure in place &#8211; all we actually need to do is write the actual command. You&#8217;ll be surprised how little that actually takes:</p>
<pre class="brush: csharp;">
using MoXAML.Infrastructure;

namespace MoXAML.Scrubber
{
    public class ScrubFileCommand : ScrubberCommandBase
    {
        public ScrubFileCommand()
            : base()
        {
            CommandName = &quot;ScrubFile&quot;;
            Caption = &quot;Scrubber&quot;;
            ParentCommandBar.Add(CommandBarType.XamlContextMenu);
        }

        public override void Execute()
        {
            base.Execute();
            ParseFile(Application.ActiveDocument.FullName);
        }
    }
}
</pre>
<p>Let&#8217;s break it down. In the constructor, we&#8217;re giving the command a unique name that MoXAML uses to track whether or not the command was previously installed. The Caption is what will actually appear in the menu, and the line ParentCommandBar.Add is used to add the command to the appropriate menu.</p>
<p>Finally, we actually need our command to do something, and that&#8217;s where the Execute method comes in &#8211; MoXAML uses this method to execute the command, so it&#8217;s the place to hook our command logic to. In this case, we&#8217;re hooking into the ParseFile method in the class we inherit from.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/peteohanlon.wordpress.com/391/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/peteohanlon.wordpress.com/391/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/peteohanlon.wordpress.com/391/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/peteohanlon.wordpress.com/391/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/peteohanlon.wordpress.com/391/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/peteohanlon.wordpress.com/391/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/peteohanlon.wordpress.com/391/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/peteohanlon.wordpress.com/391/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/peteohanlon.wordpress.com/391/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/peteohanlon.wordpress.com/391/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/peteohanlon.wordpress.com/391/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/peteohanlon.wordpress.com/391/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/peteohanlon.wordpress.com/391/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/peteohanlon.wordpress.com/391/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=peteohanlon.wordpress.com&amp;blog=1230283&amp;post=391&amp;subd=peteohanlon&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://peteohanlon.wordpress.com/2011/09/13/adding-to-moxaml/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/b13854c10ce07efee2062f13d9334cba?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">Pete O'Hanlon</media:title>
		</media:content>
	</item>
		<item>
		<title>MoXAML goes MefXAML</title>
		<link>http://peteohanlon.wordpress.com/2011/09/06/moxaml-goes-mefxaml/</link>
		<comments>http://peteohanlon.wordpress.com/2011/09/06/moxaml-goes-mefxaml/#comments</comments>
		<pubDate>Tue, 06 Sep 2011 20:53:02 +0000</pubDate>
		<dc:creator>peteohanlon</dc:creator>
				<category><![CDATA[MoXAML]]></category>
		<category><![CDATA[MoXAMLPowerToys]]></category>

		<guid isPermaLink="false">http://peteohanlon.wordpress.com/?p=387</guid>
		<description><![CDATA[First of all, I must apologise that it&#8217;s taken me so long to release the new version of MoXAML. Unfortunately it&#8217;s taken a back burner to other projects that I have going on, so it&#8217;s been lower down on my priority list than I would have liked. Saying that, I have been tinkering with a [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=peteohanlon.wordpress.com&amp;blog=1230283&amp;post=387&amp;subd=peteohanlon&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>First of all, I must apologise that it&#8217;s taken me so long to release the new version of MoXAML. Unfortunately it&#8217;s taken a back burner to other projects that I have going on, so it&#8217;s been lower down on my priority list than I would have liked. Saying that, I have been tinkering with a new version and making changes to the internal architecture to make it easier for me to add new functionality to it. MoXAML has now got the MEF mojo underpinning it.</p>
<p>A feature of the original version of MoXAML that I was never happy with was the way I had to register commands so that they will appear in the menus. To be honest, the code was a complete mess and it offended my sensibilities whenever I looked at it. Well, the new version has completely changed that. I&#8217;ve added a MoXAML.Infrastructure library that provides a lot of the underpinnings of MoXAML registration; all we need to do is derive from the CommandBase class in this library and with just a couple of commands we are good to go.</p>
<p>First of all, we need to add a unique command name, the menu text and the parent command that we want to show this command in. This just gets added into the constructor likes so:</p>
<pre class="brush: csharp;">
public MyConstructor()
{
  CommandName = &quot;MyUniqueCommandName&quot;;
  Caption = &quot;Menu text&quot;;
  ParentCommandBar.Add(CommandBarType.SolutionContextMenu);
}
</pre>
<p>Now, to add the code to actually do the work, just override the Execute method and add in the functionality that you want to perform.</p>
<p>In a future post, I&#8217;ll cover creating an add-in from scratch and talk about the API that&#8217;s now been exposed in MoXAML. To get the latest version of MoXAML, please check it out <a href="http://peteohanlon.wordpress.com/moxaml-power-toys/">here</a>.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/peteohanlon.wordpress.com/387/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/peteohanlon.wordpress.com/387/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/peteohanlon.wordpress.com/387/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/peteohanlon.wordpress.com/387/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/peteohanlon.wordpress.com/387/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/peteohanlon.wordpress.com/387/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/peteohanlon.wordpress.com/387/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/peteohanlon.wordpress.com/387/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/peteohanlon.wordpress.com/387/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/peteohanlon.wordpress.com/387/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/peteohanlon.wordpress.com/387/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/peteohanlon.wordpress.com/387/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/peteohanlon.wordpress.com/387/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/peteohanlon.wordpress.com/387/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=peteohanlon.wordpress.com&amp;blog=1230283&amp;post=387&amp;subd=peteohanlon&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://peteohanlon.wordpress.com/2011/09/06/moxaml-goes-mefxaml/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/b13854c10ce07efee2062f13d9334cba?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">Pete O'Hanlon</media:title>
		</media:content>
	</item>
		<item>
		<title>It&#8217;s time to dock with the mothership</title>
		<link>http://peteohanlon.wordpress.com/2011/08/17/its-time-to-dock-with-the-mothership/</link>
		<comments>http://peteohanlon.wordpress.com/2011/08/17/its-time-to-dock-with-the-mothership/#comments</comments>
		<pubDate>Wed, 17 Aug 2011 20:10:16 +0000</pubDate>
		<dc:creator>peteohanlon</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[VS Live]]></category>

		<guid isPermaLink="false">http://peteohanlon.wordpress.com/?p=381</guid>
		<description><![CDATA[It seems that the many headed Hydra that is VS Live is coming round again in October, and it&#8217;s bigger and better than ever. If you thought it was good before, you haven&#8217;t seen anything yet. While I can&#8217;t promise that attending it will make you more successful with members of whichever sex you prefer, [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=peteohanlon.wordpress.com&amp;blog=1230283&amp;post=381&amp;subd=peteohanlon&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>It seems that the many headed Hydra that is <a href="http://vslive.com/events/redmond-2011/home.aspx">VS Live</a> is coming round again in October, and it&#8217;s bigger and better than ever. If you thought it was good before, you haven&#8217;t seen anything yet.</p>
<p>While I can&#8217;t promise that attending it will make you more successful with members of whichever sex you prefer, I can tell you that some of my favourite speakers are going to be there. Rachel Appel will be delivering talks on creating data driven web sites with WebMatrix and Razor, a dive into how Orchard CMS works and will finish off with a high dive off Microsoft 1 into a thimble containing an inch of water.</p>
<p>If you think that&#8217;s impressive, Pete Brown will be delivering a whole host of XAMLicious goodness and rumour has it that he will do this tied up in chains, dangling upside down in a big box of water, wearing nothing other than a goose-fat thong. You owe it to yourself to get along to the Redmond mothership and catch these outstanding talks, and a whole lot more.</p>
<p>Disclaimer: Some of this shizzle is made up, but the bit about the <a href="http://vslive.com/events/redmond-2011/speakers/speaker-list.aspx">great speaker</a>s and the topics they&#8217;ll be talking about is 100% straight up.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/peteohanlon.wordpress.com/381/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/peteohanlon.wordpress.com/381/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/peteohanlon.wordpress.com/381/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/peteohanlon.wordpress.com/381/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/peteohanlon.wordpress.com/381/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/peteohanlon.wordpress.com/381/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/peteohanlon.wordpress.com/381/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/peteohanlon.wordpress.com/381/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/peteohanlon.wordpress.com/381/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/peteohanlon.wordpress.com/381/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/peteohanlon.wordpress.com/381/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/peteohanlon.wordpress.com/381/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/peteohanlon.wordpress.com/381/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/peteohanlon.wordpress.com/381/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=peteohanlon.wordpress.com&amp;blog=1230283&amp;post=381&amp;subd=peteohanlon&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://peteohanlon.wordpress.com/2011/08/17/its-time-to-dock-with-the-mothership/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/b13854c10ce07efee2062f13d9334cba?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">Pete O'Hanlon</media:title>
		</media:content>
	</item>
		<item>
		<title>You see, you don&#8217;t always need code behind.</title>
		<link>http://peteohanlon.wordpress.com/2011/06/07/you-see-you-dont-always-need-code-behind/</link>
		<comments>http://peteohanlon.wordpress.com/2011/06/07/you-see-you-dont-always-need-code-behind/#comments</comments>
		<pubDate>Tue, 07 Jun 2011 20:57:51 +0000</pubDate>
		<dc:creator>peteohanlon</dc:creator>
				<category><![CDATA[behavior]]></category>
		<category><![CDATA[Windows Presentation Foundation, Action]]></category>
		<category><![CDATA[attached behavior]]></category>
		<category><![CDATA[WPF]]></category>

		<guid isPermaLink="false">http://peteohanlon.wordpress.com/?p=371</guid>
		<description><![CDATA[By now you should be aware that I&#8217;m a big fan of attached behaviors. In this post, I&#8217;m going to demonstrate a simple technique to add resize and close functionality to window buttons when you want to custom draw your window chrome without having to add code behind the window. This is going to be [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=peteohanlon.wordpress.com&amp;blog=1230283&amp;post=371&amp;subd=peteohanlon&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>By now you should be aware that I&#8217;m a big fan of attached behaviors. In this post, I&#8217;m going to demonstrate a simple technique to add resize and close functionality to window buttons when you want to custom draw your window chrome without having to add code behind the window. This is going to be a quick post, because it&#8217;s just so darned easy.</p>
<p>Note: Originally I was using Application.Current.MainWindow to retrieve the window as I only ever apply this trick to the application main window. Mike Strobel suggested using Window.GetWindow instead to retrieve the logical window for the button, just in case it was in a separate window. I&#8217;ve adjusted the code sample here to demonstrate this as it makes this more reusable. Thanks Mike.</p>
<pre class="brush: csharp;">
namespace AttachedTitleButtonsSample
{
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Interactivity;

    /// &lt;summary&gt;
    /// Attach this behaviour to a button to enable a button to change the window state without
    /// having to write any code behind the view.
    /// &lt;/summary&gt;
    public partial class TitleButtonBehavior : Behavior&lt;Button&gt;
    {
        /// &lt;summary&gt;
        /// The tile button action to apply.
        /// &lt;/summary&gt;
        public enum TitleButtonAction
        {
            /// &lt;summary&gt;
            /// Close the application
            /// &lt;/summary&gt;
            Close,
            /// &lt;summary&gt;
            /// Maximize the application
            /// &lt;/summary&gt;
            Maximize,
            /// &lt;summary&gt;
            /// Minimize the application
            /// &lt;/summary&gt;
            Minimize,
            /// &lt;summary&gt;
            /// Reset the application to normal
            /// &lt;/summary&gt;
            Normal
        }

        /// &lt;summary&gt;
        /// Gets or sets the button behavior.
        /// &lt;/summary&gt;
        public TitleButtonAction ButtonBehavior { get; set; }

        /// &lt;summary&gt;
        /// Add the click handler when this is attached.
        /// &lt;/summary&gt;
        protected override void OnAttached()
        {
            this.AssociatedObject.Click += AssociatedObject_Click;
            base.OnAttached();
        }

        /// &lt;summary&gt;
        /// Remove the click handler when this is detached.
        /// &lt;/summary&gt;
        protected override void OnDetaching()
        {
            this.AssociatedObject.Click -= AssociatedObject_Click;
            base.OnDetaching();
        }

        /// &lt;summary&gt;
        /// Change the window state when the button is clicked.
        /// &lt;/summary&gt;
        void AssociatedObject_Click(object sender, System.Windows.RoutedEventArgs e)
        {
            Window window = Window.GetWindow(AssociatedObject);
            switch (ButtonBehavior)
            {
                case TitleButtonAction.Close:
                    window.Close();
                    break;
                case TitleButtonAction.Maximize:
                    window.WindowState = WindowState.Maximized;
                    break;
                case TitleButtonAction.Minimize:
                    window.WindowState = WindowState.Minimized;
                    break;
                case TitleButtonAction.Normal:
                    window.WindowState = WindowState.Normal;
                    break;
            }
        }
    }
}
</pre>
<p>Basically, all you need to do is create an attached behavior that hooks up to the Click event of the button and sets the size based on the appropriate value from the enumeration.</p>
<p><strong>Sample application</strong><br />
I&#8217;ve attached a sample application that demonstrates this technique in action. As always, when you download the sample, you&#8217;ll need to rename it from a doc to a zip file.</p>
<p><a href='http://peteohanlon.files.wordpress.com/2011/06/attachedtitlebuttonssamplezip.doc'>AttachedTitleButtonsSampleZip</a></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/peteohanlon.wordpress.com/371/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/peteohanlon.wordpress.com/371/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/peteohanlon.wordpress.com/371/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/peteohanlon.wordpress.com/371/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/peteohanlon.wordpress.com/371/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/peteohanlon.wordpress.com/371/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/peteohanlon.wordpress.com/371/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/peteohanlon.wordpress.com/371/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/peteohanlon.wordpress.com/371/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/peteohanlon.wordpress.com/371/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/peteohanlon.wordpress.com/371/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/peteohanlon.wordpress.com/371/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/peteohanlon.wordpress.com/371/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/peteohanlon.wordpress.com/371/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=peteohanlon.wordpress.com&amp;blog=1230283&amp;post=371&amp;subd=peteohanlon&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://peteohanlon.wordpress.com/2011/06/07/you-see-you-dont-always-need-code-behind/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/b13854c10ce07efee2062f13d9334cba?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">Pete O'Hanlon</media:title>
		</media:content>
	</item>
		<item>
		<title>So where do we go from here?</title>
		<link>http://peteohanlon.wordpress.com/2011/06/03/so-where-do-we-go-from-here/</link>
		<comments>http://peteohanlon.wordpress.com/2011/06/03/so-where-do-we-go-from-here/#comments</comments>
		<pubDate>Fri, 03 Jun 2011 19:45:07 +0000</pubDate>
		<dc:creator>peteohanlon</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://peteohanlon.wordpress.com/?p=365</guid>
		<description><![CDATA[Well, Microsoft has finally unveiled what is commonly known as Windows 8. If you have been learning Kung Fu in a secret Tibetan monastery or yak fishing off the coast of Antarctica, you may have missed the announcements this week and the blizzard of opinion and talking heads pronouncements. To some it&#8217;s the death knell [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=peteohanlon.wordpress.com&amp;blog=1230283&amp;post=365&amp;subd=peteohanlon&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Well, Microsoft has finally unveiled what is commonly known as <a href="http://www.youtube.com/watch?v=p92QfWOw88I" target="_blank">Windows 8</a>. If you have been learning Kung Fu in a secret Tibetan monastery or yak fishing off the coast of Antarctica, you may have missed the announcements this week and the blizzard of opinion and talking heads pronouncements. To some it&#8217;s the death knell of Windows, to others it&#8217;s a brave and bold move. Whatever your take, one thing is clear, the Metro UI represents a dramatic step forward for Windows applications.</p>
<p>First of all, let me make it clear that the Metro UI is not the only UI that you can use in Windows. It&#8217;s a great choice for Tablets, and if you&#8217;ve used a Windows Phone, you&#8217;ll know just how useful it really is (I love my Live Tiles), but if you want to use a non touch UI you still have the Aero interface to provide that familiar gooey goodness. What the new version of Windows represents is a step out to other processors and technologies; a move beyond Wintel, and this has to be good news for all concerned. As a developer, the exciting thing is that I should be able to write software that targets tablets, phones and PCs all from the same environment.</p>
<p>Let me clear something else up. Despite what you may think you have heard, Microsoft is not abandoning all other languages and technologies in favour of HTML 5 and JavaScript. Yes, this represents an important plank in Microsoft&#8217;s strategy to write once run-anywhere, and have applications run in the cloud. I was one heck of an HTML 5 sceptic, but having looked into HTML 5 and WCF vNext, I can&#8217;t believe just how good developing for it can be in the MS stack &#8211; I will be writing more on this in the future; take it from me, you&#8217;re going to love it. The thing is, though, while this is great in webby, cloudy environments, HTML apps just don&#8217;t mut the custard in desktop environments, or in applications where you really don&#8217;t want your IP exposed. This is why I&#8217;m excited about the future of technologies like .NET, Silverlight, WPF and C++. Microsoft has made a huge investment in .NET and XAML, and it seems incredibly unlikely that they will alienate virtually their entire developer ecosystem &#8211; and rumour has it that Win C++ is going to have a big impact in Windows 8.</p>
<p>Indeed, Microsoft&#8217;s biggest problem still seems to be that it isn&#8217;t communicating this information effectively. They get so excited about all the new stuff that&#8217;s coming, they don&#8217;t mention the existing stuff; after all, why should they? They assume that people realise that they aren&#8217;t cutting their own noses off, and forget that people remember the history of failed tech. Let me assure you, from conversations I&#8217;ve had, and from talking to those in the know, your technological investment is safe. Your apps may look different in the future, and respond to different inputs, so you may need to learn some new APIs, but that should excite you, not frighten you.</p>
<p>Finally, let me quote the great <a href="http://jmorrill.hjtcentral.com/" target="_blank">Jeremiah Morrill</a>:</p>
<p><em>&#8220;Anyways, why is everyone so surprised about the annoucement?  People have been saying this was going to be a feature of Win8 for at least 5 or 6 months <img src='http://s1.wp.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </em></p>
<p><em>I think it&#8217;s important to remember what Ballmer said in his Swiss keynote.  That Win8 applications can be written using, C++, C# and JS.  He was very careful to NOT mention a framework, only languages.  Now there are is a lot of &#8220;Will it run Silverlight?&#8221; or &#8220;Will it run WPF?&#8221;.  Microsoft will respond with &#8220;Yeah, its Windows&#8221;.  This is true.  They did demo Win8 also running &#8220;traditional&#8221; applications.</em></p>
<p><em>I think we should be asking:  What technologies can I use to make these new immersive Win8 applications?</em></p>
<p><em>The other question I would ask, mostly to devs is, &#8220;Does this new thing perform better than Silverlight/WPF at making fluid user interfaces?&#8221;  If so, besides backwards compatibility, what advantages does Silverlight/WPF have over this new thing?  Will Silverlight (or WPF) still be an island of richness, or an island of relative choppiness and CPU tax?</em></p>
<p><em>One thing I can say for certain, is XAML is part of Microsoft DNA.  They have promised us our investment in XAML is safe, over and over.  What I&#8217;m not certain about is, what is our investment defined as?  Knowledge/familiarity or our actual code?  Will there be a solid upgrade path, or will we be left dumping old code?  My advice is we should all be patient until Sept.  There&#8217;s just too many questions that cannot be answered with a Win8 demo that wasn&#8217;t geared for devs.&#8221;</em></p>
<p>Possibly the wisest words you&#8217;ll hear on the subject.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/peteohanlon.wordpress.com/365/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/peteohanlon.wordpress.com/365/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/peteohanlon.wordpress.com/365/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/peteohanlon.wordpress.com/365/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/peteohanlon.wordpress.com/365/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/peteohanlon.wordpress.com/365/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/peteohanlon.wordpress.com/365/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/peteohanlon.wordpress.com/365/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/peteohanlon.wordpress.com/365/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/peteohanlon.wordpress.com/365/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/peteohanlon.wordpress.com/365/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/peteohanlon.wordpress.com/365/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/peteohanlon.wordpress.com/365/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/peteohanlon.wordpress.com/365/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=peteohanlon.wordpress.com&amp;blog=1230283&amp;post=365&amp;subd=peteohanlon&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://peteohanlon.wordpress.com/2011/06/03/so-where-do-we-go-from-here/feed/</wfw:commentRss>
		<slash:comments>46</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/b13854c10ce07efee2062f13d9334cba?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">Pete O'Hanlon</media:title>
		</media:content>
	</item>
		<item>
		<title>Losing your identity</title>
		<link>http://peteohanlon.wordpress.com/2011/05/13/losing-your-identity/</link>
		<comments>http://peteohanlon.wordpress.com/2011/05/13/losing-your-identity/#comments</comments>
		<pubDate>Fri, 13 May 2011 13:47:07 +0000</pubDate>
		<dc:creator>peteohanlon</dc:creator>
				<category><![CDATA[Silverlight]]></category>
		<category><![CDATA[Windows Presentation Foundation]]></category>
		<category><![CDATA[identity]]></category>
		<category><![CDATA[sequence]]></category>
		<category><![CDATA[user interface]]></category>

		<guid isPermaLink="false">http://peteohanlon.wordpress.com/?p=362</guid>
		<description><![CDATA[Recently I&#8217;ve had time to revisit the question of identity columns (or sequences if you like). A client had come up with a screen that they really wanted us to incorporate in to their application, and the design of it had been done by some of their business analysts. One of the fields that was [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=peteohanlon.wordpress.com&amp;blog=1230283&amp;post=362&amp;subd=peteohanlon&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Recently I&#8217;ve had time to revisit the question of identity columns (or sequences if you like). A client had come up with a screen that they really wanted us to incorporate in to their application, and the design of it had been done by some of their business analysts. One of the fields that was present on the screen was a unique identifier. Now, being a bit of a nosy so and so, I wanted to know where the unique identifier came from and was told that it was just an identify column padded out to 9 digits with the letter C in front of it (apparently C stood for client). This lead me to have an interesting discussion with the analysts:</p>
<p>Me: Why are we taking up valuable screen real estate with this field?<br />
Analyst: It&#8217;s on there so the user knows the id of the customer.<br />
Me: Fair enough. Can they search on this field?<br />
Analyst: No.<br />
Me: Does the client know their id value?<br />
Analyst: No<br />
Me: So, what purpose does this field have?<br />
Analyst (in a sneering tone): It&#8217;s there to ensure referential integrity, and to give us a unique value to update the client on. Don&#8217;t you know anything about relational design?</p>
<p>Now, at this point, you might imagine that I was less than pleased with the design based on my questioning it, but why was I so put off by this field? First of all, when you are designing a screen, you have to ask yourself what the user will be doing with the screen. How will they interact with it? What do you need to put on there to let the user do their job? By putting an identifier on the screen that had no other purpose than to hold the identifier they were going to update the record against, the analysts had made a classic UI design. This, by the way, is why you need to have a User experience expert on your project, and why users, not just analysts, should have input into the UI.</p>
<p>By putting this field onto the screen, the analyst had given it an importance that it didn&#8217;t have. It&#8217;s a distraction for the user; always try to put on the screen the information that they need to do their job, and give them an easy flow through to discover additional information if they need it. With newer technologies like Silverlight and WPF, it&#8217;s incredibly easy to design attractive screens that show and hide information in visually appealing ways, so it&#8217;s a shame not to take advantage of these features while you can.</p>
<p>Don&#8217;t get me wrong, there can be a case for putting identifiers on a screen. If the user can search on the identifier, or the client could be reasonably expected to know the identifier, then it&#8217;s perfectly valid to have these on the screen. Nine times out of ten though, if the value is an auto-generated identity or sequence and it&#8217;s sole purpose is to enable referential integrity, then you don&#8217;t need to display it.</p>
<p>Please remember, when you have a piece of UI design in front of you, question everything. Ask why things are taking up valuable screen real estate. Ask if there are other options, such as flyouts, that could be used to present the additional information in none-intrusive ways. Most importantly of all, ask the users what they need to see &#8211; they are the experts after all.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/peteohanlon.wordpress.com/362/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/peteohanlon.wordpress.com/362/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/peteohanlon.wordpress.com/362/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/peteohanlon.wordpress.com/362/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/peteohanlon.wordpress.com/362/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/peteohanlon.wordpress.com/362/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/peteohanlon.wordpress.com/362/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/peteohanlon.wordpress.com/362/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/peteohanlon.wordpress.com/362/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/peteohanlon.wordpress.com/362/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/peteohanlon.wordpress.com/362/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/peteohanlon.wordpress.com/362/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/peteohanlon.wordpress.com/362/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/peteohanlon.wordpress.com/362/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=peteohanlon.wordpress.com&amp;blog=1230283&amp;post=362&amp;subd=peteohanlon&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://peteohanlon.wordpress.com/2011/05/13/losing-your-identity/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/b13854c10ce07efee2062f13d9334cba?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">Pete O'Hanlon</media:title>
		</media:content>
	</item>
		<item>
		<title>Keeping it regular</title>
		<link>http://peteohanlon.wordpress.com/2011/04/03/keeping-it-regular/</link>
		<comments>http://peteohanlon.wordpress.com/2011/04/03/keeping-it-regular/#comments</comments>
		<pubDate>Sun, 03 Apr 2011 20:07:03 +0000</pubDate>
		<dc:creator>peteohanlon</dc:creator>
				<category><![CDATA[behavior]]></category>
		<category><![CDATA[Regular Expressions]]></category>
		<category><![CDATA[Windows Presentation Foundation]]></category>
		<category><![CDATA[attached behavior]]></category>

		<guid isPermaLink="false">http://peteohanlon.wordpress.com/?p=359</guid>
		<description><![CDATA[Last week I posted an example of using a regular expression to control the input of numbers into a TextBox. A couple of my fellow disciples commented that they&#8217;d just use a regular expression Behavior or DP to control the input of the text. Now, there are a couple of reasons that I&#8217;d use the [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=peteohanlon.wordpress.com&amp;blog=1230283&amp;post=359&amp;subd=peteohanlon&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Last week I posted an example of using a regular expression to <a href="http://peteohanlon.wordpress.com/2011/03/30/getting-control-of-your-numbers/">control the input of numbers into a TextBox</a>. A couple of my fellow disciples commented that they&#8217;d just use a regular expression Behavior or DP to control the input of the text. Now, there are a couple of reasons that I&#8217;d use the dedicated NumericTextBoxBehavior.</p>
<p>The first reason is that it&#8217;s a simple control for those that aren&#8217;t comfortable writing regular expressions. After all, why should you write a complex regular expression when I can write one for you? </p>
<p>The second reason is that the numeric control is internationalised from the get-go. I&#8217;ve already take care of sorting out the whole internationalised decimal place issue, so you don&#8217;t have to worry about it with your regular expression.</p>
<p>Saying that, the regular expression behavior is a cracking idea, and one I could kick myself for not thinking of earlier. So, in order to add regular expression functionality in your TextBox, all you need do is add the following code:</p>
<pre class="brush: csharp;">
namespace Goldlight.Base.Behaviors
{
  using System.Linq;
  using System.Windows.Controls;
  using System.Windows.Interactivity;
  using System.Windows;
  using System.Windows.Input;
  using System.Text.RegularExpressions;

  /// &lt;summary&gt;
  /// Apply this behavior to a TextBox to ensure that input matches a regular
  /// expression.
  /// &lt;para&gt;
  /// &lt;remarks&gt;
  /// In the view, this behavior is attached in the following way:
  /// &lt;code&gt;
  /// &lt;TextBox Text=&quot;{Binding Price}&quot;&gt;
  ///   &lt;i:Interaction.Behaviors&gt;
  ///   &lt;gl:RegularExpressionTextBoxBehavior
  ///    Mask=&quot;^([\(]{1}[0-9]{3}[\)]{1}[ ]{1}[0-9]{3}[\-]{1}[0-9]{4})$&quot; /&gt;
  ///   &lt;/i:Interaction.Behaviors&gt;
  /// &lt;/TextBox&gt;
  /// &lt;/code&gt;
  /// &lt;para&gt;
  /// Add references to System.Windows.Interactivity to the view to use
  /// this behavior.
  /// &lt;/para&gt;
  /// &lt;/remarks&gt;
  public class RegularExpressionTextBoxBehavior : Behavior&lt;TextBox&gt;
  {
    /// &lt;summary&gt;
    /// Gets or sets the regular expression mask.
    /// &lt;/summary&gt;
    public string Mask { get; set; }

    #region Overrides
    protected override void OnAttached()
    {
      base.OnAttached();

      AssociatedObject.PreviewTextInput += AssociatedObject_PreviewTextInput;
#if !SILVERLIGHT
      DataObject.AddPastingHandler(AssociatedObject, OnClipboardPaste);
#endif
    }

    protected override void OnDetaching()
    {
      base.OnDetaching();
      AssociatedObject.PreviewTextInput -= AssociatedObject_PreviewTextInput;
#if !SILVERLIGHT
      DataObject.RemovePastingHandler(AssociatedObject, OnClipboardPaste);
#endif
    }
    #endregion

#if !SILVERLIGHT
    /// &lt;summary&gt;
    /// Handle paste operations into the textbox to ensure that the behavior
    /// is consistent with directly typing into the TextBox.
    /// &lt;/summary&gt;
    /// &lt;param name=&quot;sender&quot;&gt;The TextBox sender.&lt;/param&gt;
    /// &lt;param name=&quot;dopea&quot;&gt;Paste event arguments.&lt;/param&gt;
    /// &lt;remarks&gt;This operation is only available in WPF.&lt;/remarks&gt;
    private void OnClipboardPaste(object sender, DataObjectPastingEventArgs dopea)
    {
      string text = dopea.SourceDataObject.GetData(dopea.FormatToApply).ToString();

      if (!string.IsNullOrWhiteSpace(text) &amp;&amp; !Validate(text))
        dopea.CancelCommand();
    }
#endif

    /// &lt;summary&gt;
    /// Preview the text input.
    /// &lt;/summary&gt;
    /// &lt;param name=&quot;sender&quot;&gt;The TextBox sender.&lt;/param&gt;
    /// &lt;param name=&quot;e&quot;&gt;The composition event arguments.&lt;/param&gt;
    void AssociatedObject_PreviewTextInput(object sender, TextCompositionEventArgs e)
    {
      e.Handled = !Validate(e.Text);
    }

    /// &lt;summary&gt;
    /// Validate the contents of the textbox with the new content to see if it is
    /// valid.
    /// &lt;/summary&gt;
    /// &lt;param name=&quot;value&quot;&gt;The text to validate.&lt;/param&gt;
    /// &lt;returns&gt;True if this is valid, false otherwise.&lt;/returns&gt;
    protected bool Validate(string value)
    {
      TextBox textBox = AssociatedObject;

      string pre = string.Empty;
      string post = string.Empty;

      if (!string.IsNullOrWhiteSpace(textBox.Text))
      {
        pre = textBox.Text.Substring(0, textBox.SelectionStart);
        post = textBox.Text.Substring(textBox.SelectionStart + textBox.SelectionLength,
          textBox.Text.Length - (textBox.SelectionStart + textBox.SelectionLength));
      }
      else
      {
        pre = textBox.Text.Substring(0, textBox.CaretIndex);
        post = textBox.Text.Substring(textBox.CaretIndex,
          textBox.Text.Length - textBox.CaretIndex);
      }
      string test = string.Concat(pre, value, post);

      string pattern = Mask;

      if (string.IsNullOrWhiteSpace(pattern))
        return true;

      return new Regex(pattern).IsMatch(test);
    }
  }
}
</pre>
<p>As you can see, it&#8217;s similar in code to the other behaviour. The only real difference in it is that it has a Mask string which is used to add the regular expression text.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/peteohanlon.wordpress.com/359/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/peteohanlon.wordpress.com/359/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/peteohanlon.wordpress.com/359/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/peteohanlon.wordpress.com/359/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/peteohanlon.wordpress.com/359/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/peteohanlon.wordpress.com/359/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/peteohanlon.wordpress.com/359/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/peteohanlon.wordpress.com/359/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/peteohanlon.wordpress.com/359/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/peteohanlon.wordpress.com/359/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/peteohanlon.wordpress.com/359/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/peteohanlon.wordpress.com/359/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/peteohanlon.wordpress.com/359/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/peteohanlon.wordpress.com/359/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=peteohanlon.wordpress.com&amp;blog=1230283&amp;post=359&amp;subd=peteohanlon&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://peteohanlon.wordpress.com/2011/04/03/keeping-it-regular/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/b13854c10ce07efee2062f13d9334cba?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">Pete O'Hanlon</media:title>
		</media:content>
	</item>
		<item>
		<title>Getting control of your numbers</title>
		<link>http://peteohanlon.wordpress.com/2011/03/30/getting-control-of-your-numbers/</link>
		<comments>http://peteohanlon.wordpress.com/2011/03/30/getting-control-of-your-numbers/#comments</comments>
		<pubDate>Wed, 30 Mar 2011 19:37:51 +0000</pubDate>
		<dc:creator>peteohanlon</dc:creator>
				<category><![CDATA[behavior]]></category>
		<category><![CDATA[Windows Presentation Foundation]]></category>
		<category><![CDATA[attached behavior]]></category>
		<category><![CDATA[number]]></category>
		<category><![CDATA[numeric control]]></category>
		<category><![CDATA[WPF]]></category>

		<guid isPermaLink="false">http://peteohanlon.wordpress.com/?p=353</guid>
		<description><![CDATA[Today on Code Project, one of the regulars asked how to set up a textbox so that it only accepted a currency amount. He was concerned that there doesn&#8217;t seem to be a simple mechanism to limit the input of data so that it only accepted the relevant numeric amount. Well, this is a feature [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=peteohanlon.wordpress.com&amp;blog=1230283&amp;post=353&amp;subd=peteohanlon&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Today on Code Project, one of the regulars asked how to <a href="http://www.codeproject.com/Forums/1004257/Silverlight-WPF.aspx?fid=1004257&amp;tid=3835948">set up a textbox so that it only accepted a currency amount</a>. He was concerned that there doesn&#8217;t seem to be a simple mechanism to limit the input of data so that it only accepted the relevant numeric amount. Well, this is a feature I recently added into Goldlight, so I thought I&#8217;d post it here, along with an explanation of how it works.</p>
<p>Basically, and this will come as no surprise to you, it&#8217;s an Attached Behavior that you associate to the TextBox. There are many numeric only behaviors out there, so this one goes a little bit further. First of all, if you want, you can limit it to integers by setting AllowDecimal to false. If you want to limit it to a set number of decimal places, set DecimalLimit to the number of decimal places. If you don&#8217;t want to allow the developer to use negative numbers, set AllowNegatives to false. It&#8217;s that simple, so the solution to the problem would be to add the behaviour to the TextBox like this:</p>
<pre class="brush: xml;">
&lt;TextBox Text=&quot;{Binding Price}&quot;&gt;
  &lt;i:Interaction.Behaviors&gt;
    &lt;gl:NumericTextBoxBehavior AllowNegatives=&quot;False&quot; /&gt;
  &lt;/i:Interaction.Behaviors&gt;
&lt;/TextBox&gt;
</pre>
<p>The full code to do this is shown below:</p>
<pre class="brush: csharp;">

namespace Goldlight.Extensions.Behaviors
{
  using System.Windows.Controls;
  using System.Windows.Interactivity;
  using System.Windows.Input;
  using System.Text.RegularExpressions;
  using System.Windows;
  using System.Globalization;

  /// &lt;summary&gt;
  /// Apply this behavior to a TextBox to ensure that it only accepts numeric values.
  /// The property &lt;see cref=&quot;NumericTextBoxBehavior.AllowDecimal&quot;/&gt; controls whether or not
  /// the input is an integer or not.
  /// &lt;para&gt;
  /// A common requirement is to constrain the number count that appears after the decimal place.
  /// Setting &lt;see cref=&quot;NumericTextBoxBehavior.DecimalLimit&quot;/&gt; specifies how many numbers appear here.
  /// If this value is 0, no limit is applied.
  /// &lt;/para&gt;
  /// &lt;/summary&gt;
  /// &lt;remarks&gt;
  /// In the view, this behavior is attached in the following way:
  /// &lt;code&gt;
  /// &lt;TextBox Text=&quot;{Binding Price}&quot;&gt;
  ///   &lt;i:Interaction.Behaviors&gt;
  ///     &lt;gl:NumericTextBoxBehavior AllowDecimal=&quot;False&quot; /&gt;
  ///   &lt;/i:Interaction.Behaviors&gt;
  /// &lt;/TextBox&gt;
  /// &lt;/code&gt;
  /// &lt;para&gt;
  /// Add references to System.Windows.Interactivity to the view to use
  /// this behavior.
  /// &lt;/para&gt;
  /// &lt;/remarks&gt;
  public partial class NumericTextBoxBehavior : Behavior&lt;TextBox&gt;
  {
    private bool _allowDecimal = true;
    private int _decimalLimit = 0;
    private bool _allowNegative = true;
    private string _pattern = string.Empty;

    /// &lt;summary&gt;
    /// Initialize a new instance of &lt;see cref=&quot;NumericTextBoxBehavior&quot;/&gt;.
    /// &lt;/summary&gt;
    public NumericTextBoxBehavior()
    {
      AllowDecimal = true;
      AllowNegatives = true;
      DecimalLimit = 0;
    }

    /// &lt;summary&gt;
    /// Get or set whether the input allows decimal characters.
    /// &lt;/summary&gt;
    public bool AllowDecimal
    {
      get
      {
        return _allowDecimal;
      }
      set
      {
        if (_allowDecimal == value) return;
        _allowDecimal = value;
        SetText();
      }
    }
    /// &lt;summary&gt;
    /// Get or set the maximum number of values to appear after
    /// the decimal.
    /// &lt;/summary&gt;
    /// &lt;remarks&gt;
    /// If DecimalLimit is 0, then no limit is applied.
    /// &lt;/remarks&gt;
    public int DecimalLimit
    {
      get
      {
        return _decimalLimit;
      }
      set
      {
        if (_decimalLimit == value) return;
        _decimalLimit = value;
        SetText();
      }
    }
    /// &lt;summary&gt;
    /// Get or set whether negative numbers are allowed.
    /// &lt;/summary&gt;
    public bool AllowNegatives
    {
      get
      {
        return _allowNegative;
      }
      set
      {
        if (_allowNegative == value) return;
        _allowNegative = value;
        SetText();
      }
    }

    #region Overrides
    protected override void OnAttached()
    {
      base.OnAttached();

      AssociatedObject.PreviewTextInput += new TextCompositionEventHandler(AssociatedObject_PreviewTextInput);
#if !SILVERLIGHT
      DataObject.AddPastingHandler(AssociatedObject, OnClipboardPaste);
#endif
    }

    protected override void OnDetaching()
    {
      base.OnDetaching();
      AssociatedObject.PreviewTextInput -= new TextCompositionEventHandler(AssociatedObject_PreviewTextInput);
#if !SILVERLIGHT
      DataObject.RemovePastingHandler(AssociatedObject, OnClipboardPaste);
#endif
    }
    #endregion

    #region Private methods
    private void SetText()
    {
      _pattern = string.Empty;
      GetRegularExpressionText();
    }

#if !SILVERLIGHT
    /// &lt;summary&gt;
    /// Handle paste operations into the textbox to ensure that the behavior
    /// is consistent with directly typing into the TextBox.
    /// &lt;/summary&gt;
    /// &lt;param name=&quot;sender&quot;&gt;The TextBox sender.&lt;/param&gt;
    /// &lt;param name=&quot;dopea&quot;&gt;Paste event arguments.&lt;/param&gt;
    /// &lt;remarks&gt;This operation is only available in WPF.&lt;/remarks&gt;
    private void OnClipboardPaste(object sender, DataObjectPastingEventArgs dopea)
    {
      string text = dopea.SourceDataObject.GetData(dopea.FormatToApply).ToString();

      if (!string.IsNullOrWhiteSpace(text) &amp;&amp; !Validate(text))
        dopea.CancelCommand();
    }
#endif

    /// &lt;summary&gt;
    /// Preview the text input.
    /// &lt;/summary&gt;
    /// &lt;param name=&quot;sender&quot;&gt;The TextBox sender.&lt;/param&gt;
    /// &lt;param name=&quot;e&quot;&gt;The composition event arguments.&lt;/param&gt;
    void AssociatedObject_PreviewTextInput(object sender, TextCompositionEventArgs e)
    {
      e.Handled = !Validate(e.Text);
    }

    /// &lt;summary&gt;
    /// Validate the contents of the textbox with the new content to see if it is
    /// valid.
    /// &lt;/summary&gt;
    /// &lt;param name=&quot;value&quot;&gt;The text to validate.&lt;/param&gt;
    /// &lt;returns&gt;True if this is valid, false otherwise.&lt;/returns&gt;
    protected bool Validate(string value)
    {
      TextBox textBox = AssociatedObject;

      string pre = string.Empty;
      string post = string.Empty;

      if (!string.IsNullOrWhiteSpace(textBox.Text))
      {
        pre = textBox.Text.Substring(0, textBox.SelectionStart);
        post = textBox.Text.Substring(textBox.SelectionStart + textBox.SelectionLength, textBox.Text.Length - (textBox.SelectionStart + textBox.SelectionLength));
      }
      else
      {
        pre = textBox.Text.Substring(0, textBox.CaretIndex);
        post = textBox.Text.Substring(textBox.CaretIndex, textBox.Text.Length - textBox.CaretIndex);
      }
      string test = string.Concat(pre, value, post);

      string pattern = GetRegularExpressionText();

      return new Regex(pattern).IsMatch(test);
    }

    private string GetRegularExpressionText()
    {
      if (!string.IsNullOrWhiteSpace(_pattern))
      {
        return _pattern;
      }
      _pattern = GetPatternText();
      return _pattern;
    }

    private string GetPatternText()
    {
      string pattern = string.Empty;
      string signPattern = &quot;[{0}+]&quot;;

      // If the developer has chosen to allow negative numbers, the pattern will be [-+].
      // If the developer chooses not to allow negatives, the pattern is [+].
      if (AllowNegatives)
      {
        signPattern = string.Format(signPattern, &quot;-&quot;);
      }
      else
      {
        signPattern = string.Format(signPattern, string.Empty);
      }

      // If the developer doesn't allow decimals, return the pattern.
      if (!AllowDecimal)
      {
        return string.Format(@&quot;^({0}?)(\d*)$&quot;, signPattern);
      }

      // If the developer has chosen to apply a decimal limit, the pattern matches
      // on a
      if (DecimalLimit &gt; 0)
      {
        pattern = string.Format(@&quot;^({2}?)(\d*)([{0}]?)(\d{{0,{1}}})$&quot;,
          NumberFormatInfo.CurrentInfo.CurrencyDecimalSeparator,
          DecimalLimit,
          signPattern);
      }
      else
      {
        pattern = string.Format(@&quot;^({1}?)(\d*)([{0}]?)(\d*)$&quot;, NumberFormatInfo.CurrentInfo.CurrencyDecimalSeparator, signPattern);
      }

      return pattern;
    }
    #endregion
  }
}
</pre>
<p>The clever thing is that this behavior doesn&#8217;t allow the user to paste an incorrect value in either &#8211; the paste operation is subject to the same rules as directly entering the value in the first place.</p>
<p>Anyway, I hope this behavior is as much use to you as it is to me.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/peteohanlon.wordpress.com/353/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/peteohanlon.wordpress.com/353/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/peteohanlon.wordpress.com/353/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/peteohanlon.wordpress.com/353/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/peteohanlon.wordpress.com/353/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/peteohanlon.wordpress.com/353/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/peteohanlon.wordpress.com/353/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/peteohanlon.wordpress.com/353/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/peteohanlon.wordpress.com/353/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/peteohanlon.wordpress.com/353/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/peteohanlon.wordpress.com/353/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/peteohanlon.wordpress.com/353/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/peteohanlon.wordpress.com/353/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/peteohanlon.wordpress.com/353/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=peteohanlon.wordpress.com&amp;blog=1230283&amp;post=353&amp;subd=peteohanlon&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://peteohanlon.wordpress.com/2011/03/30/getting-control-of-your-numbers/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/b13854c10ce07efee2062f13d9334cba?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">Pete O'Hanlon</media:title>
		</media:content>
	</item>
		<item>
		<title>Well Bipply-flipply. More VS Live</title>
		<link>http://peteohanlon.wordpress.com/2011/03/11/well-bipply-flipply-more-vs-live/</link>
		<comments>http://peteohanlon.wordpress.com/2011/03/11/well-bipply-flipply-more-vs-live/#comments</comments>
		<pubDate>Fri, 11 Mar 2011 22:44:52 +0000</pubDate>
		<dc:creator>peteohanlon</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://peteohanlon.wordpress.com/?p=350</guid>
		<description><![CDATA[All round good guy and guru of gurus, the lurv god of cod himself, Mr Walt Ritscher will be presenting three talks at VS Live, one on the Tuesday and two on Thursday: http://vslive.com/Events/Spring-2011/Sessions/Tuesday/T1-Easing-in-to-Windows-Phone-7-Development.aspx http://vslive.com/Events/Spring-2011/Sessions/Thursday/TH4-Digging-Deeper-in-Windows-Phone-7.aspx http://vslive.com/Events/Spring-2011/Sessions/Thursday/TH5-XAML-Primer-Clarifying-the-UI-Markup-Language.aspx If Walt can make them then you owe it to yourself to as well. Go on, see this giant [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=peteohanlon.wordpress.com&amp;blog=1230283&amp;post=350&amp;subd=peteohanlon&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>All round good guy and guru of gurus, the lurv god of cod himself, Mr Walt Ritscher will be presenting three talks at VS Live, one on the Tuesday and two on Thursday:</p>
<p><a href="http://vslive.com/Events/Spring-2011/Sessions/Tuesday/T1-Easing-in-to-Windows-Phone-7-Development.aspx" target="_blank">http://vslive.com/Events/Spring-2011/Sessions/Tuesday/T1-Easing-in-to-Windows-Phone-7-Development.aspx</a></p>
<p><a href="http://vslive.com/Events/Spring-2011/Sessions/Thursday/TH4-Digging-Deeper-in-Windows-Phone-7.aspx" target="_blank">http://vslive.com/Events/Spring-2011/Sessions/Thursday/TH4-Digging-Deeper-in-Windows-Phone-7.aspx</a></p>
<p><a href="http://vslive.com/Events/Spring-2011/Sessions/Thursday/TH5-XAML-Primer-Clarifying-the-UI-Markup-Language.aspx" target="_blank">http://vslive.com/Events/Spring-2011/Sessions/Thursday/TH5-XAML-Primer-Clarifying-the-UI-Markup-Language.aspx</a></p>
<p>If Walt can make them then you owe it to yourself to as well. Go on, see this giant of the development world in action &#8211; it&#8217;s true, he really is a giant; he&#8217;s 8 foot 6.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/peteohanlon.wordpress.com/350/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/peteohanlon.wordpress.com/350/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/peteohanlon.wordpress.com/350/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/peteohanlon.wordpress.com/350/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/peteohanlon.wordpress.com/350/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/peteohanlon.wordpress.com/350/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/peteohanlon.wordpress.com/350/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/peteohanlon.wordpress.com/350/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/peteohanlon.wordpress.com/350/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/peteohanlon.wordpress.com/350/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/peteohanlon.wordpress.com/350/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/peteohanlon.wordpress.com/350/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/peteohanlon.wordpress.com/350/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/peteohanlon.wordpress.com/350/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=peteohanlon.wordpress.com&amp;blog=1230283&amp;post=350&amp;subd=peteohanlon&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://peteohanlon.wordpress.com/2011/03/11/well-bipply-flipply-more-vs-live/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/b13854c10ce07efee2062f13d9334cba?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">Pete O'Hanlon</media:title>
		</media:content>
	</item>
	</channel>
</rss>
