<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0">
  <channel>
    <title>Grant Archibald - wpf</title>
    <link>http://www.garchibald.com/blog/</link>
    <description>Continuous Improvement</description>
    <language>en-us</language>
    <copyright>Grant Archibald</copyright>
    <lastBuildDate>Fri, 06 Feb 2009 02:53:31 GMT</lastBuildDate>
    <generator>newtelligence dasBlog 2.1.8102.813</generator>
    <managingEditor>http://kontactr.com/user/garchibald</managingEditor>
    <webMaster>http://kontactr.com/user/garchibald</webMaster>
    <item>
      <trackback:ping>http://www.garchibald.com/blog/Trackback.aspx?guid=d3febb59-26c6-408c-8986-77b9a496bca6</trackback:ping>
      <pingback:server>http://www.garchibald.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.garchibald.com/blog/PermaLink,guid,d3febb59-26c6-408c-8986-77b9a496bca6.aspx</pingback:target>
      <dc:creator>Grant Archibald</dc:creator>
      <wfw:comment>http://www.garchibald.com/blog/CommentView,guid,d3febb59-26c6-408c-8986-77b9a496bca6.aspx</wfw:comment>
      <wfw:commentRss>http://www.garchibald.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=d3febb59-26c6-408c-8986-77b9a496bca6</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
In this post I will cover the changes required to use a PasswordBox control to display
the FTP password. 
</p>
        <p>
The following links a quick reference to the topics covered:
</p>
        <ul>
          <li>
            <a href="#FTPPluginOverview">FTP Plug-in Overview</a> – Quick description of the plug-in
control created by Tim Heuer. 
</li>
          <li>
            <a href="#FTPPluginChanges">FTP Plug-in Changes</a> – Steps to change the plug-in
to use a PasswordBox control instead of TextBox. 
</li>
          <li>
            <a href="#TestingTheChanges">Testing The Changes</a> – Describes testing the changes
with Expression Encoder and the issues encountered. 
</li>
          <li>
            <a href="#PasswordBoxStyles">PasswordBox Styles</a> – Describes to changes made to
alter the style for the PasswordBox control so that it has consistent look and feel. 
</li>
          <li>
            <a href="#InvestigatingDefaultStyles">Investigating Default Styles</a> - Investigating
the Expression Encoder WPF Styles using Redgate’s .Net Reflector. 
</li>
          <li>
            <a href="#FinalVersion">Final Version</a> – Describes the final version incorporating
the style changes in the previous sections. 
</li>
          <li>
            <a href="#Review">Review</a> – Describes the step taken to modify the plug-in to make
use the of a PasswordBox control.</li>
        </ul>
        <p>
Technologies Used
</p>
        <ul>
          <li>
Microsoft Visual Studio 2008 (with .Net 3.5 SP1 <a href="http://www.microsoft.com/net/">installed</a>) 
</li>
          <li>
Microsoft Expression Encoder 2 (with Expression Encoder 2 SP1 <a href="http://www.microsoft.com/downloads/details.aspx?FamilyId=A29BE9F9-29E1-4E70-BF67-02D87D3E556E&amp;displaylang=en">installed</a>)</li>
        </ul>
        <h2>
          <a name="FTPPluginOverview">FTP Plug-in Overview</a>
        </h2>
        <p>
The <a href="http://www.codeplex.com/encoderftppublish">FTP Publishing Plug-in for
Encoder</a> created by <a href="http://timheuer.com/blog/">Tim Heuer</a> allows the
encoded output of to be “published” to a FTP server for hosting. One minor issue from
a security point of view is the password is shown in clear text. As a result the password
is always visible and it could represent a security risk.
</p>
        <p>
          <img src="http://www.garchibald.com/images/Expression-Encoder-FTP-Plugin/ClearTextPassword.jpg" />
        </p>
        <p>
        </p>
        <p>
In the next section I will look at replacing the standard WPF text TextBox control
with a PasswordBox so that the password is masked from the user.
</p>
        <h2>
          <a name="FTPPluginChanges">FTP Plug-in Changes</a>
        </h2>
        <p>
Looking at the original XAML it is a standard TextBox that makes use of data binding
to load and save changes. 
</p>
        <div style="margin: 0px; padding: 0px; display: inline; float: none;" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:2ec36460-addf-430b-b968-e1738ba932c5" class="wlWriterEditableSmartContent">
          <pre name="code" class="xml">&lt;Label Grid.Column="0" Grid.Row="2" HorizontalAlignment="Right" Margin="0,0,3,0" Content="Password" /&gt;
&lt;TextBox Name="Password" Grid.Row="2" Grid.Column="1" ToolTip="FTP account password" Margin="0,2.5,0,2.5" Text="{Binding Path=Password, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" /&gt;</pre>
        </div>
        <p>
The obvious change to replace this with a PasswordBox and bind to the Password property
instead of the Text property. 
</p>
        <div style="margin: 0px; padding: 0px; display: inline; float: none;" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:8a02ca6c-3e70-46b5-b18b-7f0436fab20e" class="wlWriterEditableSmartContent">
          <pre name="code" class="xml">        &lt;Label Grid.Column="0" Grid.Row="2" HorizontalAlignment="Right" Margin="0,0,3,0" Content="Password" /&gt;
        &lt;PasswordBox  Name="Password" Grid.Row="2" Grid.Column="1" ToolTip="FTP account password" Margin="0,2.5,0,2.5" Password="{Binding Path=Password, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" /&gt;
</pre>
        </div>
        <p>
This however generates an error. Looking at the problem further, Samuel Jack provides
the explanation in his post <a href="http://blog.functionalfun.net/2008/06/wpf-passwordbox-and-data-binding.html">WPF
PasswordBox and Data binding</a>. In the post he discusses how the Password property
is a plain CLR property rather than a <a href="http://msdn.microsoft.com/en-us/library/system.windows.dependencyproperty.aspx">Dependency
Property</a>, so it doesn't support being the target of a data binding. Using Samuel’s
solution the code is easily modified to make use of attached properties by adding
a attribute namespace reference at the top of the UserControl
</p>
        <p>
        </p>
        <div style="margin: 0px; padding: 0px; display: inline; float: none;" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:8024c6c1-d5ce-4041-9068-6300866da537" class="wlWriterEditableSmartContent">
          <pre name="code" class="xml">xmlns:FtpPublish="clr-namespace:TimHeuer.Expression.FtpPublish"</pre>
        </div>
        <p>
Combined with additions to the the PasswordBox xaml to make use of the attached properties
</p>
        <div style="margin: 0px; padding: 0px; display: inline; float: none;" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:f9cc00bc-34e8-4cc9-8317-a374cd81e711" class="wlWriterEditableSmartContent">
          <pre name="code" class="xml">&lt;Label Grid.Column="0" Grid.Row="2" HorizontalAlignment="Right" Margin="0,0,3,0" Content="Password" /&gt;
&lt;PasswordBox  Name="Password" Grid.Row="2" Grid.Column="1" ToolTip="FTP account password" Margin="0,2.5,0,2.5" FtpPublish:PasswordBoxAssistant.BindPassword="true" FtpPublish:PasswordBoxAssistant.BoundPassword="{Binding Path=Password, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" /&gt;</pre>
        </div>
        <p>
        </p>
        <p>
And adding the following C# class to define the implementation of the PasswordBoxAssistant
class.
</p>
        <p>
        </p>
        <div style="margin: 0px; padding: 0px; display: inline; float: none;" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:b930a322-c7bb-4a2f-94b6-5952825c049e" class="wlWriterEditableSmartContent">
          <pre name="code" class="c#">using System.Windows;
using System.Windows.Controls;

namespace TimHeuer.Expression.FtpPublish
{
    /// &lt;summary&gt;
    /// Class that allows a &lt;see cref="PasswordBox"/&gt; to be included in DataBinding using attached properties
    /// &lt;/summary&gt;
    /// &lt;remarks&gt;
    /// Original source http://blog.functionalfun.net/2008/06/wpf-passwordbox-and-data-binding.html
    /// &lt;/remarks&gt;
    public static class PasswordBoxAssistant
    {
        public static readonly DependencyProperty BoundPassword =
            DependencyProperty.RegisterAttached("BoundPassword", typeof(string), typeof(PasswordBoxAssistant), new FrameworkPropertyMetadata(string.Empty, OnBoundPasswordChanged));

        public static readonly DependencyProperty BindPassword = DependencyProperty.RegisterAttached(
            "BindPassword", typeof(bool), typeof(PasswordBoxAssistant), new PropertyMetadata(false, OnBindPasswordChanged));

        private static readonly DependencyProperty UpdatingPassword =
            DependencyProperty.RegisterAttached("UpdatingPassword", typeof(bool), typeof(PasswordBoxAssistant));

        private static void OnBoundPasswordChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var box = d as PasswordBox;

            // only handle this event when the property is attached to a PasswordBox
            // and when the BindPassword attached property has been set to true
            if (box == null || !GetBindPassword(d))
            {
                return;
            }

            // avoid recursive updating by ignoring the box's changed event
            box.PasswordChanged -= HandlePasswordChanged;

            var newPassword = (string)e.NewValue;

            if (!GetUpdatingPassword(box))
            {
                box.Password = newPassword;
            }

            box.PasswordChanged += HandlePasswordChanged;
        }

        private static void OnBindPasswordChanged(DependencyObject dp, DependencyPropertyChangedEventArgs e)
        {
            // when the BindPassword attached property is set on a PasswordBox,
            // start listening to its PasswordChanged event

            var box = dp as PasswordBox;

            if (box == null)
            {
                return;
            }

            var wasBound = (bool)(e.OldValue);
            var needToBind = (bool)(e.NewValue);

            if (wasBound)
            {
                box.PasswordChanged -= HandlePasswordChanged;
            }

            if (needToBind)
            {
                box.PasswordChanged += HandlePasswordChanged;
            }
        }

        private static void HandlePasswordChanged(object sender, RoutedEventArgs e)
        {
            var box = sender as PasswordBox;

            if (box == null)
                return;

            // set a flag to indicate that we're updating the password
            SetUpdatingPassword(box, true);
            // push the new password into the BoundPassword property
            SetBoundPassword(box, box.Password);
            SetUpdatingPassword(box, false);
        }

        public static void SetBindPassword(DependencyObject dp, bool value)
        {
            dp.SetValue(BindPassword, value);
        }

        public static bool GetBindPassword(DependencyObject dp)
        {
            return (bool)dp.GetValue(BindPassword);
        }

        public static string GetBoundPassword(DependencyObject dp)
        {
            return (string)dp.GetValue(BoundPassword);
        }

        public static void SetBoundPassword(DependencyObject dp, string value)
        {
            dp.SetValue(BoundPassword, value);
        }

        private static bool GetUpdatingPassword(DependencyObject dp)
        {
            return (bool)dp.GetValue(UpdatingPassword);
        }

        private static void SetUpdatingPassword(DependencyObject dp, bool value)
        {
            dp.SetValue(UpdatingPassword, value);
        }
    }
}
</pre>
        </div>
        <h2>
          <a name="TestingTheChanges">Testing The Changes</a>
        </h2>
        <p>
Copying the updated dll to the &lt;Program Files&gt;\Microsoft Expression\Encoder
2\Plugins folder, the plug-in now correctly loads but the password box does not have
the correct visual styles applied to it because the PasswordBox has not been included
in the template styles for the WPF plug-in.
</p>
        <p>
          <img src="http://www.garchibald.com/images/Expression-Encoder-FTP-Plugin/ChangedPasswordBoxNoStyle.jpg" />
        </p>
        <p>
Overall the control is missing the following functionality:
</p>
        <ul>
          <li>
The correct background colour. 
</li>
          <li>
Rounded corners on the control border, 
</li>
          <li>
Missing a password character to display when characters are typed.</li>
        </ul>
        <p>
The next sections will look at adding applying styles to the PasswordBox so that it
is consistent with the rest of the plug-in.
</p>
        <h2>
          <a name="PasswordBoxStyles">PasswordBox Styles</a>
        </h2>
        <p>
Adjusting The style of the password box can be performed by altering the UserControl
resources of the StandardSettings.xaml. An example of how apply the rounded corners
is provided by Tamir Khason on the <a href="http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/e4e0c12f-b8df-4bb0-b0df-aef359b241da/">msdn
forums</a>. Tweaking example slightly to only have a border radius of 2 gives the
following xaml to be added to the xaml file.
</p>
        <div style="margin: 0px; padding: 0px; display: inline; float: none;" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:cbfb90a9-cf18-494d-9e84-7290d6a1776f" class="wlWriterEditableSmartContent">
          <pre name="code" class="xml">&lt;UserControl.Resources&gt;
    &lt;Style TargetType="PasswordBox"&gt;
        &lt;Setter Property="PasswordChar" Value="●"/&gt;
        &lt;Setter Property="KeyboardNavigation.TabNavigation" Value="None"/&gt;
        &lt;Setter Property="BorderThickness" Value="1"/&gt;
        &lt;Setter Property="HorizontalContentAlignment" Value="Left"/&gt;
        &lt;Setter Property="Padding" Value="1"/&gt;
        &lt;Setter Property="FocusVisualStyle" Value="{x:Null}"/&gt;
        &lt;Setter Property="AllowDrop" Value="true"/&gt;
        &lt;Setter Property="Template"&gt;
            &lt;Setter.Value&gt;
                &lt;ControlTemplate TargetType="PasswordBox"&gt;
                    &lt;Border CornerRadius="2" x:Name="Bd" Background="{DynamicResource WindowBackgroundBrush}" BorderBrush="Black" BorderThickness="1" OpacityMask="{x:Null}"&gt;
                        &lt;ScrollViewer SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" x:Name="PART_ContentHost" Template="{DynamicResource ScrollViewerControlTemplate1}"/&gt;
                    &lt;/Border&gt;
                    &lt;ControlTemplate.Triggers&gt;
                        &lt;Trigger Property="IsEnabled" Value="false"&gt;
                            &lt;Setter Property="Background" TargetName="Bd" Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"/&gt;
                            &lt;Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/&gt;
                        &lt;/Trigger&gt;
                    &lt;/ControlTemplate.Triggers&gt;
                &lt;/ControlTemplate&gt;
            &lt;/Setter.Value&gt;
        &lt;/Setter&gt;
    &lt;/Style&gt;
&lt;/UserControl.Resources&gt;</pre>
        </div>
        <p>
Which gives the following output
</p>
        <p>
          <img src="http://www.garchibald.com/images/Expression-Encoder-FTP-Plugin/PasswordBoxWithRoundedCorners.jpg" />
        </p>
        <p>
This style is much closer, but it gives the impression that the password box is not
editable by the user. In the next section I will make use Redgate’s .Net Reflector
to determine the styles used by the Expression Encoder UI to provide a more consistent
look and feel.
</p>
        <h2>
          <a name="InvestigatingDefaultStyles">Investigating Default Styles</a>
        </h2>
        <p>
The expression encoder is written using Microsoft.Net and WPF. As result the styles
and user interface as stored within the application assemblies and binary files. Using <a href="http://www.red-gate.com/products/reflector/">Redgates
.Net Reflector</a> together with the <a href="http://www.codeplex.com/reflectoraddins/Wiki/View.aspx?title=BamlViewer&amp;referringTitle=Home">BAML
viewer addin</a> available on codeplex we can look inside these file and discover
the styles used in the application.
</p>
        <p>
The main WPF application is located in &lt;Program Files&gt;\Microsoft Expression\Encoder
2\EncoderUI.exe and the english resource files that include the xaml for the application
is located in &lt;Program Files&gt;\Microsoft Expression\Encoder 2\en\EncoderUI.resources.dll.
Opening these files in reflector we are able to look at the implementation of the
application.
</p>
        <p>
 <img src="http://www.garchibald.com/images/Expression-Encoder-FTP-Plugin/RegateNetReflectorResourcesPasswordDialog.jpg" /></p>
        <p>
Looking at the xaml the style for a password box within the resources assembly the
dynamic resource BackgroundBrush should be applied for the BorderBrush and the Background
properties of the PasswordBox.
</p>
        <div style="margin: 0px; padding: 0px; display: inline; float: none;" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:7843839c-b5fa-4104-97b7-315c7be03697" class="wlWriterEditableSmartContent">
          <pre name="code" class="xml">&lt;Style x:Uid="Style_84" TargetType="{x:Type PasswordBox}"&gt;
    &lt;Setter x:Uid="Setter_1349" Property="BorderBrush" Value="{DynamicResource BackgroundBrush}" /&gt;
    &lt;Setter x:Uid="Setter_1350" Property="Foreground" Value="{DynamicResource Text1Brush}" /&gt;
    &lt;Setter x:Uid="Setter_1351" Property="Background" Value="{DynamicResource BackgroundBrush}" /&gt;
    &lt;Setter x:Uid="Setter_1146" Property="FontFamily" Value="{DynamicResource {x:Static MessageFontFamily}}" /&gt;
    &lt;Setter x:Uid="Setter_1147" Property="FontSize" Value="{DynamicResource {x:Static MessageFontSize}}" /&gt;
    &lt;Setter x:Uid="Setter_1148" Property="FontWeight" Value="{DynamicResource {x:Static MessageFontWeight}}" /&gt;
&lt;/Style&gt;</pre>
        </div>
        <p>
        </p>
        <h2>
          <a name="FinalVersion">Final Version</a>
        </h2>
        <p>
Applying the style changes in the last section provides the following UserControl.Resources
section. 
</p>
        <div style="margin: 0px; padding: 0px; display: inline; float: none;" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:97a5c392-7402-4958-bd8d-1faefaa4bd29" class="wlWriterEditableSmartContent">
          <pre name="code" class="xml">&lt;UserControl.Resources&gt;
    &lt;Style TargetType="PasswordBox"&gt;
        &lt;Setter Property="PasswordChar" Value="●"/&gt;
        &lt;Setter Property="KeyboardNavigation.TabNavigation" Value="None"/&gt;
        &lt;Setter Property="BorderThickness" Value="1"/&gt;
        &lt;Setter Property="HorizontalContentAlignment" Value="Left"/&gt;
        &lt;Setter Property="Padding" Value="1"/&gt;
        &lt;Setter Property="FocusVisualStyle" Value="{x:Null}"/&gt;
        &lt;Setter Property="AllowDrop" Value="true"/&gt;
        &lt;Setter Property="Template"&gt;
            &lt;Setter.Value&gt;
                &lt;ControlTemplate TargetType="PasswordBox"&gt;
                    &lt;Border CornerRadius="2" x:Name="Bd" Background="{DynamicResource BackgroundBrush}" BorderBrush="{DynamicResource BackgroundBrush}" BorderThickness="1" OpacityMask="{x:Null}"&gt;
                        &lt;ScrollViewer SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" x:Name="PART_ContentHost" Template="{DynamicResource ScrollViewerControlTemplate1}"/&gt;
                    &lt;/Border&gt;
                    &lt;ControlTemplate.Triggers&gt;
                        &lt;Trigger Property="IsEnabled" Value="false"&gt;
                            &lt;Setter Property="Background" TargetName="Bd" Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"/&gt;
                            &lt;Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/&gt;
                        &lt;/Trigger&gt;
                    &lt;/ControlTemplate.Triggers&gt;
                &lt;/ControlTemplate&gt;
            &lt;/Setter.Value&gt;
        &lt;/Setter&gt;
    &lt;/Style&gt;
&lt;/UserControl.Resources&gt;</pre>
        </div>
        <p>
With an output of 
</p>
        <p>
          <img src="http://www.garchibald.com/images/Expression-Encoder-FTP-Plugin/PasswordBoxWithUpdatedBackground.jpg" />
        </p>
        <h2>
          <a name="Review">Review</a>
        </h2>
        <p>
So there we have it, the plug-in look and feel was updated by altering the XAML to
make use of Password box. The changes required the use of WPF attached properties
to ensure the data binding continues to work with he original code. To make the user
interface look consistent with rest of the plug-in UserControl resources where used
to apply the correct styles and resources.
</p>
        <img width="0" height="0" src="http://www.garchibald.com/blog/aggbug.ashx?id=d3febb59-26c6-408c-8986-77b9a496bca6" />
      </body>
      <title>Extending the Expression Encoder 2 FTP Publishing Plug-in – Adding a WPF PasswordBox And UserControl Style</title>
      <guid isPermaLink="false">http://www.garchibald.com/blog/PermaLink,guid,d3febb59-26c6-408c-8986-77b9a496bca6.aspx</guid>
      <link>http://www.garchibald.com/blog/2009/02/06/ExtendingTheExpressionEncoder2FTPPublishingPluginAddingAWPFPasswordBoxAndUserControlStyle.aspx</link>
      <pubDate>Fri, 06 Feb 2009 02:53:31 GMT</pubDate>
      <description>&lt;p&gt;
In this post I will cover the changes required to use a PasswordBox control to display
the FTP password. 
&lt;/p&gt;
&lt;p&gt;
The following links a quick reference to the topics covered:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;a href="#FTPPluginOverview"&gt;FTP Plug-in Overview&lt;/a&gt; – Quick description of the plug-in
control created by Tim Heuer. 
&lt;/li&gt;
&lt;li&gt;
&lt;a href="#FTPPluginChanges"&gt;FTP Plug-in Changes&lt;/a&gt; – Steps to change the plug-in
to use a PasswordBox control instead of TextBox. 
&lt;/li&gt;
&lt;li&gt;
&lt;a href="#TestingTheChanges"&gt;Testing The Changes&lt;/a&gt; – Describes testing the changes
with Expression Encoder and the issues encountered. 
&lt;/li&gt;
&lt;li&gt;
&lt;a href="#PasswordBoxStyles"&gt;PasswordBox Styles&lt;/a&gt; – Describes to changes made to
alter the style for the PasswordBox control so that it has consistent look and feel. 
&lt;/li&gt;
&lt;li&gt;
&lt;a href="#InvestigatingDefaultStyles"&gt;Investigating Default Styles&lt;/a&gt; - Investigating
the Expression Encoder WPF Styles using Redgate’s .Net Reflector. 
&lt;/li&gt;
&lt;li&gt;
&lt;a href="#FinalVersion"&gt;Final Version&lt;/a&gt; – Describes the final version incorporating
the style changes in the previous sections. 
&lt;/li&gt;
&lt;li&gt;
&lt;a href="#Review"&gt;Review&lt;/a&gt; – Describes the step taken to modify the plug-in to make
use the of a PasswordBox control.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
Technologies Used
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
Microsoft Visual Studio 2008 (with .Net 3.5 SP1 &lt;a href="http://www.microsoft.com/net/"&gt;installed&lt;/a&gt;) 
&lt;/li&gt;
&lt;li&gt;
Microsoft Expression Encoder 2 (with Expression Encoder 2 SP1 &lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyId=A29BE9F9-29E1-4E70-BF67-02D87D3E556E&amp;amp;displaylang=en"&gt;installed&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;&lt;a name="FTPPluginOverview"&gt;FTP Plug-in Overview&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;
The &lt;a href="http://www.codeplex.com/encoderftppublish"&gt;FTP Publishing Plug-in for
Encoder&lt;/a&gt; created by &lt;a href="http://timheuer.com/blog/"&gt;Tim Heuer&lt;/a&gt; allows the
encoded output of to be “published” to a FTP server for hosting. One minor issue from
a security point of view is the password is shown in clear text. As a result the password
is always visible and it could represent a security risk.
&lt;/p&gt;
&lt;p&gt;
&lt;img src="http://www.garchibald.com/images/Expression-Encoder-FTP-Plugin/ClearTextPassword.jpg"&gt; 
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
In the next section I will look at replacing the standard WPF text TextBox control
with a PasswordBox so that the password is masked from the user.
&lt;/p&gt;
&lt;h2&gt;&lt;a name="FTPPluginChanges"&gt;FTP Plug-in Changes&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;
Looking at the original XAML it is a standard TextBox that makes use of data binding
to load and save changes. 
&lt;/p&gt;
&lt;div style="margin: 0px; padding: 0px; display: inline; float: none;" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:2ec36460-addf-430b-b968-e1738ba932c5" class="wlWriterEditableSmartContent"&gt;&lt;pre name="code" class="xml"&gt;&amp;lt;Label Grid.Column="0" Grid.Row="2" HorizontalAlignment="Right" Margin="0,0,3,0" Content="Password" /&amp;gt;
&amp;lt;TextBox Name="Password" Grid.Row="2" Grid.Column="1" ToolTip="FTP account password" Margin="0,2.5,0,2.5" Text="{Binding Path=Password, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" /&amp;gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;
The obvious change to replace this with a PasswordBox and bind to the Password property
instead of the Text property. 
&lt;/p&gt;
&lt;div style="margin: 0px; padding: 0px; display: inline; float: none;" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:8a02ca6c-3e70-46b5-b18b-7f0436fab20e" class="wlWriterEditableSmartContent"&gt;&lt;pre name="code" class="xml"&gt;        &amp;lt;Label Grid.Column="0" Grid.Row="2" HorizontalAlignment="Right" Margin="0,0,3,0" Content="Password" /&amp;gt;
        &amp;lt;PasswordBox  Name="Password" Grid.Row="2" Grid.Column="1" ToolTip="FTP account password" Margin="0,2.5,0,2.5" Password="{Binding Path=Password, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" /&amp;gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;
This however generates an error. Looking at the problem further, Samuel Jack provides
the explanation in his post &lt;a href="http://blog.functionalfun.net/2008/06/wpf-passwordbox-and-data-binding.html"&gt;WPF
PasswordBox and Data binding&lt;/a&gt;. In the post he discusses how the Password property
is a plain CLR property rather than a &lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.dependencyproperty.aspx"&gt;Dependency
Property&lt;/a&gt;, so it doesn't support being the target of a data binding. Using Samuel’s
solution the code is easily modified to make use of attached properties by adding
a attribute namespace reference at the top of the UserControl
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;div style="margin: 0px; padding: 0px; display: inline; float: none;" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:8024c6c1-d5ce-4041-9068-6300866da537" class="wlWriterEditableSmartContent"&gt;&lt;pre name="code" class="xml"&gt;xmlns:FtpPublish="clr-namespace:TimHeuer.Expression.FtpPublish"&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;
Combined with additions to the the PasswordBox xaml to make use of the attached properties
&lt;/p&gt;
&lt;div style="margin: 0px; padding: 0px; display: inline; float: none;" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:f9cc00bc-34e8-4cc9-8317-a374cd81e711" class="wlWriterEditableSmartContent"&gt;&lt;pre name="code" class="xml"&gt;&amp;lt;Label Grid.Column="0" Grid.Row="2" HorizontalAlignment="Right" Margin="0,0,3,0" Content="Password" /&amp;gt;
&amp;lt;PasswordBox  Name="Password" Grid.Row="2" Grid.Column="1" ToolTip="FTP account password" Margin="0,2.5,0,2.5" FtpPublish:PasswordBoxAssistant.BindPassword="true" FtpPublish:PasswordBoxAssistant.BoundPassword="{Binding Path=Password, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" /&amp;gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
And adding the following C# class to define the implementation of the PasswordBoxAssistant
class.
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;div style="margin: 0px; padding: 0px; display: inline; float: none;" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:b930a322-c7bb-4a2f-94b6-5952825c049e" class="wlWriterEditableSmartContent"&gt;&lt;pre name="code" class="c#"&gt;using System.Windows;
using System.Windows.Controls;

namespace TimHeuer.Expression.FtpPublish
{
    /// &amp;lt;summary&amp;gt;
    /// Class that allows a &amp;lt;see cref="PasswordBox"/&amp;gt; to be included in DataBinding using attached properties
    /// &amp;lt;/summary&amp;gt;
    /// &amp;lt;remarks&amp;gt;
    /// Original source http://blog.functionalfun.net/2008/06/wpf-passwordbox-and-data-binding.html
    /// &amp;lt;/remarks&amp;gt;
    public static class PasswordBoxAssistant
    {
        public static readonly DependencyProperty BoundPassword =
            DependencyProperty.RegisterAttached("BoundPassword", typeof(string), typeof(PasswordBoxAssistant), new FrameworkPropertyMetadata(string.Empty, OnBoundPasswordChanged));

        public static readonly DependencyProperty BindPassword = DependencyProperty.RegisterAttached(
            "BindPassword", typeof(bool), typeof(PasswordBoxAssistant), new PropertyMetadata(false, OnBindPasswordChanged));

        private static readonly DependencyProperty UpdatingPassword =
            DependencyProperty.RegisterAttached("UpdatingPassword", typeof(bool), typeof(PasswordBoxAssistant));

        private static void OnBoundPasswordChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var box = d as PasswordBox;

            // only handle this event when the property is attached to a PasswordBox
            // and when the BindPassword attached property has been set to true
            if (box == null || !GetBindPassword(d))
            {
                return;
            }

            // avoid recursive updating by ignoring the box's changed event
            box.PasswordChanged -= HandlePasswordChanged;

            var newPassword = (string)e.NewValue;

            if (!GetUpdatingPassword(box))
            {
                box.Password = newPassword;
            }

            box.PasswordChanged += HandlePasswordChanged;
        }

        private static void OnBindPasswordChanged(DependencyObject dp, DependencyPropertyChangedEventArgs e)
        {
            // when the BindPassword attached property is set on a PasswordBox,
            // start listening to its PasswordChanged event

            var box = dp as PasswordBox;

            if (box == null)
            {
                return;
            }

            var wasBound = (bool)(e.OldValue);
            var needToBind = (bool)(e.NewValue);

            if (wasBound)
            {
                box.PasswordChanged -= HandlePasswordChanged;
            }

            if (needToBind)
            {
                box.PasswordChanged += HandlePasswordChanged;
            }
        }

        private static void HandlePasswordChanged(object sender, RoutedEventArgs e)
        {
            var box = sender as PasswordBox;

            if (box == null)
                return;

            // set a flag to indicate that we're updating the password
            SetUpdatingPassword(box, true);
            // push the new password into the BoundPassword property
            SetBoundPassword(box, box.Password);
            SetUpdatingPassword(box, false);
        }

        public static void SetBindPassword(DependencyObject dp, bool value)
        {
            dp.SetValue(BindPassword, value);
        }

        public static bool GetBindPassword(DependencyObject dp)
        {
            return (bool)dp.GetValue(BindPassword);
        }

        public static string GetBoundPassword(DependencyObject dp)
        {
            return (string)dp.GetValue(BoundPassword);
        }

        public static void SetBoundPassword(DependencyObject dp, string value)
        {
            dp.SetValue(BoundPassword, value);
        }

        private static bool GetUpdatingPassword(DependencyObject dp)
        {
            return (bool)dp.GetValue(UpdatingPassword);
        }

        private static void SetUpdatingPassword(DependencyObject dp, bool value)
        {
            dp.SetValue(UpdatingPassword, value);
        }
    }
}
&lt;/pre&gt;
&lt;/div&gt;
&lt;h2&gt;&lt;a name="TestingTheChanges"&gt;Testing The Changes&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;
Copying the updated dll to the &amp;lt;Program Files&amp;gt;\Microsoft Expression\Encoder
2\Plugins folder, the plug-in now correctly loads but the password box does not have
the correct visual styles applied to it because the PasswordBox has not been included
in the template styles for the WPF plug-in.
&lt;/p&gt;
&lt;p&gt;
&lt;img src="http://www.garchibald.com/images/Expression-Encoder-FTP-Plugin/ChangedPasswordBoxNoStyle.jpg"&gt; 
&lt;/p&gt;
&lt;p&gt;
Overall the control is missing the following functionality:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
The correct background colour. 
&lt;/li&gt;
&lt;li&gt;
Rounded corners on the control border, 
&lt;/li&gt;
&lt;li&gt;
Missing a password character to display when characters are typed.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
The next sections will look at adding applying styles to the PasswordBox so that it
is consistent with the rest of the plug-in.
&lt;/p&gt;
&lt;h2&gt;&lt;a name="PasswordBoxStyles"&gt;PasswordBox Styles&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;
Adjusting The style of the password box can be performed by altering the UserControl
resources of the StandardSettings.xaml. An example of how apply the rounded corners
is provided by Tamir Khason on the &lt;a href="http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/e4e0c12f-b8df-4bb0-b0df-aef359b241da/"&gt;msdn
forums&lt;/a&gt;. Tweaking example slightly to only have a border radius of 2 gives the
following xaml to be added to the xaml file.
&lt;/p&gt;
&lt;div style="margin: 0px; padding: 0px; display: inline; float: none;" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:cbfb90a9-cf18-494d-9e84-7290d6a1776f" class="wlWriterEditableSmartContent"&gt;&lt;pre name="code" class="xml"&gt;&amp;lt;UserControl.Resources&amp;gt;
    &amp;lt;Style TargetType="PasswordBox"&amp;gt;
        &amp;lt;Setter Property="PasswordChar" Value="●"/&amp;gt;
        &amp;lt;Setter Property="KeyboardNavigation.TabNavigation" Value="None"/&amp;gt;
        &amp;lt;Setter Property="BorderThickness" Value="1"/&amp;gt;
        &amp;lt;Setter Property="HorizontalContentAlignment" Value="Left"/&amp;gt;
        &amp;lt;Setter Property="Padding" Value="1"/&amp;gt;
        &amp;lt;Setter Property="FocusVisualStyle" Value="{x:Null}"/&amp;gt;
        &amp;lt;Setter Property="AllowDrop" Value="true"/&amp;gt;
        &amp;lt;Setter Property="Template"&amp;gt;
            &amp;lt;Setter.Value&amp;gt;
                &amp;lt;ControlTemplate TargetType="PasswordBox"&amp;gt;
                    &amp;lt;Border CornerRadius="2" x:Name="Bd" Background="{DynamicResource WindowBackgroundBrush}" BorderBrush="Black" BorderThickness="1" OpacityMask="{x:Null}"&amp;gt;
                        &amp;lt;ScrollViewer SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" x:Name="PART_ContentHost" Template="{DynamicResource ScrollViewerControlTemplate1}"/&amp;gt;
                    &amp;lt;/Border&amp;gt;
                    &amp;lt;ControlTemplate.Triggers&amp;gt;
                        &amp;lt;Trigger Property="IsEnabled" Value="false"&amp;gt;
                            &amp;lt;Setter Property="Background" TargetName="Bd" Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"/&amp;gt;
                            &amp;lt;Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/&amp;gt;
                        &amp;lt;/Trigger&amp;gt;
                    &amp;lt;/ControlTemplate.Triggers&amp;gt;
                &amp;lt;/ControlTemplate&amp;gt;
            &amp;lt;/Setter.Value&amp;gt;
        &amp;lt;/Setter&amp;gt;
    &amp;lt;/Style&amp;gt;
&amp;lt;/UserControl.Resources&amp;gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;
Which gives the following output
&lt;/p&gt;
&lt;p&gt;
&lt;img src="http://www.garchibald.com/images/Expression-Encoder-FTP-Plugin/PasswordBoxWithRoundedCorners.jpg"&gt;
&lt;/p&gt;
&lt;p&gt;
This style is much closer, but it gives the impression that the password box is not
editable by the user. In the next section I will make use Redgate’s .Net Reflector
to determine the styles used by the Expression Encoder UI to provide a more consistent
look and feel.
&lt;/p&gt;
&lt;h2&gt;&lt;a name="InvestigatingDefaultStyles"&gt;Investigating Default Styles&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;
The expression encoder is written using Microsoft.Net and WPF. As result the styles
and user interface as stored within the application assemblies and binary files. Using &lt;a href="http://www.red-gate.com/products/reflector/"&gt;Redgates
.Net Reflector&lt;/a&gt; together with the &lt;a href="http://www.codeplex.com/reflectoraddins/Wiki/View.aspx?title=BamlViewer&amp;amp;referringTitle=Home"&gt;BAML
viewer addin&lt;/a&gt; available on codeplex we can look inside these file and discover
the styles used in the application.
&lt;/p&gt;
&lt;p&gt;
The main WPF application is located in &amp;lt;Program Files&amp;gt;\Microsoft Expression\Encoder
2\EncoderUI.exe and the english resource files that include the xaml for the application
is located in &amp;lt;Program Files&amp;gt;\Microsoft Expression\Encoder 2\en\EncoderUI.resources.dll.
Opening these files in reflector we are able to look at the implementation of the
application.
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;&lt;img src="http://www.garchibald.com/images/Expression-Encoder-FTP-Plugin/RegateNetReflectorResourcesPasswordDialog.jpg"&gt;
&lt;/p&gt;
&lt;p&gt;
Looking at the xaml the style for a password box within the resources assembly the
dynamic resource BackgroundBrush should be applied for the BorderBrush and the Background
properties of the PasswordBox.
&lt;/p&gt;
&lt;div style="margin: 0px; padding: 0px; display: inline; float: none;" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:7843839c-b5fa-4104-97b7-315c7be03697" class="wlWriterEditableSmartContent"&gt;&lt;pre name="code" class="xml"&gt;&amp;lt;Style x:Uid="Style_84" TargetType="{x:Type PasswordBox}"&amp;gt;
    &amp;lt;Setter x:Uid="Setter_1349" Property="BorderBrush" Value="{DynamicResource BackgroundBrush}" /&amp;gt;
    &amp;lt;Setter x:Uid="Setter_1350" Property="Foreground" Value="{DynamicResource Text1Brush}" /&amp;gt;
    &amp;lt;Setter x:Uid="Setter_1351" Property="Background" Value="{DynamicResource BackgroundBrush}" /&amp;gt;
    &amp;lt;Setter x:Uid="Setter_1146" Property="FontFamily" Value="{DynamicResource {x:Static MessageFontFamily}}" /&amp;gt;
    &amp;lt;Setter x:Uid="Setter_1147" Property="FontSize" Value="{DynamicResource {x:Static MessageFontSize}}" /&amp;gt;
    &amp;lt;Setter x:Uid="Setter_1148" Property="FontWeight" Value="{DynamicResource {x:Static MessageFontWeight}}" /&amp;gt;
&amp;lt;/Style&amp;gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;h2&gt;&lt;a name="FinalVersion"&gt;Final Version&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;
Applying the style changes in the last section provides the following UserControl.Resources
section. 
&lt;/p&gt;
&lt;div style="margin: 0px; padding: 0px; display: inline; float: none;" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:97a5c392-7402-4958-bd8d-1faefaa4bd29" class="wlWriterEditableSmartContent"&gt;&lt;pre name="code" class="xml"&gt;&amp;lt;UserControl.Resources&amp;gt;
    &amp;lt;Style TargetType="PasswordBox"&amp;gt;
        &amp;lt;Setter Property="PasswordChar" Value="●"/&amp;gt;
        &amp;lt;Setter Property="KeyboardNavigation.TabNavigation" Value="None"/&amp;gt;
        &amp;lt;Setter Property="BorderThickness" Value="1"/&amp;gt;
        &amp;lt;Setter Property="HorizontalContentAlignment" Value="Left"/&amp;gt;
        &amp;lt;Setter Property="Padding" Value="1"/&amp;gt;
        &amp;lt;Setter Property="FocusVisualStyle" Value="{x:Null}"/&amp;gt;
        &amp;lt;Setter Property="AllowDrop" Value="true"/&amp;gt;
        &amp;lt;Setter Property="Template"&amp;gt;
            &amp;lt;Setter.Value&amp;gt;
                &amp;lt;ControlTemplate TargetType="PasswordBox"&amp;gt;
                    &amp;lt;Border CornerRadius="2" x:Name="Bd" Background="{DynamicResource BackgroundBrush}" BorderBrush="{DynamicResource BackgroundBrush}" BorderThickness="1" OpacityMask="{x:Null}"&amp;gt;
                        &amp;lt;ScrollViewer SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" x:Name="PART_ContentHost" Template="{DynamicResource ScrollViewerControlTemplate1}"/&amp;gt;
                    &amp;lt;/Border&amp;gt;
                    &amp;lt;ControlTemplate.Triggers&amp;gt;
                        &amp;lt;Trigger Property="IsEnabled" Value="false"&amp;gt;
                            &amp;lt;Setter Property="Background" TargetName="Bd" Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"/&amp;gt;
                            &amp;lt;Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/&amp;gt;
                        &amp;lt;/Trigger&amp;gt;
                    &amp;lt;/ControlTemplate.Triggers&amp;gt;
                &amp;lt;/ControlTemplate&amp;gt;
            &amp;lt;/Setter.Value&amp;gt;
        &amp;lt;/Setter&amp;gt;
    &amp;lt;/Style&amp;gt;
&amp;lt;/UserControl.Resources&amp;gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;
With an output of 
&lt;/p&gt;
&lt;p&gt;
&lt;img src="http://www.garchibald.com/images/Expression-Encoder-FTP-Plugin/PasswordBoxWithUpdatedBackground.jpg"&gt;
&lt;/p&gt;
&lt;h2&gt;&lt;a name="Review"&gt;Review&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;
So there we have it, the plug-in look and feel was updated by altering the XAML to
make use of Password box. The changes required the use of WPF attached properties
to ensure the data binding continues to work with he original code. To make the user
interface look consistent with rest of the plug-in UserControl resources where used
to apply the correct styles and resources.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.garchibald.com/blog/aggbug.ashx?id=d3febb59-26c6-408c-8986-77b9a496bca6" /&gt;</description>
      <comments>http://www.garchibald.com/blog/CommentView,guid,d3febb59-26c6-408c-8986-77b9a496bca6.aspx</comments>
      <category>wpf</category>
      <category>xaml</category>
    </item>
  </channel>
</rss>