views:

42

answers:

3

Is there an easy way to transform or format a string as part of WPF data binding?

Suppose I want to create a WPF Hyperlink element based on a string tag.

<Hyperlink NavigateUri="{Binding Tag}">
    <Run Text="{Binding Tag}" />
</Hyperlink>

But I need to transform the Tag first for the NavigateUri property to make it a true hyperlink or PackUri.

For instance, if my tag were "folksonomy" I'd want to create a string like: http://www.example.com/tags/tagview?tag=folksonomy

What's the best way to achieve this? Is there a string manipulation function in XAML? Do I have to write a converter? Do a have to build a whole separate ViewModel class just to do a little string formatting?

UPDATE: There appears to be something strange going on with the Hyperlink element. I can get the StringFormat syntax suggested in the answers to work for an ordinary TextBlock, but not for a Hyperlink. I've tried both the NavigateUri and ToolTip properties, and neither seems to respect the StringFormat settings.

So apparently a custom converter or ViewModel property will be required.

+4  A: 

You can use the string formatting capabilities of bindings:

<Hyperlink NavigateUri="{Binding Tag, StringFormat=http://www.example.com/tags/tagview?tag={0}}"&gt;
    <Run Text="{Binding Tag}" />
</Hyperlink>

HTH,
Kent

Kent Boogaart
Hmmm. I can get this to work for the TextBlock element's Text property, but not for Hyperlink's NavigateUri or Tooltip properties.
dthrasher
Interesting. Probably because the target type is `Uri` rather than `String`. You might need to resort to your own converter, or a separate property on your view model.
Kent Boogaart
That makes sense for the NavigateUri method, but it's interesting that the Tooltip won't take the StringFormat either. It seems like StringFormat just wasn't implemented at all. Maybe because Hyperlink lives in the System.Windows.Documents namespace?
dthrasher
Anyway, it looks like I'll have to use a custom converter or ViewModel property to format the strings properly. Thanks for your help!
dthrasher
+3  A: 

Like Kent said you can use string formatting assuming you are on .NET 3.5 SP1 (string formatting was added as part of SP1). Good Samples here: http://blogs.msdn.com/b/llobo/archive/2008/05/19/wpf-3-5-sp1-feature-stringformat.aspx

If you aren't on .NET 3.5 SP1 or the string format approach becomes too messy you would want to us an IValueConverter http://msdn.microsoft.com/en-us/library/system.windows.data.ivalueconverter.aspx

Foovanadil
Are you sure this works for the Hyperlink element? I can get the StringFormat to work with TextBlock properties, but Hyperlink seems to ignore them.
dthrasher
A: 

For anyone else stumbling across this thread seeking a solution, I found Foovanadil's suggested IValueConverter worked well for me.

<TextBlock> 
    <Hyperlink Name="lnkGoogle" NavigateUri="{Binding Path=Alert.Query,Converter={View:UriConverter},ConverterParameter=google}" RequestNavigate="Hyperlink_RequestNavigate">
        Find news on Google
    </Hyperlink>
</TextBlock>

With the converter class in my codebehind:

public class UriConverter : MarkupExtension, IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            string address = string.Empty;
            switch ((string)parameter)
            {
                case "google":
                    address = "http://www.google.co.uk/news?q=" + value;
                    break;                    
            }

            Uri path = new Uri(@address);
            return path;
        }

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

        public override object ProvideValue(System.IServiceProvider serviceProvider)
        {
            return this;
        }
    }
Skrealin