1

I have a WPF ListBox that I am binding to a collection of Contact objects, similar to

public class Contact
{
    int ContactId { get; set; }
    int ContactType { get; set; }   // 1 = phone number, 2 = email address
    string Value { get; set; }
}

My current ListBox binding is

<ListBox Name="ContactsListBox"
    ItemsSource="{Binding Contacts, Mode=Oneway}"
    SelectedValuePath="ContactId"
    DisplayMemberPath="Value"
</ListBox>

I would like to display the phone numbers as text and emails as clickable "mailto:" type hyperlinks, but I'm unclear on how to get the binding to work the way I need.

JSR
  • 6,106
  • 2
  • 20
  • 24

3 Answers3

2

What you need is conditional binding for your ListBox.

First you define two DateTemplates each for one contact type:

<ListBox.Resources>
    <DataTemplate x:Key="PhoneTemplate">
        <TextBlock Text="{Binding Value}" />
    </DataTemplate>
    <DataTemplate x:Key="MailTemplate">
        <TextBlock>
            <Hyperlink NavigateUri="{Binding Value}">
                <TextBlock Text="{Binding Value}" />
            </Hyperlink>
        </TextBlock>
    </DataTemplate>
</ListBox.Resources>

And then you define ItemTemplate with DataTrigger bounded to ContactType property:

<ListBox.ItemTemplate>
    <DataTemplate>
        <ContentControl Content="{Binding}">
            <ContentControl.Style>
                <Style TargetType="ContentControl">
                    <Style.Triggers>
                        <DataTrigger Binding="{Binding ContactType}" Value="1">
                            <Setter Property="ContentTemplate" Value="{StaticResource PhoneTemplate}" />
                        </DataTrigger>
                        <DataTrigger Binding="{Binding ContactType}" Value="2">
                            <Setter Property="ContentTemplate" Value="{StaticResource MailTemplate}" />
                        </DataTrigger>
                    </Style.Triggers>
                </Style>
            </ContentControl.Style>
        </ContentControl>
    </DataTemplate>
</ListBox.ItemTemplate>

Remember to remove DisplayMemberPath from your ListBox because you cannot use it if you set ItemTemplate.

Alex
  • 1,433
  • 9
  • 18
1

You need to write your ItemTemplate for ListBox.

<Window.Resources>
<DataTemplate  x:Key="MyTemplate">

     <StackPanel Orientation="Horizontal">
            <TextBlock Text="{Binding Value }"></TextBlock>
            <TextBlock>           
                <Hyperlink NavigateUri="{Binding YourString}" RequestNavigate="OnNavigate">Click here</Hyperlink>
            </TextBlock>
     </StackPanel>

<ListBox Name="ContactsListBox"
         ItemsSource="{Binding Contacts}"
         ItemTemplate="{StaticResource MyTemplate}"
</ListBox>
leapold
  • 133
  • 1
  • 10
  • How to navigate:http://stackoverflow.com/questions/23020377/link-to-open-new-email-message-in-default-e-mail-handler-in-wpf-application – leapold Dec 14 '16 at 16:06
1

Define an ItemTemplate with a DataTrigger that binds to the ContactType property:

<ListBox Name="ContactsListBox" ItemsSource="{Binding Contacts, Mode=Oneway}" SelectedValuePath="ContactId">
<ListBox.ItemTemplate>
    <DataTemplate>
        <Grid>
            <TextBlock x:Name="phone" Text="{Binding Value}" />
            <TextBlock x:Name="email" Visibility="Collapsed">
                        <Hyperlink NavigateUri="{Binding Value}">
                            <Run Text="{Binding Value}" />
                        </Hyperlink>
            </TextBlock>
        </Grid>
        <DataTemplate.Triggers>
            <DataTrigger Binding="{Binding ContactType}" Value="2">
                <Setter TargetName="email" Property="Visibility" Value="Visible" />
            </DataTrigger>
        </DataTemplate.Triggers>
    </DataTemplate>
</ListBox.ItemTemplate>
</ListBox>

If you want the link to be opened in a web browser you should handle the RequestNavigate event of the Hyperlink as suggested here: Example using Hyperlink in WPF.

Also make sure that you define your properties as public:

public class Contact
{
    public int ContactId { get; set; }
    public int ContactType { get; set; }  // 1 = phone number, 2 = email address
    public string Value { get; set; }
}
Community
  • 1
  • 1
mm8
  • 163,881
  • 10
  • 57
  • 88