views:

216

answers:

3

Given this object

class Contact 
{
     public IEnumerable<Person> People { get; }
     public string PhoneNumber { get; }
}

class Person
{
     public string MobileNumber { get; }
}

And the following layout

<Contact>
    <PhoneNumber/>
    <SinglePerson.MobileNumber/>
    <People>
       <MobileNumber />
    </People>
<Contact>

What I'd like to do is hide the People element when there is only one person, and show the SinglePerson.Mobile number element instead.

Hiding is fairly easy:

<Style.Triggers>
    <DataTrigger Binding="{Binding Path=People.Count}" Value="1">
        <Setter Property="Visibility" Value="Collapsed" />
    </DataTrigger>
</Style.Triggers>

Showing is slightly more tricky:

<Setter Property="Visibility" Value="Collapsed"/>   
<Style.Triggers>
    <DataTrigger Binding="{Binding Path=People.Count}" Value="1">
        <Setter Property="Visibility" Value="Visible" />
    </DataTrigger>
</Style.Triggers>

The thing that I can't work out how to do is to bind the <SinglePerson.MobileNumber> Text to the first person in the People list. I've tried variants of "{Binding People[0].MobilePhone}", but that doesn't work.

Is it even possible?

+1  A: 

There may be other ways, but I have solved this in the past by creating a value converter (a class named PersonIndexerConverter that implements IValueConverter). The conversion can take a parameter which is your index. Pass the index as a parementer in the XAML. The binding becomes a tad more complicated, but you get your indexing.

Brian Genisio
Cool, works ok for me, I've made a FirstPersonMobileConverter (I could have decided to pass in the Property name as parameter, that will be for the next version).
Benjol
A: 

It is actually far easier, if you only want to get the FIRST item in a collection. If you reference the desired property, wpf automatically picks the value for the first element in the collection:

<DataTrigger Binding="{Binding People/MobileNumber}" Value="">
    <Setter Property="Visibility" Value="Collapsed" />
</DataTrigger>

(from IanG)

Benjol
A: 

How can you bind indexed properties and the index is not a string but from another source in the viewmodel, say another property from the same datacontext?

Lawrence A. Contreras