Saturday, March 27, 2010

Microsoft Offers Career Help

Microsoft has launched a new website to help advance your career called Thrive. The site includes resources to enhance your skills, connect to your community, improve interviewing skills and search for jobs. One of the most valuable resources for the developer is a podcast series on improving your soft skills. Even if you have great communication, work and interviewing skills this is a great reminder of those skills and each webcast includes valuable web resources/references at the end of the webcast.

Enjoy!
Todd Stephan

Wednesday, March 24, 2010

How to Create ToolTips on the cheap – integrating ToolTip and IDataErrorInfo.

In a previous post I discussed how to create a more pleasing to the eye error template.

But it has been noted by the WPF guru Karl Shifflett and others that this simple mechanism for integrating tooltips and IDataErrorInfo has some draw backs. The most annoying of which is that you can’t assign a tool tip to any control that might show a data validation error! If you do assign a tooltip, the data validation error will not appear.

There is a simple work around. Use the tag of the control to hold the tooltip and use it for the content of the tooltip when there is no data validation error. Here are a few screen shots of the tooltips and data validation in action.





Here is the relevant code snippet:

<Style.Triggers>
<Trigger Property="Validation.HasError" Value="True">
<!--
In the following xaml, Path=AdornedElement.(Validation.Errors)[0].ErrorContent} throws an exception if no error condition is present,
although the exception does not cause a crash. It shows up in the debug window which is annoying.
This work around implemented here - http://joshsmithonwpf.wordpress.com/2008/10/08/binding-to-validationerrors0-without-creating-debug-spew/
-->
<Setter Property="ToolTip" Value="{Binding RelativeSource={RelativeSource Self}, Path=(Validation.Errors).CurrentItem.ErrorContent}" />
</Trigger>
<Trigger Property="Validation.HasError" Value="False">
<Setter Property="ToolTip" Value="{Binding RelativeSource={RelativeSource Self}, Path=Tag}" />
</Trigger>
</Style.Triggers>

The tooltip is set using the tag of the control as content in the second trigger when Validation.HasErrors is false. Note that I implemented Josh Smith's fix for debug spew.

The full code is available here. 

Enjoy!
Todd Stephan

Apple News Aggregator - aggregates Top 200 Apple news sites

Check out the site - very well formatted for quick scanning / searching.

http://apple.alltop.com/

Enjoy!
Todd Stephan

Saturday, March 13, 2010

Yet Another WPF Boolean Converter – or not! The only WPF Boolean Converter you need.

I sat down to write yet another WPF BooleanToXXX converter and decided this was not acceptable. Bool converters are used to select between two choices based on the true/false value of the bool in question. To me this cried out for a generic class to handle all of these cases so I created a class called BooleanToValueConverter as shown below.


public class BooleanToValueConverter : IValueConverter
{
// parameter specifies what to return based on the boolean
// parameter is of the format value1;value2 where value1 is returned if the bool is false and value2 is returned if the bool is true
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
System.Diagnostics.Debug.Assert(value is bool);
System.Diagnostics.Debug.Assert(parameter as string != null);
if (value == null || !(value is bool) || parameter as string == null)
return null;

string[] valueList = (parameter as string).Split(new char[] { ';' });
System.Diagnostics.Debug.Assert(valueList.Length == 2);
if (valueList.Length != 2)
return null;

if ((bool)value == true)
return valueList[1];

return valueList[0];
}

public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}

The following XAML snippets show how the converter is used. The trick to making this converter generic is the ConverterParameter which takes a string of two options separated by a semicolon. The converter parameter is of the format value1;value2 where value1 is returned if the bool is false and value2 is returned if the bool is true.


<Window.Resources>
<local:BooleanToValueConverter x:Key="booleanToValueConverter"/>
</Window.Resources>

<Button Content="_Delete" Visibility="{Binding Path=IsDeleteAllowed, Converter={StaticResource booleanToValueConverter}, ConverterParameter=Collapsed;Visible}" />

Now in the example screen shot below we see that the Delete button is not visible since the IsDeleteAllowed property is returning false and thus the button is collapsed.



I have used this in many locations to choose between two values including visibility as shown above, two margins, grid row/column widths, and more. The grid row use case is interesting because you can make a grid row disappear by binding to the row height and using a BooleanToValueConverter to set the width to 0 when you want the row to disappear.

The full code is available here. 

Enjoy!
Todd Stephan