Question

I have a ListBox showing a list of people's names, emails, departments, etc. There is a DataTemplate that has a few TextBlocks to display each property. One of these TextBlocks is wrapping a Hyperlink to show email addresses like so:

<TextBlock>
   <Hyperlink NavigateUri="{Binding Email}">
      <TextBlock Text="{Binding Email}" />
   </Hyperlink>   
</TextBlock>

This works fine, but if the person doesn't have an email address, the TextBlock is not collapsed automatically. So I wrote a value converter and used in the style like so (simplified):

string s = (String) value;
if (s == ""){
   return Visibility.Collapsed;
}
return Visibility.Visible;

And this is the Style using the ValueConverter:

<Style x:Key="ResultItemTextBoxStyle">
    <Setter Property="TextBlock.Visibility" Value="{Binding Path=Text, RelativeSource={RelativeSource Self}, 
                                                    Converter={StaticResource StringToVisibilityConverter}}"/>
</Style>

And I added the style calling the converter to the TextBlock:

<TextBlock Style="{StaticResource ResultItemTextBoxStyle}">
   <Hyperlink NavigateUri="{Binding Email}">
      <TextBlock Text="{Binding Email}" />
   </Hyperlink>   
</TextBlock>

After this change the email address is never shown - In the value converter, the text of the TextBlock is always empty and it returns Visibility.Collapsed. It is like it's evaluating the text of the TextBlock before the Hyperlink get loaded or something...

Please help me figure this one out.

Thanks!

Was it helpful?

Solution

The converter that you wrote is comparing the Text of the TextBlock to empty, not the text of the inner Hyperlink. I think you really want to set the RelativeSource to the child Hyperlink, but I don't think that is possible.

Are you sure that it is the TextBlock's size that doesn't get collapsed? If you put the style on the Hyperlink instead (or even its inner TextBlock), maybe that would still work?

Edit: Hyperlink doesn't have a Visibility property, so moving the style to it won't help, unfortunately. The only other option that I can think of is to create a custom control that derives from TextBlock, and it contains a Hyperlink and TextBlock. If you add an Email DependencyProperty to it, then you can use that to determine if the control should be visible or not, and for the value of the Hyperlink and its inner TextBlock.

It seems like there should be a better way to handle this, but I can't think of anything currently.

OTHER TIPS

I would do something like this:

<TextBlock>
   <TextBlock.Style>
      <Style>
         <Setter Property="Visibility" Value="Visible"/>
         <Style.Triggers>
            <DataTrigger Binding="{Binding Email}" Value="">
               <Setter Property="Visibility" Value="Collapsed"/>
            </DataTrigger>
         </Style.Triggers>
      </Style>
   </TextBlock.Style>
   <Hyperlink NavigateUri="{Binding Email}">
      <TextBlock Text="{Binding Email}" />
   </Hyperlink>   
</TextBlock>

I think writing a value converter is overkill (no offense intended).

I know this is not exactly your question, but why do you use textblocks at all?

Simply using

    <Hyperlink NavigateUri="{Binding Email}" Content="{Binding Email}" 
Visibility="{Binding Email, Converter={StaticResource StringToVisibilityConverter}}" />

should do what you want it do do, unless I am mistaken.

update: OK, I am mistaken, WPF Hyperlink is not Silverlight's HyperlinkButton and does not have a Content property. Shame on me.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top