<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" gd:etag="W/&quot;D0ECSHk8eSp7ImA9WxNWFE0.&quot;"><id>tag:blogger.com,1999:blog-8838794302949839825</id><updated>2009-10-13T04:47:49.771+01:00</updated><title>Andy On WPF</title><subtitle type="html" /><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://andyonwpf.blogspot.com/feeds/posts/default" /><link rel="alternate" type="text/html" href="http://andyonwpf.blogspot.com/" /><link rel="hub" href="http://pubsubhubbub.appspot.com/" /><author><name>Andrew Wilkinson</name><uri>http://www.blogger.com/profile/10117584978862298252</uri><email>noreply@blogger.com</email></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>8</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><link rel="self" href="http://feeds.feedburner.com/AndyOnWpf" type="application/atom+xml" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com" /><entry gd:etag="W/&quot;AkAAQHc8eSp7ImA9WBFVFks.&quot;"><id>tag:blogger.com,1999:blog-8838794302949839825.post-5977760543524623233</id><published>2007-04-15T21:16:00.000+01:00</published><updated>2007-04-15T21:25:41.971+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2007-04-15T21:25:41.971+01:00</app:edited><title>How small can you go? - Part III</title><content type="html">&lt;p&gt;In part one of this series of posts &lt;a href="http://andyonwpf.blogspot.com/2007/01/how-small-can-you-go.html"&gt;("How small can you go?" 22 Jan 2007)&lt;/a&gt; I described how you could design a Windows Presentation Foundation (WPF) control that altered the visibility of specific areas of a UI when then containing window was resized. Compare this to the behaviour of the Office 2007 ribbon, which will hide itself to show more of the edited document when the window is below a certain size. In part II &lt;a href="http://andyonwpf.blogspot.com/2007/02/how-small-can-you-go-part-ii.html"&gt;("How small can you go? - Part II" 15 Feb 2007)&lt;/a&gt; I detailed an alternative approach that allowed a trigger to be used when any bindable property (e.g. the width of a window) was below a certain size. In this post I will complete the implementation.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;To summarise part II, we implemented an &lt;a href="http://msdn2.microsoft.com/en-us/library/system.windows.data.ivalueconverter.aspx" target="_blank"&gt;IValueConverter&lt;/a&gt; that would return a boolean value indicating whether a specified binding was less than a certain value. This could be used as follows,&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;/p&gt;&lt;br /&gt;&lt;div class="wlWriterEditableSmartContent" id="57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:ad2c3872-d361-49bd-b1fa-e781332f20fd" contenteditable="false" style="PADDING-RIGHT: 0px; DISPLAY: inline; PADDING-LEFT: 0px; FLOAT: none; PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-TOP: 0px"&gt;&lt;pre style="BACKGROUND-COLOR: white; WORD-WRAP: break-word"&gt;&lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;... .Resources&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;cvt:LessThanConverter &lt;/span&gt;&lt;span style="color:#ff0000;"&gt;x:Key&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;="LessThanConverter"&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;... .Resources&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;DataTrigger &lt;/span&gt;&lt;span style="color:#ff0000;"&gt;Value&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;="True"&lt;/span&gt;&lt;span style="color:#ff0000;"&gt; Binding&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;="{Binding RelativeSource={RelativeSource Self}, Path=ActualWidth, Converter={StaticResource lessThanConverter}, ConverterParameter=200}"&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;&lt;br /&gt;...&lt;br /&gt;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;DataTrigger&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;While this allowed defining a trigger for when the width was below a specific threshhold, we would have to define the trigger again for the height of the window. What we really need is some way to combine two bindings with a 'logical OR' operation.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Introducing the &lt;a href="http://msdn2.microsoft.com/en-us/library/system.windows.data.imultivalueconverter.aspx" target="_blank"&gt;IMultiValueConverter&lt;/a&gt;...&lt;/p&gt;&lt;br /&gt;&lt;p&gt;An &lt;strong&gt;IMultiValueConverter&lt;/strong&gt; is similar in principle to an &lt;strong&gt;IValueConverter&lt;/strong&gt;, whereas the latter allows the conversion of a single value into another form (in our case, a &lt;strong&gt;double&lt;/strong&gt; into a &lt;strong&gt;bool&lt;/strong&gt; indicating whether the value is below a threshold), the former will take several values, and combine them into a single output value that is then used as a trigger. We therefore need an &lt;strong&gt;IMultiValueConverter&lt;/strong&gt; that will take a number of booleans and output a single boolean that represents a 'logical OR' of all the input values. We can then use the following XAML,&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;/p&gt;&lt;br /&gt;&lt;div class="wlWriterEditableSmartContent" id="57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:c66344ea-26d9-4e3f-9b96-4305ae596b91" contenteditable="false" style="PADDING-RIGHT: 0px; DISPLAY: inline; PADDING-LEFT: 0px; FLOAT: none; PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-TOP: 0px"&gt;&lt;pre style="BACKGROUND-COLOR: white; WORD-WRAP: break-word"&gt;&lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;... .Resources&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;cvt:LessThanConverter &lt;/span&gt;&lt;span style="color:#ff0000;"&gt;x:Key&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;="lessThanConverter"&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;cvt:MultiValueOrConverter &lt;/span&gt;&lt;span style="color:#ff0000;"&gt;x:Key&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;="multiValueOrConverter"&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;... .Resources&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;&lt;br /&gt;&lt;br /&gt;...&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;DataTrigger &lt;/span&gt;&lt;span style="color:#ff0000;"&gt;Value&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;="True"&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;DataTrigger&lt;/span&gt;&lt;span style="color:#ff0000;"&gt;.Binding&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;MultiBinding &lt;/span&gt;&lt;span style="color:#ff0000;"&gt;Converter&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;="{StaticResource multiValueOrConverter}"&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Binding &lt;/span&gt;&lt;span style="color:#ff0000;"&gt;RelativeSource&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;="{RelativeSource Self}"&lt;/span&gt;&lt;span style="color:#ff0000;"&gt; Path&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;="ActualWidth"&lt;/span&gt;&lt;span style="color:#ff0000;"&gt; Converter&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;="{StaticResource lessThanConverter}"&lt;/span&gt;&lt;span style="color:#ff0000;"&gt; ConverterParameter&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;="200"&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Binding &lt;/span&gt;&lt;span style="color:#ff0000;"&gt;RelativeSource&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;="{RelativeSource Self}"&lt;/span&gt;&lt;span style="color:#ff0000;"&gt; Path&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;="ActualHeight"&lt;/span&gt;&lt;span style="color:#ff0000;"&gt; Converter&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;="{StaticResource lessThanConverter}"&lt;/span&gt;&lt;span style="color:#ff0000;"&gt; ConverterParameter&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;="200"&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;MultiBinding&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;DataTrigger.Binding&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;&lt;br /&gt;...&lt;br /&gt;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;DataTrigger&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;This snippet declares two objects, our &lt;strong&gt;LessThanConverter&lt;/strong&gt; from before, and a new &lt;strong&gt;MultiValueOrConverter&lt;/strong&gt;. Following this we have a &lt;strong&gt;DataTrigger&lt;/strong&gt; who's binding is a &lt;strong&gt;MultiBinding&lt;/strong&gt; that takes two bindings that will return true if the width or height is less than 200. By default the &lt;strong&gt;MultiBinding&lt;/strong&gt; will only trigger if all the child bindings are true (a 'logical AND'). We change this behaviour to a 'logical OR' by specifying our multi-value converter. The trigger will now fire if either the element width OR height are less than 200.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;The actual code for the multi-value converter is similar in principle to that of a single-value converter. We take an array of input values that we will assume are all boolean values. We then perform a foreach loop over them and if any are true, we return true, otherwise false. Therefore the resulting code is,&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;/p&gt;&lt;br /&gt;&lt;div class="wlWriterEditableSmartContent" id="57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:207cc07e-ea56-4aea-a150-ec7f3085f55b" contenteditable="false" style="PADDING-RIGHT: 0px; DISPLAY: inline; PADDING-LEFT: 0px; FLOAT: none; PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-TOP: 0px"&gt;&lt;pre style="OVERFLOW: auto; BACKGROUND-COLOR: white"&gt;&lt;span style="color:#0000ff;"&gt;using&lt;/span&gt;&lt;span style="color:#000000;"&gt; System;&lt;br /&gt;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;using&lt;/span&gt;&lt;span style="color:#000000;"&gt; System.Collections.Generic;&lt;br /&gt;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;using&lt;/span&gt;&lt;span style="color:#000000;"&gt; System.Text;&lt;br /&gt;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;using&lt;/span&gt;&lt;span style="color:#000000;"&gt; System.Windows.Data;&lt;br /&gt;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;using&lt;/span&gt;&lt;span style="color:#000000;"&gt; System.Globalization;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;namespace&lt;/span&gt;&lt;span style="color:#000000;"&gt; SizingApplication2&lt;br /&gt;{&lt;br /&gt;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000ff;"&gt;class&lt;/span&gt;&lt;span style="color:#000000;"&gt; MultiValueOrConverter : IMultiValueConverter&lt;br /&gt;{&lt;br /&gt;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000ff;"&gt;object&lt;/span&gt;&lt;span style="color:#000000;"&gt; Convert(&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;object&lt;/span&gt;&lt;span style="color:#000000;"&gt;[] values, Type targetType, &lt;/span&gt;&lt;span style="color:#0000ff;"&gt;object&lt;/span&gt;&lt;span style="color:#000000;"&gt; parameter, CultureInfo culture)&lt;br /&gt;{&lt;br /&gt;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;foreach&lt;/span&gt;&lt;span style="color:#000000;"&gt; (&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;bool&lt;/span&gt;&lt;span style="color:#000000;"&gt; value &lt;/span&gt;&lt;span style="color:#0000ff;"&gt;in&lt;/span&gt;&lt;span style="color:#000000;"&gt; values)&lt;br /&gt;{&lt;br /&gt;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;if&lt;/span&gt;&lt;span style="color:#000000;"&gt; (value &lt;/span&gt;&lt;span style="color:#000000;"&gt;==&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000ff;"&gt;true&lt;/span&gt;&lt;span style="color:#000000;"&gt;)&lt;br /&gt;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;return&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000ff;"&gt;true&lt;/span&gt;&lt;span style="color:#000000;"&gt;;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;return&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000ff;"&gt;false&lt;/span&gt;&lt;span style="color:#000000;"&gt;;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000ff;"&gt;object&lt;/span&gt;&lt;span style="color:#000000;"&gt;[] ConvertBack(&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;object&lt;/span&gt;&lt;span style="color:#000000;"&gt; value, Type[] targetTypes, &lt;/span&gt;&lt;span style="color:#0000ff;"&gt;object&lt;/span&gt;&lt;span style="color:#000000;"&gt; parameter, CultureInfo culture)&lt;br /&gt;{&lt;br /&gt;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;throw&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000ff;"&gt;new&lt;/span&gt;&lt;span style="color:#000000;"&gt; NotSupportedException();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;If we combine this with the XAML snippet above and include a suitable setter to hide the desired parts of the UI, we now have all the behaviour we require. Advantages of this approach include not requiring any extra elements, and being able to adapt the value converters to any situation where the UI changes based upon a certain value (for example, to display a warning message when a slider is moved above a certain value, or even change its colour as a warning).&lt;/p&gt;&lt;br /&gt;&lt;p&gt;The full code for this post and an example usage is available &lt;a href="http://channel9.msdn.com/ShowPost.aspx?PostID=301048"&gt;here&lt;/a&gt;.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8838794302949839825-5977760543524623233?l=andyonwpf.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/AndyOnWpf/~4/zuKsofmn8cE" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://andyonwpf.blogspot.com/feeds/5977760543524623233/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=8838794302949839825&amp;postID=5977760543524623233" title="4 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8838794302949839825/posts/default/5977760543524623233?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8838794302949839825/posts/default/5977760543524623233?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/AndyOnWpf/~3/zuKsofmn8cE/how-small-can-you-go-part-iii.html" title="How small can you go? - Part III" /><author><name>Andrew Wilkinson</name><uri>http://www.blogger.com/profile/10117584978862298252</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="00484481544222125542" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">4</thr:total><feedburner:origLink>http://andyonwpf.blogspot.com/2007/04/how-small-can-you-go-part-iii.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DkADSH09fyp7ImA9WB5WF0k.&quot;"><id>tag:blogger.com,1999:blog-8838794302949839825.post-3444214338172089415</id><published>2007-03-04T15:35:00.001Z</published><updated>2007-07-29T22:32:59.367+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2007-07-29T22:32:59.367+01:00</app:edited><title>It's all in the Blend</title><content type="html">Recently I've been experimenting with the new software tool Expression Blend. For those of you who do not know, &lt;a title="Expression Blend" href="http://www.microsoft.com/products/expression/en/expression-blend/default.mspx"&gt;Expression Blend&lt;/a&gt; is Microsoft's design tool for XAML and WPF applications and is available as I write in Beta 2 form. It provides a visual design workspace where you can lay out all the elements that make up a UI, and adjust their properties as required.&lt;br /&gt;&lt;div&gt;&lt;p&gt;I have been making extensive use of it to style all the elements in my ribbon UI framework that I am currently developing. For someone who has previously edited the XAML directly it provides a much quicker environment for laying out the UI, with instant feedback on all changes. It also simplifies the introduction of triggers (changes on IsMouseOver, IsPressed, etc.) and animation. As an example, shown below is the application menu button for the ribbon UI. Of course since this is WPF this is all vector based, and smoothly scales up (NB: This screen grab is from an actual live UI - rollover animations, opens a menu when clicked, etc...).&lt;br /&gt;&lt;/p&gt;&lt;img id="BLOGGER_PHOTO_ID_5038094321961625122" style="DISPLAY: block; MARGIN: 0px auto 10px; CURSOR: hand; TEXT-ALIGN: center" alt="" src="http://3.bp.blogspot.com/_hUwtjPLXAAY/ReroF8VvZiI/AAAAAAAAAAc/9UIaj3ra-Dk/s400/RibbonAppButton.png" border="0" /&gt;&lt;br /&gt;&lt;p&gt;In its current incarnation (beta 2) there are some issues I have had. First of all I have been unable currently to get the whole of my ribbon UI in the designer. To be fair, I haven't really tried fixing this, and it is a large composition of custom controls in a WPF rendered chrome window. It also takes a bit of learning to get used to the way it places elements by default. Of course I never read the help when I started using it which could of helped, and once you understand the basic ideas it is very easy to build up the control structure desired.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;My favorite features apart from the ease at which the UI can be styled... One item I'll definitely add here is the gradient eyedropper tool. This is similar to the standard eyedropper, which can pick up individual pixel colours from the screen. However, when the gradient eyedropper tool is dragged across a region of the screen it will automatically pick up entire gradient fills. Great for designing smooth user interfaces. Also I like the simplicity by which you can apply property changes and animation upon events.&lt;/p&gt;&lt;p&gt;Let me know below if anybody else has any experiences of Expression Blend...&lt;/p&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Update: After a request for the XAML code I have attached the basic code below (copy and paste into XamlPad to see it). The actual Expression Blend generated XAML is significantly more complex (and much less readable!), and includes all the roll-over behaviour etc.. This is the main reason I chose a designer over hand crafting the XAML. Hopefully the attached code will give you an idea how to approach such designs.&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="wlWriterEditableSmartContent" id="57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:4a1b8ff5-5943-46b0-9e30-4806f0b861f7" contenteditable="false" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre style="overflow: auto; background-color: white word-wrap: none"&gt;&lt;div&gt;&lt;!--&lt;br /&gt;&lt;br /&gt;Code highlighting produced by Actipro CodeHighlighter (freeware)&lt;br /&gt;http://www.CodeHighlighter.com/&lt;br /&gt;&lt;br /&gt;--&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Page &lt;/span&gt;&lt;span style="color: #ff0000"&gt;xmlns&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="http://schemas.microsoft.com/winfx/2006/xaml/presentation"&lt;/span&gt;&lt;span style="color: #ff0000"&gt; xmlns:sys&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="clr-namespace:System;assembly=mscorlib"&lt;/span&gt;&lt;span style="color: #ff0000"&gt; xmlns:x&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="http://schemas.microsoft.com/winfx/2006/xaml"&lt;/span&gt;&lt;span style="color: #ff0000"&gt; &lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&lt;br /&gt;  &lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Page&lt;/span&gt;&lt;span style="color: #ff0000"&gt;.Resources&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Style &lt;/span&gt;&lt;span style="color: #ff0000"&gt;TargetType&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="{x:Type Button}"&lt;/span&gt;&lt;span style="color: #ff0000"&gt; x:Key&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="RibbonApplicationMenuButton"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&lt;br /&gt;      &lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Setter &lt;/span&gt;&lt;span style="color: #ff0000"&gt;Property&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="Width"&lt;/span&gt;&lt;span style="color: #ff0000"&gt; Value&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="37"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&lt;br /&gt;      &lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Setter &lt;/span&gt;&lt;span style="color: #ff0000"&gt;Property&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="Height"&lt;/span&gt;&lt;span style="color: #ff0000"&gt; Value&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="37"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&lt;br /&gt;      &lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Setter &lt;/span&gt;&lt;span style="color: #ff0000"&gt;Property&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="HorizontalContentAlignment"&lt;/span&gt;&lt;span style="color: #ff0000"&gt; Value&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="Center"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&lt;br /&gt;      &lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Setter &lt;/span&gt;&lt;span style="color: #ff0000"&gt;Property&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="VerticalContentAlignment"&lt;/span&gt;&lt;span style="color: #ff0000"&gt; Value&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="Center"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&lt;br /&gt;&lt;br /&gt;      &lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Setter &lt;/span&gt;&lt;span style="color: #ff0000"&gt;Property&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="Template"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Setter&lt;/span&gt;&lt;span style="color: #ff0000"&gt;.Value&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&lt;br /&gt;          &lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;ControlTemplate &lt;/span&gt;&lt;span style="color: #ff0000"&gt;TargetType&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="{x:Type Button}"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&lt;br /&gt;            &lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Grid&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&lt;br /&gt;              &lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Border &lt;/span&gt;&lt;span style="color: #ff0000"&gt;BorderThickness&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="0,0,0,0"&lt;/span&gt;&lt;span style="color: #ff0000"&gt; CornerRadius&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="100000,100000,100000,100000"&lt;/span&gt;&lt;span style="color: #ff0000"&gt; Opacity&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="1"&lt;/span&gt;&lt;span style="color: #ff0000"&gt; Margin&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="0,0,-1,-1"&lt;/span&gt;&lt;span style="color: #ff0000"&gt; x:Name&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="ShadowBorder"&lt;/span&gt;&lt;span style="color: #ff0000"&gt; Background&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="#39000000"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&lt;br /&gt;                &lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Border &lt;/span&gt;&lt;span style="color: #ff0000"&gt;x:Name&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="OuterBorder"&lt;/span&gt;&lt;span style="color: #ff0000"&gt; BorderBrush&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="#FF6E7D95"&lt;/span&gt;&lt;span style="color: #ff0000"&gt; BorderThickness&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="1,1,1,1"&lt;/span&gt;&lt;span style="color: #ff0000"&gt; CornerRadius&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="100000,100000,100000,100000"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&lt;br /&gt;                  &lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Border &lt;/span&gt;&lt;span style="color: #ff0000"&gt;ClipToBounds&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="False"&lt;/span&gt;&lt;span style="color: #ff0000"&gt; x:Name&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="InnerBorder"&lt;/span&gt;&lt;span style="color: #ff0000"&gt; Width&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="Auto"&lt;/span&gt;&lt;span style="color: #ff0000"&gt; Height&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="Auto"&lt;/span&gt;&lt;span style="color: #ff0000"&gt; BorderBrush&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="#FFDDE2EC"&lt;/span&gt;&lt;span style="color: #ff0000"&gt; BorderThickness&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="1,1,1,1"&lt;/span&gt;&lt;span style="color: #ff0000"&gt; CornerRadius&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="10000,10000,10000,10000"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&lt;br /&gt;                    &lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Border&lt;/span&gt;&lt;span style="color: #ff0000"&gt;.Background&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&lt;br /&gt;                      &lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;LinearGradientBrush &lt;/span&gt;&lt;span style="color: #ff0000"&gt;EndPoint&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="0.505,0.489"&lt;/span&gt;&lt;span style="color: #ff0000"&gt; StartPoint&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="0.512,-0.004"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&lt;br /&gt;                        &lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;GradientStop &lt;/span&gt;&lt;span style="color: #ff0000"&gt;Color&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="#FFF3F5F8"&lt;/span&gt;&lt;span style="color: #ff0000"&gt; Offset&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="0"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&lt;br /&gt;                        &lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;GradientStop &lt;/span&gt;&lt;span style="color: #ff0000"&gt;Color&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="#FFC0CADB"&lt;/span&gt;&lt;span style="color: #ff0000"&gt; Offset&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="1"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&lt;br /&gt;                      &lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;LinearGradientBrush&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&lt;br /&gt;                    &lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;Border.Background&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&lt;br /&gt;                    &lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Grid &lt;/span&gt;&lt;span style="color: #ff0000"&gt;Width&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="Auto"&lt;/span&gt;&lt;span style="color: #ff0000"&gt; Height&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="Auto"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&lt;br /&gt;                      &lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Path &lt;/span&gt;&lt;span style="color: #ff0000"&gt;RenderTransformOrigin&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="0.499999990968993,0.0833333333333333"&lt;/span&gt;&lt;span style="color: #ff0000"&gt; Stretch&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="Fill"&lt;/span&gt;&lt;span style="color: #ff0000"&gt; Margin&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="0,15,0,0"&lt;/span&gt;&lt;span style="color: #ff0000"&gt; x:Name&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="path"&lt;/span&gt;&lt;span style="color: #ff0000"&gt; Width&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="Auto"&lt;/span&gt;&lt;span style="color: #ff0000"&gt; Data&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="F1 M16.5,15.5 C22.163836,15.5 27.559435,15.738094 32.466614,16.168823 L32.5,16.5 C32.5,25.336555 25.336555,32.5 16.5,32.5 7.663444,32.5 0.5,25.336555 0.5000006,16.5 L0.53338605,16.168823 C5.4405661,15.738094 10.836165,15.5 16.5,15.5 z"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&lt;br /&gt;                        &lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Path&lt;/span&gt;&lt;span style="color: #ff0000"&gt;.Fill&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&lt;br /&gt;                          &lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;RadialGradientBrush &lt;/span&gt;&lt;span style="color: #ff0000"&gt;MappingMode&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="RelativeToBoundingBox"&lt;/span&gt;&lt;span style="color: #ff0000"&gt; GradientOrigin&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="0.5,0.5"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&lt;br /&gt;                            &lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;RadialGradientBrush&lt;/span&gt;&lt;span style="color: #ff0000"&gt;.RelativeTransform&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&lt;br /&gt;                              &lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;TransformGroup&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&lt;br /&gt;                                &lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;ScaleTransform &lt;/span&gt;&lt;span style="color: #ff0000"&gt;CenterX&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="0.5"&lt;/span&gt;&lt;span style="color: #ff0000"&gt; CenterY&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="0.5"&lt;/span&gt;&lt;span style="color: #ff0000"&gt; ScaleX&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="1.077"&lt;/span&gt;&lt;span style="color: #ff0000"&gt; ScaleY&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="1.748"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&lt;br /&gt;                                &lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;SkewTransform &lt;/span&gt;&lt;span style="color: #ff0000"&gt;AngleX&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="0"&lt;/span&gt;&lt;span style="color: #ff0000"&gt; AngleY&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="0"&lt;/span&gt;&lt;span style="color: #ff0000"&gt; CenterX&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="0.5"&lt;/span&gt;&lt;span style="color: #ff0000"&gt; CenterY&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="0.5"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&lt;br /&gt;                                &lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;RotateTransform &lt;/span&gt;&lt;span style="color: #ff0000"&gt;Angle&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="0"&lt;/span&gt;&lt;span style="color: #ff0000"&gt; CenterX&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="0.5"&lt;/span&gt;&lt;span style="color: #ff0000"&gt; CenterY&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="0.5"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&lt;br /&gt;                                &lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;TranslateTransform &lt;/span&gt;&lt;span style="color: #ff0000"&gt;X&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="-0.002"&lt;/span&gt;&lt;span style="color: #ff0000"&gt; Y&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="-0.025"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&lt;br /&gt;                              &lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;TransformGroup&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&lt;br /&gt;                            &lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;RadialGradientBrush.RelativeTransform&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&lt;br /&gt;                            &lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;GradientStop &lt;/span&gt;&lt;span style="color: #ff0000"&gt;Color&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="#FFFFFFFF"&lt;/span&gt;&lt;span style="color: #ff0000"&gt; Offset&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="0.375"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&lt;br /&gt;                            &lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;GradientStop &lt;/span&gt;&lt;span style="color: #ff0000"&gt;Color&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="#FF93A5C2"&lt;/span&gt;&lt;span style="color: #ff0000"&gt; Offset&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="1"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&lt;br /&gt;                            &lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;GradientStop &lt;/span&gt;&lt;span style="color: #ff0000"&gt;Color&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="#FFF2F4F7"&lt;/span&gt;&lt;span style="color: #ff0000"&gt; Offset&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="0.529"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&lt;br /&gt;                          &lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;RadialGradientBrush&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&lt;br /&gt;                        &lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;Path.Fill&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&lt;br /&gt;                      &lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;Path&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&lt;br /&gt;                      &lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;ContentPresenter &lt;/span&gt;&lt;span style="color: #ff0000"&gt;HorizontalAlignment&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="Center"&lt;/span&gt;&lt;span style="color: #ff0000"&gt; Margin&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="0,0,0,0"&lt;/span&gt;&lt;span style="color: #ff0000"&gt; VerticalAlignment&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="Center"&lt;/span&gt;&lt;span style="color: #ff0000"&gt; Width&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="Auto"&lt;/span&gt;&lt;span style="color: #ff0000"&gt; Height&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="Auto"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&lt;br /&gt;                    &lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;Grid&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&lt;br /&gt;                  &lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;Border&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&lt;br /&gt;                &lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;Border&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&lt;br /&gt;              &lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;Grid&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&lt;br /&gt;&lt;br /&gt;            &lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;ControlTemplate&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&lt;br /&gt;          &lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;Setter.Value&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;Setter&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&lt;br /&gt;      &lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;Style&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;Page.Resources&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&lt;br /&gt;&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Button &lt;/span&gt;&lt;span style="color: #ff0000"&gt;Style&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="{StaticResource RibbonApplicationMenuButton}"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;Page&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;&lt;br /&gt;&lt;strong&gt;&lt;/strong&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8838794302949839825-3444214338172089415?l=andyonwpf.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/AndyOnWpf/~4/sfNsklRlJ00" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://andyonwpf.blogspot.com/feeds/3444214338172089415/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=8838794302949839825&amp;postID=3444214338172089415" title="4 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8838794302949839825/posts/default/3444214338172089415?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8838794302949839825/posts/default/3444214338172089415?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/AndyOnWpf/~3/sfNsklRlJ00/it-all-in-blend.html" title="It&amp;#39;s all in the Blend" /><author><name>Andrew Wilkinson</name><uri>http://www.blogger.com/profile/10117584978862298252</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="00484481544222125542" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://3.bp.blogspot.com/_hUwtjPLXAAY/ReroF8VvZiI/AAAAAAAAAAc/9UIaj3ra-Dk/s72-c/RibbonAppButton.png" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">4</thr:total><feedburner:origLink>http://andyonwpf.blogspot.com/2007/03/it-all-in-blend.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEECQX48cSp7ImA9WBFXE04.&quot;"><id>tag:blogger.com,1999:blog-8838794302949839825.post-221210824311255758</id><published>2007-02-15T21:40:00.001Z</published><updated>2007-03-19T19:31:00.079Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2007-03-19T19:31:00.079Z</app:edited><title>How small can you go? - Part II</title><content type="html">&lt;p&gt;&lt;em&gt;Updated: 19 March 2007 to resolve some errors&lt;/em&gt;&lt;/p&gt;&lt;p&gt;In my last post (&lt;a title="How small can you go?" href="http://andyonwpf.blogspot.com/2007/01/how-small-can-you-go.html"&gt;"How small can you go?" 22 Jan 2007&lt;/a&gt;) I presented a custom control that allowed you to determine if the control was below a specific size, and to alter its visual appearance based upon this. There are many cases however where altering appearance based upon size is important (for example, to make the thumb grips on scrollbars disappear when they become too small), and I felt a more generic method of performing this calculation was required.&lt;/p&gt;&lt;p&gt;Ideally this method would not require a special base class as described in my previous post. It should also be as general as possible, allowing bindings to any available dependency properties.&lt;/p&gt;&lt;p&gt;So let us consider how we currently implement triggers,&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;div class="wlWriterSmartContent" id="57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:264e45bf-50af-4ecb-981f-3a71c16f59b6" contenteditable="false" style="PADDING-RIGHT: 0px; DISPLAY: inline; PADDING-LEFT: 0px; FLOAT: none; PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-TOP: 0px"&gt;&lt;pre  style="color:white;"&gt;&lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Trigger &lt;/span&gt;&lt;span style="color:#ff0000;"&gt;Property&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;="IsMouseOver"&lt;/span&gt;&lt;span style="color:#ff0000;"&gt; Value&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;="True"&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;&lt;br /&gt;...&lt;br /&gt;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;Trigger&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Trigger &lt;/span&gt;&lt;span style="color:#ff0000;"&gt;Property&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;="Width"&lt;/span&gt;&lt;span style="color:#ff0000;"&gt; Value&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;="150"&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;&lt;br /&gt;...&lt;br /&gt;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;Trigger&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;The first of these examples makes perfect sense. The &lt;strong&gt;IsMouseOver&lt;/strong&gt; property is either true or false. We apply the default style when it is false, and apply any changes specified within the Trigger when it is true. However, the &lt;strong&gt;Width&lt;/strong&gt; property does not have a small number of distinct values. Whilst the above trigger will apply if the width equals 150, it will not if it is 149,148,147,etc. or 151,152,153,etc. If only we had a less-than trigger...&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Now let me introduce the &lt;strong&gt;&lt;a title="IValueConverter interface" href="http://msdn2.microsoft.com/en-us/library/system.windows.data.ivalueconverter.aspx" target="_blank"&gt;IValueConverter&lt;/a&gt;&lt;/strong&gt; interface. This according to the MSDN documentation "Provides a way to apply custom logic to a binding." Basically it allows you to include some logic that alters the value of the property before the trigger performs its comparison.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;For example,&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;div class="wlWriterSmartContent" id="57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:edf24687-180e-43c6-b2cb-a4f252f33ae7" contenteditable="false" style="PADDING-RIGHT: 0px; DISPLAY: inline; PADDING-LEFT: 0px; FLOAT: none; PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-TOP: 0px"&gt;&lt;pre  style="color:white;"&gt;&lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;DataTrigger &lt;/span&gt;&lt;span style="color:#ff0000;"&gt;Value&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;="True"&lt;/span&gt;&lt;span style="color:#ff0000;"&gt; Binding&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;="{Binding RelativeSource={RelativeSource Self}, Path=ActualWidth, Converter={StaticResource addTenConverter}, ConverterParameter=150}"&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;&lt;br /&gt;...&lt;br /&gt;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;DataTrigger&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Here we specify a custom converter, whose logic simply adds ten to a value. Therefore if the &lt;strong&gt;Width&lt;/strong&gt; of our element is 140, the binding will first call our converter, which will of course return 150. Since this matches the &lt;strong&gt;Value&lt;/strong&gt; attribute, the trigger will be applied. The converter just sits between the &lt;strong&gt;Property&lt;/strong&gt; and the comparison to &lt;strong&gt;Value&lt;/strong&gt; and provides some conversion.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;So how does this help us? Well, there is one more attribute we need to introduce. The &lt;strong&gt;ConverterParameter&lt;/strong&gt; attribute allows us to supply an additional parameter to our converter when it does its stuff. Now we can envisage,&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;div class="wlWriterSmartContent" id="57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:90eed4c9-a5e1-49f0-b8bc-e7582a53c119" contenteditable="false" style="PADDING-RIGHT: 0px; DISPLAY: inline; PADDING-LEFT: 0px; FLOAT: none; PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-TOP: 0px"&gt;&lt;pre  style="color:white;"&gt;&lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;... .Resources&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;cvt:LessThanConverter &lt;/span&gt;&lt;span style="color:#ff0000;"&gt;x:Key&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;="LessThanConverter"&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;... .Resources&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;DataTrigger &lt;/span&gt;&lt;span style="color:#ff0000;"&gt;Value&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;="True"&lt;/span&gt;&lt;span style="color:#ff0000;"&gt; Binding&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;="{Binding RelativeSource={RelativeSource Self}, Path=ActualWidth, Converter={StaticResource lessThanConverter}, ConverterParameter=200}"&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;&lt;br /&gt;...&lt;br /&gt;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;DataTrigger&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Note that we create an instance of the converter as a static resource. The actual code behind the converter is relatively straightforward. All we do is take the supplied value, compare it to the supplied parameter, and return true if the value is less otherwise return false. In fact this is slightly more complex. Whilst a &lt;strong&gt;ValueConversionAttribute&lt;/strong&gt; may be applied to the converter class specifying the type for the parameter, when written in XAML as shown above this is ignored and a string is supplied anyway. Therefore the resulting code is,&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;div class="wlWriterSmartContent" id="57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:f535e9ad-7fc8-4868-a570-657c8fc3af33" contenteditable="false" style="PADDING-RIGHT: 0px; DISPLAY: inline; PADDING-LEFT: 0px; FLOAT: none; PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-TOP: 0px"&gt;&lt;pre  style="color:white;"&gt;&lt;span style="color:#0000ff;"&gt;using&lt;/span&gt;&lt;span style="color:#000000;"&gt; System;&lt;br /&gt;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;using&lt;/span&gt;&lt;span style="color:#000000;"&gt; System.Windows.Data;&lt;br /&gt;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;using&lt;/span&gt;&lt;span style="color:#000000;"&gt; System.Globalization;&lt;br /&gt;&lt;br /&gt;[ValueConversion(&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;typeof&lt;/span&gt;&lt;span style="color:#000000;"&gt;(&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;double&lt;/span&gt;&lt;span style="color:#000000;"&gt;), &lt;/span&gt;&lt;span style="color:#0000ff;"&gt;typeof&lt;/span&gt;&lt;span style="color:#000000;"&gt;(&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;bool&lt;/span&gt;&lt;span style="color:#000000;"&gt;), ParameterType &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000ff;"&gt;typeof&lt;/span&gt;&lt;span style="color:#000000;"&gt;(&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;double&lt;/span&gt;&lt;span style="color:#000000;"&gt;))]&lt;br /&gt;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000ff;"&gt;class&lt;/span&gt;&lt;span style="color:#000000;"&gt; LessThanConverter : IValueConverter&lt;br /&gt;{&lt;br /&gt;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000ff;"&gt;object&lt;/span&gt;&lt;span style="color:#000000;"&gt; Convert(&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;object&lt;/span&gt;&lt;span style="color:#000000;"&gt; value, Type targetType, &lt;/span&gt;&lt;span style="color:#0000ff;"&gt;object&lt;/span&gt;&lt;span style="color:#000000;"&gt; parameter, CultureInfo culture)&lt;br /&gt;{&lt;br /&gt;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;double&lt;/span&gt;&lt;span style="color:#000000;"&gt; doubleValue &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; (&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;double&lt;/span&gt;&lt;span style="color:#000000;"&gt;)value;&lt;br /&gt;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;double&lt;/span&gt;&lt;span style="color:#000000;"&gt; doubleParameter;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;if&lt;/span&gt;&lt;span style="color:#000000;"&gt; (parameter &lt;/span&gt;&lt;span style="color:#0000ff;"&gt;is&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000ff;"&gt;double&lt;/span&gt;&lt;span style="color:#000000;"&gt;)&lt;br /&gt;doubleParameter &lt;/span&gt;&lt;span style="color:#000000;"&gt;=&lt;/span&gt;&lt;span style="color:#000000;"&gt; (&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;double&lt;/span&gt;&lt;span style="color:#000000;"&gt;)parameter;&lt;br /&gt;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;else&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000ff;"&gt;if&lt;/span&gt;&lt;span style="color:#000000;"&gt; (parameter &lt;/span&gt;&lt;span style="color:#0000ff;"&gt;is&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000ff;"&gt;string&lt;/span&gt;&lt;span style="color:#000000;"&gt;)&lt;br /&gt;{&lt;br /&gt;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;if&lt;/span&gt;&lt;span style="color:#000000;"&gt; (&lt;/span&gt;&lt;span style="color:#000000;"&gt;!&lt;/span&gt;&lt;span style="color:#000000;"&gt;Double.TryParse((&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;string&lt;/span&gt;&lt;span style="color:#000000;"&gt;)parameter, &lt;/span&gt;&lt;span style="color:#0000ff;"&gt;out&lt;/span&gt;&lt;span style="color:#000000;"&gt; doubleParameter))&lt;br /&gt;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;throw&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000ff;"&gt;new&lt;/span&gt;&lt;span style="color:#000000;"&gt; FormatException(&lt;/span&gt;&lt;span style="color:#000000;"&gt;"&lt;/span&gt;&lt;span style="color:#000000;"&gt;The parameter for this LessThanConverter could not be converted to a System.Double&lt;/span&gt;&lt;span style="color:#000000;"&gt;"&lt;/span&gt;&lt;span style="color:#000000;"&gt;);&lt;br /&gt;}&lt;br /&gt;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;else&lt;/span&gt;&lt;span style="color:#000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;throw&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000ff;"&gt;new&lt;/span&gt;&lt;span style="color:#000000;"&gt; ArgumentException(&lt;/span&gt;&lt;span style="color:#000000;"&gt;"&lt;/span&gt;&lt;span style="color:#000000;"&gt;The parameter for this LessThanConverer is of an unsupported type&lt;/span&gt;&lt;span style="color:#000000;"&gt;"&lt;/span&gt;&lt;span style="color:#000000;"&gt;, &lt;/span&gt;&lt;span style="color:#000000;"&gt;"&lt;/span&gt;&lt;span style="color:#000000;"&gt;parameter&lt;/span&gt;&lt;span style="color:#000000;"&gt;"&lt;/span&gt;&lt;span style="color:#000000;"&gt;);&lt;br /&gt;&lt;br /&gt;Console.WriteLine(&lt;/span&gt;&lt;span style="color:#000000;"&gt;"&lt;/span&gt;&lt;span style="color:#000000;"&gt;{0} &amp;lt; {1}&lt;/span&gt;&lt;span style="color:#000000;"&gt;"&lt;/span&gt;&lt;span style="color:#000000;"&gt;, doubleValue, doubleParameter);&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;return&lt;/span&gt;&lt;span style="color:#000000;"&gt; doubleValue &lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#000000;"&gt; doubleParameter;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000ff;"&gt;object&lt;/span&gt;&lt;span style="color:#000000;"&gt; ConvertBack(&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;object&lt;/span&gt;&lt;span style="color:#000000;"&gt; value, Type targetType, &lt;/span&gt;&lt;span style="color:#0000ff;"&gt;object&lt;/span&gt;&lt;span style="color:#000000;"&gt; parameter, CultureInfo culture)&lt;br /&gt;{&lt;br /&gt;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;return&lt;/span&gt;&lt;span style="color:#000000;"&gt; &lt;/span&gt;&lt;span style="color:#0000ff;"&gt;new&lt;/span&gt;&lt;span style="color:#000000;"&gt; NotSupportedException();&lt;br /&gt;}&lt;br /&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;So now we can trigger when any dependency property that is defined as a &lt;strong&gt;double&lt;/strong&gt; is less than a specified value. The original problem from &lt;a title="How small can you go?" href="http://andyonwpf.blogspot.com/2007/01/how-small-can-you-go.html"&gt;part 1&lt;/a&gt; however involved changing the appearance of a window when either of the &lt;strong&gt;Width&lt;/strong&gt; or &lt;strong&gt;Height&lt;/strong&gt; properties were below a certain threshold. We can specify two separate triggers, but this requires duplication of all the setters within them. What we really need is some way to apply a 'logical OR' operation to two or more triggers. Next time... The &lt;strong&gt;&lt;a title="IMultiValueConverter interface" href="http://msdn2.microsoft.com/en-us/library/system.windows.data.imultivalueconverter.aspx" target="_blank"&gt;IMultiValueConverter&lt;/a&gt;&lt;/strong&gt; interface.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;/p&gt;&lt;br /&gt;&lt;div class="wlWriterSmartContent" id="0767317B-992E-4b12-91E0-4F059A8CECA8:70fc90ca-eb27-47d8-89a9-1a9268790e28" contenteditable="false" style="PADDING-RIGHT: 0px; DISPLAY: inline; PADDING-LEFT: 0px; PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-TOP: 0px"&gt;Technorati tags: &lt;a href="http://technorati.com/tags/WPF" rel="tag"&gt;WPF&lt;/a&gt;, &lt;a href="http://technorati.com/tags/IValueConverter" rel="tag"&gt;IValueConverter&lt;/a&gt;, &lt;a href="http://technorati.com/tags/Triggers" rel="tag"&gt;Triggers&lt;/a&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8838794302949839825-221210824311255758?l=andyonwpf.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/AndyOnWpf/~4/6MKZmQd6Ae0" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://andyonwpf.blogspot.com/feeds/221210824311255758/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=8838794302949839825&amp;postID=221210824311255758" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8838794302949839825/posts/default/221210824311255758?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8838794302949839825/posts/default/221210824311255758?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/AndyOnWpf/~3/6MKZmQd6Ae0/how-small-can-you-go-part-ii.html" title="How small can you go? - Part II" /><author><name>Andrew Wilkinson</name><uri>http://www.blogger.com/profile/10117584978862298252</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="00484481544222125542" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">2</thr:total><feedburner:origLink>http://andyonwpf.blogspot.com/2007/02/how-small-can-you-go-part-ii.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUYFR3w9fip7ImA9WBBaFU0.&quot;"><id>tag:blogger.com,1999:blog-8838794302949839825.post-7567457923895559728</id><published>2007-01-22T22:51:00.001Z</published><updated>2007-01-22T23:05:16.266Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2007-01-22T23:05:16.266Z</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="WPF" /><title>How small can you go?</title><content type="html">&lt;p&gt;In the past, creation of fully sizable user interfaces was a tedious job involving writing complex and bugging "pixel-counting" code to layout controls upon a window resize event. Windows Presentation Foundation (WPF) has made the job of creating such UIs much simpler by including a straightforward layout engine within the framework. But sometimes there is a limit to how small you can resize the UI before it becomes unusable.&lt;/p&gt; &lt;p&gt;One solution is&amp;nbsp;the approach&amp;nbsp;used by the 2007 Microsoft Office System, whereby the ribbon control will disappear from view if the window is resized too small, allowing the document content to fill the space. In this post I'll describe how to implement this effect in WPF applications. I will discuss how to implement dependency properties in your custom controls and&amp;nbsp;the strange world of read-only dependency properties.&lt;/p&gt; &lt;p&gt;As a very simple example we will start with a custom control that is styled with a content area, and&amp;nbsp;a toolbar that&amp;nbsp;when sized below a certain size will be hidden&amp;nbsp;(in my WPF ribbon control this is actually a styled Window, however for simplicity here I will use a control).&lt;/p&gt; &lt;p&gt;&lt;/p&gt; &lt;div class="wlWriterSmartContent" id="57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:a0d55110-e138-4bb9-a97e-e6eb327db5de" contenteditable="false" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre style="background-color:White;"&gt;&lt;div&gt;&lt;!--&lt;br /&gt;&lt;br /&gt;Code highlighting produced by Actipro CodeHighlighter (freeware)&lt;br /&gt;http://www.CodeHighlighter.com/&lt;br /&gt;&lt;br /&gt;--&gt;&lt;span style="color: #0000FF; "&gt;public&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;class&lt;/span&gt;&lt;span style="color: #000000; "&gt; SizingControl : Control&lt;br /&gt;{&lt;br /&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Now we will add a "dependency property", a special type of property used for WPF applications that allows additional functionality such as data binding, animations and styling. We define these with the &lt;strong&gt;DependencyProperty.Register&lt;/strong&gt; static method, supplying a property name, property type and owner type. In addition, metadata may be added defining addition information such as default values. In addition we add a standard CLR property of the same name, passing the value to and from the property system with the &lt;strong&gt;DependencyObject.GetValue&lt;/strong&gt; and &lt;strong&gt;DependencyObject.SetValue&lt;/strong&gt; methods. In this case we add a dependency property to specify the size below which the control will display a different UI.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;&lt;div class="wlWriterSmartContent" id="57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:e6ca1d62-5b67-4794-8833-9b2dacf57dfb" contenteditable="false" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre style="background-color:White;"&gt;&lt;div&gt;&lt;!--&lt;br /&gt;&lt;br /&gt;Code highlighting produced by Actipro CodeHighlighter (freeware)&lt;br /&gt;http://www.CodeHighlighter.com/&lt;br /&gt;&lt;br /&gt;--&gt;&lt;span style="color: #0000FF; "&gt;public&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;static&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;readonly&lt;/span&gt;&lt;span style="color: #000000; "&gt; DependencyProperty SmallSizeProperty &lt;/span&gt;&lt;span style="color: #000000; "&gt;=&lt;/span&gt;&lt;span style="color: #000000; "&gt; DependencyProperty.Register(&lt;/span&gt;&lt;span style="color: #000000; "&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000; "&gt;SmallSize&lt;/span&gt;&lt;span style="color: #000000; "&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000; "&gt;, &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;typeof&lt;/span&gt;&lt;span style="color: #000000; "&gt;(Size), &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;typeof&lt;/span&gt;&lt;span style="color: #000000; "&gt;(SizingControl), &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;new&lt;/span&gt;&lt;span style="color: #000000; "&gt; UIPropertyMetadata(&lt;/span&gt;&lt;span style="color: #0000FF; "&gt;new&lt;/span&gt;&lt;span style="color: #000000; "&gt; Size(&lt;/span&gt;&lt;span style="color: #000000; "&gt;0.0&lt;/span&gt;&lt;span style="color: #000000; "&gt;, &lt;/span&gt;&lt;span style="color: #000000; "&gt;0.0&lt;/span&gt;&lt;span style="color: #000000; "&gt;)));&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000FF; "&gt;public&lt;/span&gt;&lt;span style="color: #000000; "&gt; Size SmallSize&lt;br /&gt;{&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;get&lt;/span&gt;&lt;span style="color: #000000; "&gt;&lt;br /&gt;    {&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;return&lt;/span&gt;&lt;span style="color: #000000; "&gt; (Size)GetValue(SmallSizeProperty);&lt;br /&gt;    }&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;set&lt;/span&gt;&lt;span style="color: #000000; "&gt;&lt;br /&gt;    {&lt;br /&gt;        SetValue(SmallSizeProperty, value);&lt;br /&gt;    }&lt;br /&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Next we add a read-only dependency property that indicates whether the control is below the specified size. The &lt;a href="http://msdn2.microsoft.com/en-us/library//ms754044.aspx" target="_blank"&gt;Windows SDK&lt;/a&gt; warns against using read-only dependency properties in many cases, and suggests that such properties should only be used "for state determination". Think of this as properties of the form "IsXXX" (such as IsMouseOver).&lt;/p&gt;&lt;br /&gt;&lt;p&gt;To register a read-only dependency property, we use the &lt;strong&gt;DependencyProperty.Register.ReadOnly&lt;/strong&gt; static method, which rather than a &lt;strong&gt;DependencyProperty&lt;/strong&gt;, returns a &lt;strong&gt;DependencyPropertyKey&lt;/strong&gt;. To set the value we can use this with the respective override of &lt;strong&gt;DependencyObject.SetValue&lt;/strong&gt;, however no suitable override of &lt;strong&gt;DependencyObject.GetValue&lt;/strong&gt; exists. In fact, the property system does not allow us to get a value of a dependency property that is marked as read-only. So how do we obtain this value? The answer is that we have to include a private field to contain the property value. Since by its very nature a read-only property may only be set by the owner class, we can always ensure that the value in the field is synchronized with that of the dependency property. To avoid writing code that breaks this rule, I tend to encapsulate this logic into a private property setter (note that property setters and getters with different accessibility is a feature of C# 2.0).&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;&lt;div class="wlWriterSmartContent" id="57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:83ea4022-2af4-4228-84a2-8de901094d46" contenteditable="false" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre style="background-color:White;"&gt;&lt;div&gt;&lt;!--&lt;br /&gt;&lt;br /&gt;Code highlighting produced by Actipro CodeHighlighter (freeware)&lt;br /&gt;http://www.CodeHighlighter.com/&lt;br /&gt;&lt;br /&gt;--&gt;&lt;span style="color: #0000FF; "&gt;private&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;bool&lt;/span&gt;&lt;span style="color: #000000; "&gt; isSmall;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000FF; "&gt;public&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;static&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;readonly&lt;/span&gt;&lt;span style="color: #000000; "&gt; DependencyPropertyKey IsSmallPropertyKey &lt;/span&gt;&lt;span style="color: #000000; "&gt;=&lt;/span&gt;&lt;span style="color: #000000; "&gt; DependencyProperty.RegisterReadOnly(&lt;/span&gt;&lt;span style="color: #000000; "&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000; "&gt;IsSmall&lt;/span&gt;&lt;span style="color: #000000; "&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000; "&gt;, &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;typeof&lt;/span&gt;&lt;span style="color: #000000; "&gt;(&lt;/span&gt;&lt;span style="color: #0000FF; "&gt;bool&lt;/span&gt;&lt;span style="color: #000000; "&gt;), &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;typeof&lt;/span&gt;&lt;span style="color: #000000; "&gt;(SizingControl), &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;new&lt;/span&gt;&lt;span style="color: #000000; "&gt; UIPropertyMetadata(&lt;/span&gt;&lt;span style="color: #0000FF; "&gt;false&lt;/span&gt;&lt;span style="color: #000000; "&gt;));&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000FF; "&gt;public&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;bool&lt;/span&gt;&lt;span style="color: #000000; "&gt; IsSmall&lt;br /&gt;{&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;get&lt;/span&gt;&lt;span style="color: #000000; "&gt;&lt;br /&gt;    {&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;return&lt;/span&gt;&lt;span style="color: #000000; "&gt; isSmall;&lt;br /&gt;    }&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;private&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;set&lt;/span&gt;&lt;span style="color: #000000; "&gt;&lt;br /&gt;    {&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;if&lt;/span&gt;&lt;span style="color: #000000; "&gt; (value &lt;/span&gt;&lt;span style="color: #000000; "&gt;!=&lt;/span&gt;&lt;span style="color: #000000; "&gt; isSmall)&lt;br /&gt;        {&lt;br /&gt;            isSmall &lt;/span&gt;&lt;span style="color: #000000; "&gt;=&lt;/span&gt;&lt;span style="color: #000000; "&gt; value;&lt;br /&gt;            SetValue(IsSmallPropertyKey, value);&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Now all is required is to override the &lt;strong&gt;OnRenderSizeChanged&lt;/strong&gt; event of our control, and determine whether the control is small or not.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;&lt;div class="wlWriterSmartContent" id="57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:86946144-e8fd-402a-9787-50d6e43ff581" contenteditable="false" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre style="background-color:White;"&gt;&lt;div&gt;&lt;!--&lt;br /&gt;&lt;br /&gt;Code highlighting produced by Actipro CodeHighlighter (freeware)&lt;br /&gt;http://www.CodeHighlighter.com/&lt;br /&gt;&lt;br /&gt;--&gt;&lt;span style="color: #0000FF; "&gt;private&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;void&lt;/span&gt;&lt;span style="color: #000000; "&gt; UpdateIsSmall(Size newSize)&lt;br /&gt;{&lt;br /&gt;    IsSmall &lt;/span&gt;&lt;span style="color: #000000; "&gt;=&lt;/span&gt;&lt;span style="color: #000000; "&gt; (newSize.Width &lt;/span&gt;&lt;span style="color: #000000; "&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000; "&gt; SmallSize.Width &lt;/span&gt;&lt;span style="color: #000000; "&gt;||&lt;/span&gt;&lt;span style="color: #000000; "&gt; newSize.Height &lt;/span&gt;&lt;span style="color: #000000; "&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000; "&gt; SmallSize.Height);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000FF; "&gt;protected&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;override&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;void&lt;/span&gt;&lt;span style="color: #000000; "&gt; OnRenderSizeChanged(SizeChangedInfo sizeInfo)&lt;br /&gt;{&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #008000; "&gt;//&lt;/span&gt;&lt;span style="color: #008000; "&gt; Calculate whether the window size is smaller than the specified values&lt;/span&gt;&lt;span style="color: #008000; "&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000; "&gt;    UpdateIsSmall(sizeInfo.NewSize);&lt;br /&gt;&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #008000; "&gt;//&lt;/span&gt;&lt;span style="color: #008000; "&gt; Call the base method&lt;/span&gt;&lt;span style="color: #008000; "&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000; "&gt;    &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;base&lt;/span&gt;&lt;span style="color: #000000; "&gt;.OnRenderSizeChanged(sizeInfo);&lt;br /&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;The XAML below shows how to use the control to hide a toolbar when the window is too small. We style the control with the desired content, and set a trigger on the &lt;strong&gt;IsSmall&lt;/strong&gt; property to show or hide the toolbar as required.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;&lt;div class="wlWriterSmartContent" id="57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:ef527f0a-af5f-40ec-b2c2-bd131f5fd6f4" contenteditable="false" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre style="background-color:White;"&gt;&lt;div&gt;&lt;!--&lt;br /&gt;&lt;br /&gt;Code highlighting produced by Actipro CodeHighlighter (freeware)&lt;br /&gt;http://www.CodeHighlighter.com/&lt;br /&gt;&lt;br /&gt;--&gt;&lt;span style="color: #0000FF; "&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000; "&gt;Window &lt;/span&gt;&lt;span style="color: #FF0000; "&gt;x:Class&lt;/span&gt;&lt;span style="color: #0000FF; "&gt;=&amp;quot;SizingApplication.Window1&amp;quot;&lt;/span&gt;&lt;span style="color: #FF0000; "&gt; xmlns&lt;/span&gt;&lt;span style="color: #0000FF; "&gt;=&amp;quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&amp;quot;&lt;/span&gt;&lt;span style="color: #FF0000; "&gt; xmlns:x&lt;/span&gt;&lt;span style="color: #0000FF; "&gt;=&amp;quot;http://schemas.microsoft.com/winfx/2006/xaml&amp;quot;&lt;/span&gt;&lt;span style="color: #FF0000; "&gt; Title&lt;/span&gt;&lt;span style="color: #0000FF; "&gt;=&amp;quot;SizingApplication&amp;quot;&lt;/span&gt;&lt;span style="color: #FF0000; "&gt; Height&lt;/span&gt;&lt;span style="color: #0000FF; "&gt;=&amp;quot;300&amp;quot;&lt;/span&gt;&lt;span style="color: #FF0000; "&gt; Width&lt;/span&gt;&lt;span style="color: #0000FF; "&gt;=&amp;quot;300&amp;quot;&lt;/span&gt;&lt;span style="color: #FF0000; "&gt; xmlns:local&lt;/span&gt;&lt;span style="color: #0000FF; "&gt;=&amp;quot;clr-namespace:SizingApplication&amp;quot;&lt;/span&gt;&lt;span style="color: #FF0000; "&gt; Background&lt;/span&gt;&lt;span style="color: #0000FF; "&gt;=&amp;quot;Silver&amp;quot;&lt;/span&gt;&lt;span style="color: #0000FF; "&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000; "&gt;&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000; "&gt;Window&lt;/span&gt;&lt;span style="color: #FF0000; "&gt;.Resources&lt;/span&gt;&lt;span style="color: #0000FF; "&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000; "&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000; "&gt;Style &lt;/span&gt;&lt;span style="color: #FF0000; "&gt;x:Key&lt;/span&gt;&lt;span style="color: #0000FF; "&gt;=&amp;quot;MySizingRegion&amp;quot;&lt;/span&gt;&lt;span style="color: #FF0000; "&gt; TargetType&lt;/span&gt;&lt;span style="color: #0000FF; "&gt;=&amp;quot;local:SizingControl&amp;quot;&lt;/span&gt;&lt;span style="color: #0000FF; "&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000; "&gt;&lt;br /&gt;            &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000; "&gt;Setter &lt;/span&gt;&lt;span style="color: #FF0000; "&gt;Property&lt;/span&gt;&lt;span style="color: #0000FF; "&gt;=&amp;quot;SmallSize&amp;quot;&lt;/span&gt;&lt;span style="color: #FF0000; "&gt; Value&lt;/span&gt;&lt;span style="color: #0000FF; "&gt;=&amp;quot;200,200&amp;quot;&lt;/span&gt;&lt;span style="color: #0000FF; "&gt;/&amp;gt;&lt;/span&gt;&lt;span style="color: #000000; "&gt;&lt;br /&gt;&lt;br /&gt;            &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000; "&gt;Setter &lt;/span&gt;&lt;span style="color: #FF0000; "&gt;Property&lt;/span&gt;&lt;span style="color: #0000FF; "&gt;=&amp;quot;Template&amp;quot;&lt;/span&gt;&lt;span style="color: #0000FF; "&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000; "&gt;&lt;br /&gt;                &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000; "&gt;Setter&lt;/span&gt;&lt;span style="color: #FF0000; "&gt;.Value&lt;/span&gt;&lt;span style="color: #0000FF; "&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000; "&gt;&lt;br /&gt;                    &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000; "&gt;ControlTemplate &lt;/span&gt;&lt;span style="color: #FF0000; "&gt;TargetType&lt;/span&gt;&lt;span style="color: #0000FF; "&gt;=&amp;quot;local:SizingControl&amp;quot;&lt;/span&gt;&lt;span style="color: #0000FF; "&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000; "&gt;&lt;br /&gt;                        &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000; "&gt;DockPanel&lt;/span&gt;&lt;span style="color: #0000FF; "&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000; "&gt;&lt;br /&gt;                            &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000; "&gt;ToolBar &lt;/span&gt;&lt;span style="color: #FF0000; "&gt;x:Name&lt;/span&gt;&lt;span style="color: #0000FF; "&gt;=&amp;quot;toolBar&amp;quot;&lt;/span&gt;&lt;span style="color: #FF0000; "&gt; DockPanel.Dock&lt;/span&gt;&lt;span style="color: #0000FF; "&gt;=&amp;quot;Top&amp;quot;&lt;/span&gt;&lt;span style="color: #FF0000; "&gt; Height&lt;/span&gt;&lt;span style="color: #0000FF; "&gt;=&amp;quot;50&amp;quot;&lt;/span&gt;&lt;span style="color: #0000FF; "&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000; "&gt;&lt;br /&gt;                                &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000; "&gt;Label &lt;/span&gt;&lt;span style="color: #FF0000; "&gt;VerticalAlignment&lt;/span&gt;&lt;span style="color: #0000FF; "&gt;=&amp;quot;Center&amp;quot;&lt;/span&gt;&lt;span style="color: #0000FF; "&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000; "&gt;My ToolBar&lt;/span&gt;&lt;span style="color: #0000FF; "&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000; "&gt;Label&lt;/span&gt;&lt;span style="color: #0000FF; "&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000; "&gt;&lt;br /&gt;                            &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000; "&gt;ToolBar&lt;/span&gt;&lt;span style="color: #0000FF; "&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000; "&gt;&lt;br /&gt;                            &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000; "&gt;Border &lt;/span&gt;&lt;span style="color: #FF0000; "&gt;Margin&lt;/span&gt;&lt;span style="color: #0000FF; "&gt;=&amp;quot;10&amp;quot;&lt;/span&gt;&lt;span style="color: #FF0000; "&gt; Background&lt;/span&gt;&lt;span style="color: #0000FF; "&gt;=&amp;quot;White&amp;quot;&lt;/span&gt;&lt;span style="color: #0000FF; "&gt;/&amp;gt;&lt;/span&gt;&lt;span style="color: #000000; "&gt;&lt;br /&gt;                        &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000; "&gt;DockPanel&lt;/span&gt;&lt;span style="color: #0000FF; "&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000; "&gt;&lt;br /&gt;                        &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000; "&gt;ControlTemplate&lt;/span&gt;&lt;span style="color: #FF0000; "&gt;.Triggers&lt;/span&gt;&lt;span style="color: #0000FF; "&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000; "&gt;&lt;br /&gt;                            &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000; "&gt;Trigger &lt;/span&gt;&lt;span style="color: #FF0000; "&gt;Property&lt;/span&gt;&lt;span style="color: #0000FF; "&gt;=&amp;quot;IsSmall&amp;quot;&lt;/span&gt;&lt;span style="color: #FF0000; "&gt; Value&lt;/span&gt;&lt;span style="color: #0000FF; "&gt;=&amp;quot;True&amp;quot;&lt;/span&gt;&lt;span style="color: #0000FF; "&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000; "&gt;&lt;br /&gt;                                &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000; "&gt;Setter &lt;/span&gt;&lt;span style="color: #FF0000; "&gt;TargetName&lt;/span&gt;&lt;span style="color: #0000FF; "&gt;=&amp;quot;toolBar&amp;quot;&lt;/span&gt;&lt;span style="color: #FF0000; "&gt; Property&lt;/span&gt;&lt;span style="color: #0000FF; "&gt;=&amp;quot;Visibility&amp;quot;&lt;/span&gt;&lt;span style="color: #FF0000; "&gt; Value&lt;/span&gt;&lt;span style="color: #0000FF; "&gt;=&amp;quot;Collapsed&amp;quot;&lt;/span&gt;&lt;span style="color: #0000FF; "&gt;/&amp;gt;&lt;/span&gt;&lt;span style="color: #000000; "&gt;&lt;br /&gt;                            &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000; "&gt;Trigger&lt;/span&gt;&lt;span style="color: #0000FF; "&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000; "&gt;&lt;br /&gt;                        &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000; "&gt;ControlTemplate.Triggers&lt;/span&gt;&lt;span style="color: #0000FF; "&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000; "&gt;&lt;br /&gt;                    &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000; "&gt;ControlTemplate&lt;/span&gt;&lt;span style="color: #0000FF; "&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000; "&gt;&lt;br /&gt;                &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000; "&gt;Setter.Value&lt;/span&gt;&lt;span style="color: #0000FF; "&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000; "&gt;&lt;br /&gt;            &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000; "&gt;Setter&lt;/span&gt;&lt;span style="color: #0000FF; "&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000; "&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000; "&gt;Style&lt;/span&gt;&lt;span style="color: #0000FF; "&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000; "&gt;&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000; "&gt;Window.Resources&lt;/span&gt;&lt;span style="color: #0000FF; "&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000; "&gt;&lt;br /&gt;&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000; "&gt;Grid&lt;/span&gt;&lt;span style="color: #0000FF; "&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000; "&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000; "&gt;local:SizingControl &lt;/span&gt;&lt;span style="color: #FF0000; "&gt;Style&lt;/span&gt;&lt;span style="color: #0000FF; "&gt;=&amp;quot;{StaticResource MySizingRegion}&amp;quot;&lt;/span&gt;&lt;span style="color: #0000FF; "&gt;/&amp;gt;&lt;/span&gt;&lt;span style="color: #000000; "&gt;&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000; "&gt;Grid&lt;/span&gt;&lt;span style="color: #0000FF; "&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000; "&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000FF; "&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000; "&gt;Window&lt;/span&gt;&lt;span style="color: #0000FF; "&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;The full&amp;nbsp;code for this post is &lt;a href="http://channel9.msdn.com/ShowPost.aspx?PostID=274848"&gt;here&lt;/a&gt;.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8838794302949839825-7567457923895559728?l=andyonwpf.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/AndyOnWpf/~4/LHaa9rJfOVc" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://andyonwpf.blogspot.com/feeds/7567457923895559728/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=8838794302949839825&amp;postID=7567457923895559728" title="4 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8838794302949839825/posts/default/7567457923895559728?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8838794302949839825/posts/default/7567457923895559728?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/AndyOnWpf/~3/LHaa9rJfOVc/how-small-can-you-go.html" title="How small can you go?" /><author><name>Andrew Wilkinson</name><uri>http://www.blogger.com/profile/10117584978862298252</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="00484481544222125542" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">4</thr:total><feedburner:origLink>http://andyonwpf.blogspot.com/2007/01/how-small-can-you-go.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkIERH46eCp7ImA9WBBXFE0.&quot;"><id>tag:blogger.com,1999:blog-8838794302949839825.post-4057178904646276452</id><published>2006-11-24T22:48:00.001Z</published><updated>2006-11-24T22:48:25.010Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2006-11-24T22:48:25.010Z</app:edited><title>Ribbon controls are legal!</title><content type="html">&lt;p&gt;Here is the news that Microsoft have launched a licensing program for those who wish to clone the Office 2007 UI (&lt;a title="Licensing the 2007 Microsoft Office User Interface" href="http://blogs.msdn.com/jensenh/archive/2006/11/21/licensing-the-2007-microsoft-office-user-interface.aspx" target="_blank"&gt;from Jensen Harris' blog&lt;/a&gt;). This is a royalty-free scheme whereby anyone wishing to use part of the Office 2007 user interface (e.g. the ribbon) can recreate it in their applications (note that this offering does not provide any code).&lt;/p&gt; &lt;p&gt;There are some restrictions applied however, in particular that the interface must adhere to the supplied UI guidelines. These are very detailed so places quite a burden on the programmer implementing the controls; however this should at least&amp;nbsp;ensure that the end user can confidently use a ribbon-enabled application with the existing knowledge of how the UI should work. Microsoft have done a great job in explaining the requirements - for example they describe exactly how the ribbon should resize - so I'm looking forward to having an accurate check-list of requirements to implement in my controls.&lt;/p&gt; &lt;p&gt;For more information check out the links in &lt;a title="Licensing the 2007 Microsoft Office User Interface" href="http://blogs.msdn.com/jensenh/archive/2006/11/21/licensing-the-2007-microsoft-office-user-interface.aspx" target="_blank"&gt;Jensen' blog post&lt;/a&gt;...&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8838794302949839825-4057178904646276452?l=andyonwpf.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/AndyOnWpf/~4/v1slfl1Hgb4" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://andyonwpf.blogspot.com/feeds/4057178904646276452/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=8838794302949839825&amp;postID=4057178904646276452" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8838794302949839825/posts/default/4057178904646276452?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8838794302949839825/posts/default/4057178904646276452?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/AndyOnWpf/~3/v1slfl1Hgb4/ribbon-controls-are-legal.html" title="Ribbon controls are legal!" /><author><name>Andrew Wilkinson</name><uri>http://www.blogger.com/profile/10117584978862298252</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="00484481544222125542" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://andyonwpf.blogspot.com/2006/11/ribbon-controls-are-legal.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEIEQXY9eSp7ImA9WBFWEk0.&quot;"><id>tag:blogger.com,1999:blog-8838794302949839825.post-1753111869549193130</id><published>2006-11-05T16:44:00.001Z</published><updated>2007-03-29T22:08:20.861+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2007-03-29T22:08:20.861+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="WPF" /><category scheme="http://www.blogger.com/atom/ns#" term="dropshadows" /><title>From the shadows</title><content type="html">&lt;p&gt;When styling controls that have a Popup element (e.g. menus, combo boxes, etc.) a common visual cue is a drop-shadow below the pop-up. WPF contains a DropShadowBitmapEffect that will do this all for us, hence,&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;"&gt;&amp;lt;Border ...&amp;gt;&lt;br /&gt;&amp;lt;Border.BitmapEffect&amp;gt;&lt;br /&gt;&amp;lt;DropShadowBitmapEffect Softness=".5" ShadowDepth="5" Color="Black"/&amp;gt;&lt;br /&gt;&amp;lt;/Border.BitmapEffect&amp;gt;&lt;br /&gt;&amp;lt;/Border&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;"&gt;&lt;span style="font-family:Georgia;"&gt;The result is shown on the left below. However, the DropShadowBitmapEffect is a bit overkill for our needs. It is designed to add drop-shadows to arbitrary shapes (for example the text below) whereas a pop-up is generally rectangular.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;img style="DISPLAY: block; MARGIN: 0px auto 10px; CURSOR: hand; TEXT-ALIGN: center" alt="" src="http://photos1.blogger.com/blogger2/5073/1078954382684306/320/DropShadowBitmapEffect.png" border="0" /&gt;&lt;br /&gt;&lt;p&gt;If you inspect the default WPF styles you will find that a drop shadow is applied via a Decorator called Microsoft.Windows.Themes.SystemDropShadowChrome. This however is hidden away in PresentationFramework.Luna.dll and designed for use by the default styles.&lt;/p&gt;&lt;p&gt;For my controls I have developed my own decorator to do a similar job. Firstly I have decided to make some assumptions to improve performance - namely that the drop-shadow colour is always black, and that it is always to the bottom-right. All that is required then is to implement a custom "Decorator". Decorators are controls that add some additional rendering to a single element (of course that element may be a Panel that contains several other elements). We can then draw a drop-shadow in the OnRender method consisting of a set of linear and radial gradients to mimic the shadow.&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:courier new;"&gt;using System;&lt;br /&gt;using System.Collections.Generic;&lt;br /&gt;using System.Text;&lt;br /&gt;using System.Windows.Controls;&lt;br /&gt;using System.Windows.Media;&lt;br /&gt;using System.Windows&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:courier new;"&gt;class ShadowChrome : Decorator&lt;br /&gt;{&lt;br /&gt;// *** Fields *** &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:courier new;"&gt;private static SolidColorBrush backgroundBrush;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:courier new;"&gt;private static LinearGradientBrush rightBrush;&lt;br /&gt;private static LinearGradientBrush bottomBrush;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:courier new;"&gt;private static RadialGradientBrush bottomRightBrush;&lt;br /&gt;private static RadialGradientBrush topRightBrush;&lt;br /&gt;private static RadialGradientBrush bottomLeftBrush;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;// *** Constructors ***&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;static ShadowChrome()&lt;br /&gt;{&lt;br /&gt;MarginProperty.OverrideMetadata(typeof(ShadowChrome), new FrameworkPropertyMetadata(new Thickness(0, 0, 4, 4)));&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;CreateBrushes();&lt;br /&gt;}&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:courier new;"&gt;// *** Overriden base methods ***&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="font-family:courier new;"&gt;protected override void OnRender(DrawingContext drawingContext)&lt;br /&gt;{&lt;br /&gt;// Calculate the size of the shadow&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="font-family:courier new;"&gt;double shadowSize = Math.Min(Margin.Right, Margin.Bottom);&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="font-family:courier new;"&gt;// If there is no shadow, or it is bigger than the size of the child, then just return&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="font-family:courier new;"&gt;if (shadowSize &amp;lt;= 0 &amp;#124;&amp;#124; this.ActualWidth &amp;lt; shadowSize*2 &amp;#124;&amp;#124; this.ActualHeight &amp;lt; shadowSize * 2)&lt;br /&gt;return;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="font-family:courier new;"&gt;// Draw the background (this may show through rounded corners of the child object)&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="font-family:courier new;"&gt;Rect backgroundRect = new Rect(shadowSize, shadowSize, this.ActualWidth - shadowSize, this.ActualHeight - shadowSize);&lt;br /&gt;drawingContext.DrawRectangle(backgroundBrush, null, backgroundRect);&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="font-family:courier new;"&gt;// Now draw the shadow gradients&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="font-family:courier new;"&gt;Rect topRightRect = new Rect(this.ActualWidth, shadowSize, shadowSize, shadowSize);&lt;br /&gt;drawingContext.DrawRectangle(topRightBrush, null, topRightRect);&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="font-family:courier new;"&gt;Rect rightRect = new Rect(this.ActualWidth, shadowSize * 2, shadowSize, this.ActualHeight - shadowSize * 2);&lt;br /&gt;drawingContext.DrawRectangle(rightBrush, null, rightRect);&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="font-family:courier new;"&gt;Rect bottomRightRect = new Rect(this.ActualWidth, this.ActualHeight, shadowSize, shadowSize);&lt;br /&gt;drawingContext.DrawRectangle(bottomRightBrush, null, bottomRightRect);&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="font-family:courier new;"&gt;Rect bottomRect = new Rect(shadowSize * 2, this.ActualHeight, this.ActualWidth - shadowSize * 2, shadowSize);&lt;br /&gt;drawingContext.DrawRectangle(bottomBrush, null, bottomRect);&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="font-family:courier new;"&gt;Rect bottomLeftRect = new Rect(shadowSize, this.ActualHeight, shadowSize, shadowSize);&lt;br /&gt;drawingContext.DrawRectangle(bottomLeftBrush, null, bottomLeftRect);&lt;br /&gt;}&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="font-family:courier new;"&gt;// *** Private static methods ***&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="font-family:courier new;"&gt;private static void CreateBrushes()&lt;br /&gt;{&lt;br /&gt;// Get the colors for the shadow&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="font-family:courier new;"&gt;Color shadowColor = Color.FromArgb(128, 0, 0, 0);&lt;br /&gt;Color transparentColor = Color.FromArgb(16, 0, 0, 0);&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="font-family:courier new;"&gt;// Create a GradientStopCollection from these&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="font-family:courier new;"&gt;GradientStopCollection gradient = new GradientStopCollection(2);&lt;br /&gt;gradient.Add(new GradientStop(shadowColor, 0.5));&lt;br /&gt;gradient.Add(new GradientStop(transparentColor, 1.0));&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="font-family:courier new;"&gt;// Create the background brush&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="font-family:courier new;"&gt;backgroundBrush = new SolidColorBrush(shadowColor);&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="font-family:courier new;"&gt;// Create the LinearGradientBrushes&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="font-family:courier new;"&gt;rightBrush = new LinearGradientBrush(gradient, new Point(0.0, 0.0), new Point(1.0, 0.0));&lt;br /&gt;bottomBrush = new LinearGradientBrush(gradient, new Point(0.0, 0.0), new Point(0.0, 1.0));&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="font-family:courier new;"&gt;// Create the RadialGradientBrushes&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="font-family:courier new;"&gt;bottomRightBrush = new RadialGradientBrush(gradient);&lt;br /&gt;bottomRightBrush.GradientOrigin = new Point(0.0, 0.0);&lt;br /&gt;bottomRightBrush.Center = new Point(0.0, 0.0);&lt;br /&gt;bottomRightBrush.RadiusX = 1.0;&lt;br /&gt;bottomRightBrush.RadiusY = 1.0;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="font-family:courier new;"&gt;topRightBrush = new RadialGradientBrush(gradient);&lt;br /&gt;topRightBrush.GradientOrigin = new Point(0.0, 1.0);&lt;br /&gt;topRightBrush.Center = new Point(0.0, 1.0);&lt;br /&gt;topRightBrush.RadiusX = 1.0;&lt;br /&gt;topRightBrush.RadiusY = 1.0;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="font-family:courier new;"&gt;bottomLeftBrush = new RadialGradientBrush(gradient);&lt;br /&gt;bottomLeftBrush.GradientOrigin = new Point(1.0, 0.0);&lt;br /&gt;bottomLeftBrush.Center = new Point(1.0, 0.0);&lt;br /&gt;bottomLeftBrush.RadiusX = 1.0;&lt;br /&gt;bottomLeftBrush.RadiusY = 1.0;&lt;br /&gt;}&lt;br /&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;This may then be used as shown in the following XAML. Note that the Margin property is used for two uses. Firstly it provides an area around the element to render the drop-shadow (this is important in a Popup since it ensures the drop-shadow is within the pop-up window), and also specifies to ShadowChrome the size to render the drop-shadow. &lt;p&gt;&lt;span style="font-family:Courier New;"&gt;&amp;lt;ShadowChrome&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;&amp;lt;Border Margin="0,0,5,5" .../&amp;gt;&lt;br /&gt;&amp;lt;/ShadowChrome&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;img style="DISPLAY: block; MARGIN: 0px auto 10px; CURSOR: hand; TEXT-ALIGN: center" alt="" src="http://photos1.blogger.com/blogger2/5073/1078954382684306/320/DropDownShadow.png" border="0" /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8838794302949839825-1753111869549193130?l=andyonwpf.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/AndyOnWpf/~4/7Kpr2LaOUcM" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://andyonwpf.blogspot.com/feeds/1753111869549193130/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=8838794302949839825&amp;postID=1753111869549193130" title="10 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8838794302949839825/posts/default/1753111869549193130?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8838794302949839825/posts/default/1753111869549193130?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/AndyOnWpf/~3/7Kpr2LaOUcM/from-shadows.html" title="From the shadows" /><author><name>Andrew Wilkinson</name><uri>http://www.blogger.com/profile/10117584978862298252</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="00484481544222125542" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">10</thr:total><feedburner:origLink>http://andyonwpf.blogspot.com/2006/11/from-shadows.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEcFRXc7cSp7ImA9WBBREUk.&quot;"><id>tag:blogger.com,1999:blog-8838794302949839825.post-6569372675321374140</id><published>2006-10-29T12:06:00.001Z</published><updated>2006-10-29T17:13:34.909Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2006-10-29T17:13:34.909Z</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="WPF" /><category scheme="http://www.blogger.com/atom/ns#" term="Ribbon" /><category scheme="http://www.blogger.com/atom/ns#" term="DropDownButton" /><title>DropDownButtons in WPF</title><content type="html">Whilst Windows Presentation Foundation (WPF) provides good support for menus, one omission is a drop-down button. By this I mean a button, that when clicked will result in a menu dropping down from the control.&lt;br /&gt;&lt;br /&gt;&lt;img style="DISPLAY: block; MARGIN: 0px auto 10px; CURSOR: hand; TEXT-ALIGN: center" alt="" src="http://photos1.blogger.com/blogger2/5073/1078954382684306/320/DropDownButton.png" border="0" /&gt; &lt;p&gt;&lt;/p&gt;&lt;p&gt;So I started to write my own. Easy I thought, just style a MenuItem to look like a button. Well, this doesn't work as the MenuItem control will only work if it is a child of a Menu control. I could just wrap all my DropDownButtons in Menus, but that becomes a little messy wrapping everything in extra menus. I tried a number of other approaches, none of which worked as I would like.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;This was several months ago. Recently however I was informed of a couple of related blog articles at &lt;a title="Sheva's Techspace" href="http://shevaspace.spaces.live.com/blog/cns!FD9A0F1F8DD06954!453.entry" target="_blank"&gt;Sheva's Techspace&lt;/a&gt; and &lt;a title="Lester's piece on WPF" href="http://blogs.msdn.com/llobo/archive/2006/10/25/Split-Button-in-WPF.aspx" target="_blank"&gt;Lester's piece on WPF&lt;/a&gt;. In particular I liked Lester's approach. This is to use the Button's ContextMenu to apply add a context menu, and then to use code to open this on a left mouse click. A simple solution that works well. But what if I wanted to have a &lt;em&gt;real&lt;/em&gt; context-menu too?&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Solution: Well, in fact ContextMenu doesn't need to be attached to a control to work. All you need to do is create a new ContextMenu object, add your MenuItems, and set IsOpen to true. So I put together the control as below.&lt;/p&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="font-family:Courier New;"&gt;public class DropDownButton : ToggleButton&lt;br /&gt;{&lt;br /&gt;// *** Dependency Properties *** &lt;/span&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="font-family:Courier New;"&gt;public static readonly DependencyProperty DropDownProperty = DependencyProperty.Register("DropDown", typeof(ContextMenu), typeof(DropDownButton), new UIPropertyMetadata(null)); &lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="font-family:Courier New;"&gt;// *** Constructors *** &lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="font-family:Courier New;"&gt;public DropDownButton()&lt;br /&gt;{&lt;br /&gt;// Bind the ToogleButton.IsChecked property to the drop-down's IsOpen property &lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="font-family:Courier New;"&gt;Binding binding = new Binding("DropDown.IsOpen");&lt;br /&gt;binding.Source = this;&lt;br /&gt;this.SetBinding(IsCheckedProperty, binding);&lt;br /&gt;} &lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="font-family:Courier New;"&gt;// *** Properties *** &lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="font-family:Courier New;"&gt;public ContextMenu DropDown&lt;br /&gt;{&lt;br /&gt;get&lt;br /&gt;{&lt;br /&gt;return (ContextMenu)GetValue(DropDownProperty);&lt;br /&gt;}&lt;br /&gt;set&lt;br /&gt;{&lt;br /&gt;SetValue(DropDownProperty, value);&lt;br /&gt;}&lt;br /&gt;} &lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="font-family:Courier New;"&gt;// *** Overridden Methods *** &lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="font-family:Courier New;"&gt;protected override void OnClick()&lt;br /&gt;{&lt;br /&gt;if (DropDown != null)&lt;br /&gt;{&lt;br /&gt;// If there is a drop-down assigned to this button, then position and display it &lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="font-family:Courier New;"&gt;DropDown.PlacementTarget = this;&lt;br /&gt;DropDown.Placement = PlacementMode.Bottom; &lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="font-family:Courier New;"&gt;DropDown.IsOpen = true;&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;}&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;p&gt;This control derives directly from ToggleButton so we inherit the full behavior and styling of a button. We then provide a DropDown dependency property that takes a ContextMenu to show for the drop-down. In the OnClick event we simply position the menu under the control, and open it by setting IsOpen to true. Finally to tidy up, we bind the ToggleButton's IsChecked property to the drop-down menu's IsOpen property to ensure that these are synchronized.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;To use this in your own code you simply use,&lt;/p&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="font-family:Courier New;"&gt;&amp;lt;ctrl:DropDownButton Content="Drop-Down"&amp;gt;&lt;br /&gt;&amp;lt;ctrl:DropDownButton.DropDown&amp;gt;&lt;br /&gt;&amp;lt;ContextMenu&amp;gt;&lt;br /&gt;&amp;lt;MenuItem Header="Item 1"/&amp;gt;&lt;br /&gt;&amp;lt;MenuItem Header="Item 2"/&amp;gt;&lt;br /&gt;&amp;lt;MenuItem Header="Item 3"/&amp;gt;&lt;br /&gt;&amp;lt;/ContextMenu&amp;gt;&lt;br /&gt;&amp;lt;/ctrl:DropDownButton.DropDown&amp;gt;&lt;br /&gt;&amp;lt;/ctrl:DropDownButton&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;p&gt;&lt;/p&gt;&lt;br /&gt;&lt;div class="wlWriterSmartContent" id="0767317B-992E-4b12-91E0-4F059A8CECA8:d9eebd36-8fd9-41b5-8192-b7c68b472dd2" contenteditable="false" style="PADDING-RIGHT: 0px; DISPLAY: inline; PADDING-LEFT: 0px; PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-TOP: 0px"&gt;Technorati tags: &lt;a href="http://technorati.com/tags/WPF" rel="tag"&gt;WPF&lt;/a&gt;, &lt;a href="http://technorati.com/tags/DropDownButton" rel="tag"&gt;DropDownButton&lt;/a&gt;, &lt;a href="http://technorati.com/tags/Ribbon" rel="tag"&gt;Ribbon&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8838794302949839825-6569372675321374140?l=andyonwpf.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/AndyOnWpf/~4/6Lh-aUkXWQs" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://andyonwpf.blogspot.com/feeds/6569372675321374140/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=8838794302949839825&amp;postID=6569372675321374140" title="16 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8838794302949839825/posts/default/6569372675321374140?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8838794302949839825/posts/default/6569372675321374140?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/AndyOnWpf/~3/6Lh-aUkXWQs/dropdownbuttons-in-wpf.html" title="DropDownButtons in WPF" /><author><name>Andrew Wilkinson</name><uri>http://www.blogger.com/profile/10117584978862298252</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="00484481544222125542" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">16</thr:total><feedburner:origLink>http://andyonwpf.blogspot.com/2006/10/dropdownbuttons-in-wpf.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C04MRXs9cCp7ImA9WBBREUk.&quot;"><id>tag:blogger.com,1999:blog-8838794302949839825.post-3369796541685618569</id><published>2006-10-29T11:34:00.001Z</published><updated>2006-10-29T17:13:04.568Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2006-10-29T17:13:04.568Z</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="WPF" /><category scheme="http://www.blogger.com/atom/ns#" term="Ribbon" /><title>An Office 2007 style Ribbon in WPF?</title><content type="html">&lt;p&gt;For a while now I have been working on reproducing an Office 2007 Ribbon style application in Windows Presentation Foundation (WPF). This includes not just the ribbon itself, but also the full window chrome.&lt;/p&gt;&lt;p&gt;Whilst the official documentation has been in progress, blogs have been a great alternative source of information. However now I thought would be a good time to start my own blog discussing, amongst other things, how I am writing my Ribbon control.&lt;/p&gt;&lt;p&gt;Hope over the coming months you enjoy my posts and find something of interest to your own development needs. I'll focus on some of the issues that I have encountered, and will post some images of the fully working Ribbon control.&lt;/p&gt;&lt;div class="wlWriterSmartContent" id="0767317B-992E-4b12-91E0-4F059A8CECA8:67936529-85ab-49e8-90ca-dfe51d61bf13" contenteditable="false" style="PADDING-RIGHT: 0px; DISPLAY: inline; PADDING-LEFT: 0px; FLOAT: none; PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-TOP: 0px"&gt;Technorati tags: &lt;a href="http://technorati.com/tags/WPF" rel="tag"&gt;WPF&lt;/a&gt;, &lt;a href="http://technorati.com/tags/Ribbon" rel="tag"&gt;Ribbon&lt;/a&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8838794302949839825-3369796541685618569?l=andyonwpf.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/AndyOnWpf/~4/Tbl2nnq3XYw" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://andyonwpf.blogspot.com/feeds/3369796541685618569/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=8838794302949839825&amp;postID=3369796541685618569" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8838794302949839825/posts/default/3369796541685618569?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8838794302949839825/posts/default/3369796541685618569?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/AndyOnWpf/~3/Tbl2nnq3XYw/office-2007-style-ribbon-in-wpf.html" title="An Office 2007 style Ribbon in WPF?" /><author><name>Andrew Wilkinson</name><uri>http://www.blogger.com/profile/10117584978862298252</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="00484481544222125542" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">2</thr:total><feedburner:origLink>http://andyonwpf.blogspot.com/2006/10/office-2007-style-ribbon-in-wpf.html</feedburner:origLink></entry></feed>
