Dutton's blog

Auto-scrolling a WPF ListView when a new item is added

AKA: "How to give a WPF ListView a sticky bottom" but I thought better of making that the blog post title =)

If you've ever tried to auto-scroll a WPF ListView when a new item is added, you will find that as you can't access the ListView's internal ScrollViewer from XAML this is a trickier task than it should be.

Here is an auto-scrolling ListView that will ensure that any new items added will be automatically scrolled into view. This behavior is overridden if the scrollbar position is not currently at the bottom.

public class AutoScrollingListView : ListView
{
  private ScrollViewer _scrollViewer;


      
Using your own Fasthosts domain with Windows Azure Web Sites

I've now successfully moved two of my domains to Azure web hosting, I can't say it was a particularly quick process but it is relatively painless. The key is not to lose patience with the DNS updates as it can appear like nothing is working (all while your website is broken to the outside world) so I thought I'd document the moving of a third domain so you know what to expect. I use Fasthosts for all of my hosting needs, so my screenshots are from their domain management system, but I can't see why the same wouldn't work for other domain name providers that allow custom DNS.

Setting up the Windows Azure web site

OK, so first we need to set up an Azure web site for you to point your domain to, you can skip this if you've already got one.

  • Head over to https://manage.windowsazure.com/ and login to your Azure Dashboard.
  • Select the Web Sites option on the left hand bar, and if you haven't already got any websites set up you'll see something that looks like this.Azure Dashboard - No web sites
  • Select Create a Website (or click the big plus icon at the bottom of the page if you already have websites set up) and you'll see this.Azure Dashboard - New web site
  • From here you can create all sorts of websites from the gallery or a simple website via the Quick Create link. For the purposes of this tutorial, I'm going to use Quick Create to get something that I can use to test my domain forwarding is working. So choose a name (this will be your azurewebsites.net domain and so needs to be unique, the green tick will indicate when you've picked one that Microsoft is happy with, but don't get too hung up on it as no-one will see it. We're going to set up your own domain to forward to this later.
  • Click Create Website and you'll be taken back to the dashboard with your new website listed.
  • The Status column will show "Creating" for a while (mine took about 20 seconds at 1400BST on a Saturday) and then will look like this. Azure Dashboard - New web site created
  • Now, if I go to my new domain (rdutton.azurewebsites.net), I'll be greeted by this to confirm that my Azure Website is up and running.Azure web site new site default page

Configuring my own domain to use with Windows Azure websites

  • My domain 'rdutton.co.uk', is hosted over at Fasthosts, but I want to use it for my azure website. At the time of writing, Windows Azure doesn't support hosting domains so we need to do some poking about in my DNS records over in my Fasthosts Control Panel.
  • Go to https://www.fasthosts.co.uk/login/ and log into your control panel. If you've been following along from above, leave the Azure Dashboard open, you'll be needing that again soon.
  • From the Domain  tab, select Manage Domains. Fasthosts Dashboard - Manage Domains
  • And click on the DNS icon for the domain you want to change. Fasthosts Dashboard - DNS Domain Icon
  • From here you'll be taken to the Advanced DNS window, in this screenshot my domain is currently just set to the default Fasthosts settings. Fasthosts Dashboard - Advanced DNS Window
  • Go through and click Remove on all of the A Records and CNAME Records listed.
  • Keeping the Fasthosts page open, go back to the Azure dashboard and from the Web Sites list, click on the name of the website you want to edit.
  • Before you can use your own domain in Windows Azure, you need to change the scaling mode of your Azure website.

NB: This will change the Web Site Mode from Free so you will be charged for usage once you do this. Please consult the Azure price lists for more information.

Deleting photos from your iPhone or iPad with OS X

If you have more than a handful of photos you want to delete on an iPhone or iPad it can be a bit of a pain to do manually and I often find on my 4S that if you have too many photos, deleting the entire Camera Roll through Settings -> General -> Usage just doesn't work. Here's how to do it with a Mac.

NB: This will permanently delete photos from your phone, make sure you've backed up or sync'd anything you want to keep before doing this.

  1. Connect your phone via USB to your Mac.
  2. Open the Preview application, the easiest way is to search for it using Spotlight (the magnifying glass top right).
  3. Once open, from the File menu you should see your iOS device listed, mine's called "Richard's iPhone". Select Import from....
  4. You'll then see thumbnails of all of the photos on your device. I clearly like coffee =).
  5. Now select the photos you want to delete, either individually (holding down CMD to multi-select) or CMD-A to select all.
  6. And hit the delete button at the bottom.
  7. That's it.... it's as simple as that, you're photos will be deleted.
How to select all WPF TextBox text on focus using an Attached Behavior

UPDATE 12/11/2013: Fixed a mistake in the example code; the setter and getter shouldn't have "Property" in the name.

I have a simple requirement to select all of the text in a WPF TextBox when it receives focus, this lets a user tab through a bunch of TextBoxes and edit the values directly without having to use the mouse.

Although there are a few methods I could use, I thought I'd tackle this using the "Ramora", or "Attached Behavior" pattern. I always forget the syntax, hence this post.

Implementing an Attached Behavior involves creating a boolean Attached Property to indicate whether the behavior is to be applied, and then implementing the behavior in the property's change handler, like this:

    public class TextBoxBehavior
    {
        public static bool GetSelectAllTextOnFocus(TextBox textBox)
        {
            return (bool)textBox.GetValue(SelectAllTextOnFocusProperty);
        }

        public static void SetSelectAllTextOnFocus(TextBox textBox, bool value)
        {
            textBox.SetValue(SelectAllTextOnFocusProperty, value);
        }

        public static readonly DependencyProperty SelectAllTextOnFocusProperty =
            DependencyProperty.RegisterAttached(
                "SelectAllTextOnFocus",
                typeof (bool),
                typeof (TextBoxBehavior),
                new UIPropertyMetadata(false, OnSelectAllTextOnFocusChanged));

        private static void OnSelectAllTextOnFocusChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var textBox = d as TextBox;
            if (textBox == null) return;

            if (e.NewValue is bool == false) return;

            if ((bool) e.NewValue)
            {
                textBox.GotFocus += SelectAll;
                textBox.PreviewMouseDown += IgnoreMouseButton;
            }
            else
            {
                textBox.GotFocus -= SelectAll;
                textBox.PreviewMouseDown -= IgnoreMouseButton;
            }
        }

        private static void SelectAll(object sender, RoutedEventArgs e)
        {
            var textBox = e.OriginalSource as TextBox;
            if (textBox == null) return;
            textBox.SelectAll();
        }

        private static void IgnoreMouseButton(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            var textBox = sender as TextBox;
            if (textBox == null || textBox.IsKeyboardFocusWithin) return;

            e.Handled = true;
            textBox.Focus();
        }
    }

Which means you can use it like this in XAML:

<TextBox Text="Some Text" behaviors:TextBoxBehavior.SelectAllTextOnFocus="True"/>

So as you can see, it's really quite simple. I hook into the GotFocus event in `OnSelectAllTextOnFocusChanged`, and call `SelectAll` where I select all of the TextBox's text.

I added a further event handler to ensure that mouse clicks within the TextBox didn't highlight the text when it already had focus but this isn't essential.

How to install a specific version of a package with nuget

I am having a few problems with the latest version of AvalonDock (in particular my custom PRISM RegionAdapter implementation, blog post\moan to follow one day when I get a chance) so have had to roll back to the version I developed under which worked for me.

You can't do this via the "Manage nuget packages" dialog in Visual Studio as that only lets you install\uninstall\manage the latest version of packages, so you have to fire up the "Package Manager Console" (under View -> Other Windows, if you don't already have it open) and use the command line.

The command to list available versions is:

Get-Package -ListAvailable -Filter AvalonDock -AllVersions

And then you can use the following to install a specific version (make sure you have the project you want to install into selected in the "Default project" drop-down) :

Install-Package AvalonDock -Version 2.0.1320

And lo and behold, you have 2.0.1320 of AvalonDock installed and your RegionAdapter suddenly works again!