I learnt how to make WPF editing usable

I already turned off the WPF designer in Visual Studio however setting the default editor for XAML files to the Source Text Editor by default makes a huge difference.

Source: http://weblogs.asp.net/fmarguerie/archive/2009/01/29/life-changer-xaml-tip-for-visual-studio.aspx

I learnt about a neat trick with BackgroundWorker

I need to run some code that talked to a server on a background worker however the result of the call would update a collection and a view on the UI, so would need to marshall back to the UI thread.

Based on the article at http://sachabarber.net/?p=411 I took this and tweaked it a little to be able to run part on the background and part on the UI thread in a single call.

        public static void InvokeIfRequired(this DispatcherObject control, Action methodcall)
{
if (control.Dispatcher.Thread != Thread.CurrentThread)
control.Dispatcher.Invoke(DispatcherPriority.Normal, methodcall);
else
methodcall();
}

public static void RunInBackground(Action backgroundAction, DispatcherObject control, Action uiAction)
{
BackgroundWorker bgWorker = new BackgroundWorker
{
WorkerReportsProgress = true, WorkerSupportsCancellation = false
};
bgWorker.DoWork += (s, e) =>
{
backgroundAction();
if (uiAction != null)
control.InvokeIfRequired(uiAction);
};
bgWorker.RunWorkerAsync();
}


Then the call can become:


        PageHelper.RunInBackground(
() =>
{
// Background thread code
}, this,
() =>
{
// UI thread code
});
}


which I think is quite neat.

I learnt about double clicking a ListViewItem

I had a problem where double clicking on the listview in WPF was always launching an action even if it was not on a selected item or even on the header.

Found this article which helped me out.

http://www.designerwpf.com/2008/07/15/clicking-or-doubleclicking-on-an-item-in-a-listview/

I tweaked it slightly to pass an Action to execute so I can use it anywhere.

I learnt how to align the widths of controls

This is more a reminder for me. Quite often we need to make a bunch of controls the same width. The following line will set the width of a contol to that of another one.

Width="{Binding ElementName=ControlName, Path=ActualWidth}"

I learnt how to hide disabled buttons in WPF

I had a requirement that disabled buttons shouldn’t just be greyed out but be hidden. The following style achieves this:

    <Style TargetType="{x:Type Button}">
<Style.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Visibility" Value="Hidden" />
</Trigger>
</Style.Triggers>
</Style>

I learnt how to hide disabled buttons in WPF

I had a requirement that disabled buttons shouldn’t just be greyed out but be hidden. The following style achieves this:

    <Style TargetType="{x:Type Button}">
<Style.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Visibility" Value="Hidden" />
</Trigger>
</Style.Triggers>
</Style>

I learnt about converters and itemtemplates in WPF

I had an issue with binding a combobox to a bunch of type names. I had a converter which strips out the rubbish and just leaves the type name on it’s own however I was doing this on the ItemsSource which meant that when the item was selected it returned just the display name.

After a little investigation I found the following solution:

<ComboBox x:Name="Collector" Grid.Column="1" SelectedItem="{Binding Collector}" 
ItemsSource="{Binding Source={StaticResource CollectorsAvailable}}"
SelectedValuePath="." VerticalAlignment="Center"
SelectionChanged="Collector_OnSelectionChanged">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=.,Converter={x:Static Core:TypeNameConverter.Instance}}" />
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>


There may still be some changes that I need to optimize this but this seems to work.

I learnt about WPF CommandTarget

I came across a very strange issue in WPF. I had a user control that can populate another area of a parent window. Adding buttons programmatically which used RoutedUICommands didn’t evaluate whether they should display or not.

It turns out it was down to the command target. I needed to set the command target on the button to the user control.

This article helped track it down …

http://blogs.msdn.com/ebooth/archive/2006/08/31/732609.aspx