2010-06-16 8 views
2

Je suis encore aux premiers stades de l'apprentissage de WPF et j'ai décidé d'essayer d'écrire une application Contact Browser assez simple pour me familiariser avec les fondamentaux. Pour ajouter à la complexité, j'utilise des objets d'une autre application.Comment lier une collection au sein d'une collection dans WPF

Jusqu'à présent, j'ai réussi à lier un contrôle ListBox à une collection et afficher les noms de contacts. Au milieu de l'écran, j'ai un StackPanel avec un CustomControl qui affiche plus de détails sur le Contact. Tout cela fonctionne étonnamment bien, sauf que le modèle d'objet pour le contact cache le champ PhoneNUmber dans une collection de champs.

Comment lier/appeler un élément spécifique dans une collection d'une collection d'objets liés?

Voici une partie de mon XAML, d'une part la principale ContactWindow:

<DockPanel Width="auto" Height="auto" Margin="8 8 8 8"> 
    <Border Height="56" HorizontalAlignment="Stretch" VerticalAlignment="Top" BorderThickness="1" CornerRadius="8" DockPanel.Dock="Top" Background="Beige"> 
     <TextBox Height="32" Margin="23,5,135,5" Text="Search for contact here" FontStyle="Italic" Foreground="#FFAD9595" FontSize="14" BorderBrush="LightGray"/> 
    </Border> 
    <ListBox x:Name="contactList" DockPanel.Dock="Left" Width="192" Height="auto" Margin="5 4 0 8" ItemsSource="{Binding}" DisplayMemberPath="FullName" /> 
    <Grid DataContext="{Binding ElementName=contactList, Path=SelectedItem}"> 
     <Grid.RowDefinitions> 
      <RowDefinition Height="1*" /> 
      <RowDefinition Height="0.125*" /> 
     </Grid.RowDefinitions> 
     <local:BasicContactCard Margin="8 8 8 8" /> 
     <Button Grid.Row="1" x:Name="exit" Content="Exit" HorizontalAlignment="Right" Width="50" Height="25" Click="exit_Click" /> 
    </Grid> 
</DockPanel> 

Et voici le XAML pour la BasicContactCard:

<DockPanel Width="auto " Height="auto" Margin="8,8,8,8" > 
    <Grid Width="auto" Height="auto" DockPanel.Dock="Top"> 
     <Grid.RowDefinitions> 
      <RowDefinition Height="1*" /> 
      <RowDefinition Height="1*" /> 
      <RowDefinition Height="1*" /> 
      <RowDefinition Height="1*" /> 
     </Grid.RowDefinitions> 
     <TextBlock x:Name="companyField" Grid.Row="0" Width="auto" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="8,8,8,8" Text="{Binding Company}" FontWeight="Bold" FontSize="15" /> 
     <TextBlock x:Name="contactField" Grid.Row="1" Width="auto" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="8,8,8,8" Text="{Binding FullName}" FontWeight="Bold" /> 
     <TextBlock x:Name="phoneField" Grid.Row="2" Width="auto" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="8,8,8,8" Text="{Binding Phone}"/> 
     <TextBlock x:Name="emailField" Grid.Row="3" Width="auto" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="8,8,8,8" Text="{Binding ValidEmailAddress}"/> 
    </Grid> 
</DockPanel> 

Tous les éléments du BasicContactCard à l'exception du téléphone sont Exposé comme propriétés get-able à partir de l'objet de collection Contact auquel la Listbox est liée sauf pour le téléphone qui réside dans une collection d'objets Field pouvant être appelée en C# comme

Contact c = contacList[i]; 
string val = c.ContactFields.Item("Phone",FieldNameType.Alias); 

J'espère que tout cela a du sens! Toute aide ou pointeur vers des ressources serait vraiment apprécié!

Viv

+0

Quel type de collection est ce 'ContactFields' et ce que cela fait' article ("Téléphone", FieldNameType.Alias) ' – Amsakanna

+0

@Veer , La collection ContactFields expose un IEnumerator. La méthode Item renvoie la valeur (en tant que chaîne) de l'élément. c'est-à-dire pour Contact c dans la collection de Champs obtient la valeur détenue dans le champ Téléphone. – VivyG

Répondre

1

Utilisez un convertisseur de valeur pour obtenir le numéro de téléphone.

XAML:

<UserControl.Resources>  
    <TestApp:PhoneNumberConverter x:Key="PhoneNumberConverter" /> 
</UserControl.Resources> 

<TextBlock Text="{Binding ., Converter=StaticResource PhoneNumberConverter}}"/> 

code derrière:

public class PhoneNumberConverter : IValueConverter 
{ 
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
    { 
     Contact c = value as Contact; 
     string phoneNr = c.ContactFields.Item("Phone", FieldNameType.Alias); 
     return phoneNr; 
    } 

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

Je me sens très ignorant maintenant, où pourrais-je placer la balise ? Est-ce que je le place dans le xaml de la ContactWindow ou de la BasicContactCard? La BasicContactCard est un UserControl. Je suis désolé si c'est une question vraiment stupide! – VivyG

+0

Le convertisseur est requis par la carte BasicContactCard pour convertir un objet Contact en chaîne de numéro de téléphone. Ainsi, le code derrière et la déclaration en tant que ressource vont dans la BasicContactCard. J'ai édité le code pour le montrer. –

+0

Hmmm ok je ne sais pas trop ce que je fais mal ici mais ça doit être quelque chose de basique! Dans la balise Je suppose que TestApp est le nom du projet/sln qui dans mon cas est Test.WPF.BasicContcatSearch1, mais je reçois une erreur de compilation disant que le Type .. .was pas trouvé – VivyG

Questions connexes