web-dev-qa-db-fra.com

Comment puis-je lier une liste de chaînes à un ListBox dans WPF / WP7?

J'essaie de lier une liste de valeurs de chaîne à une liste afin que leurs valeurs soient répertoriées ligne par ligne. En ce moment j'utilise ceci:

<ListBox Margin="20" ItemsSource="{Binding Path=PersonNames}">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <StackPanel Orientation="Horizontal">
                <TextBlock Text="{Binding Path=Id}"></TextBlock>
            </StackPanel>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

Mais je ne sais pas ce que je suis censé mettre dans le bloc de texte au lieu de Id, car ce sont toutes des valeurs de chaîne, pas des classes personnalisées.

En outre, il se plaint de ne pas avoir à trouver les noms de personne lorsque je les ai dans MainPage, sous le nom MainPage.PersonNames.

Je règle le contexte de données sur:

DataContext="{Binding RelativeSource={RelativeSource Self}}"

Je le fais mal?

61
Joan Venge

Si simplement, que ItemsSource est lié comme ceci:

YourListBox.ItemsSource = new List<String> { "One", "Two", "Three" };

Votre XAML devrait ressembler à:

<ListBox Margin="20" Name="YourListBox">
    <ListBox.ItemTemplate> 
        <DataTemplate> 
            <StackPanel Orientation="Horizontal"> 
                <TextBlock Text="{Binding}" /> 
            </StackPanel> 
        </DataTemplate> 
    </ListBox.ItemTemplate> 
</ListBox> 

Mise à jour:

C'est une solution lors de l'utilisation d'un DataContext. Le code suivant est le modèle de vue que vous allez transmettre au DataContext de la page et le paramètre du DataContext:

public class MyViewModel
{
    public List<String> Items
    {
        get { return new List<String> { "One", "Two", "Three" }; }
    }
}

//This can be done in the Loaded event of the page:
DataContext = new MyViewModel();

Votre XAML ressemble maintenant à ceci:

<ListBox Margin="20" ItemsSource="{Binding Items}">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <StackPanel Orientation="Horizontal">
                <TextBlock Text="{Binding}" />
            </StackPanel>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

L'avantage de cette approche est que vous pouvez mettre beaucoup plus de propriétés ou d'objets complexes dans la classe MyViewModel et les extraire dans le XAML. Par exemple, pour passer un objet List of Person:

public class ViewModel
{
    public List<Person> Items
    {
        get
        {
            return new List<Person>
            {
                new Person { Name = "P1", Age = 1 },
                new Person { Name = "P2", Age = 2 }
            };
        }
    }
}

public class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
}

Et le XAML:

<ListBox Margin="20" ItemsSource="{Binding Items}">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <StackPanel Orientation="Horizontal">
                <TextBlock Text="{Binding Path=Name}" />
                <TextBlock Text="{Binding Path=Age}" />
            </StackPanel>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

J'espère que cela t'aides! :)

133
Abbas

Vous devriez nous montrer le code pour PersonNames, et je ne suis pas sûr, je comprends votre question, mais vous voulez peut-être le lier comme ceci:

<TextBlock Text="{Binding Path=.}"/>

ou

<TextBlock Text="{Binding"} />

Cela liera l’élément actuel de la liste. (En supposant que PersonNames est une liste de chaînes). Sinon, vous verrez le nom de la classe dans la liste

16
mindandmedia

Si la source d'éléments est énumérable en tant qu'entrées de chaîne, utilisez ce qui suit:

<TextBlock Text="{Binding}"></TextBlock> 

Vous pouvez utiliser cette syntaxe sur n'importe quel objet. Généralement, la méthode ToString () sera ensuite appelée pour obtenir la valeur. Ceci est dans de nombreux cas très pratique. Mais attention, aucune notification de changement ne se produira.

9
HCL

Vous pouvez le faire sans avoir à définir explicitement le contrôle TextBlock dans votre ListBox (sauf si vous souhaitez une meilleure mise en forme). L'astuce pour obtenir la liaison à déclencher utilise un ObservableCollection<string> au lieu de List<string>

Window1.xaml

<ListView Width="250" Height="50" ItemsSource="{Binding MyListViewBinding}"/>

Window1.xaml.cs

public Window1()
{
   InitializeComponent();
   DataContext = this;

   // Need to initialize this, otherwise you get a null exception
   MyListViewBinding = new ObservableCollection<string>();
}

public ObservableCollection<string> MyListViewBinding { get; set; }

// Add an item to the list        
private void Button_Click_Add(object sender, RoutedEventArgs e)
{
   // Custom control for entering a single string
   SingleEntryDialog _Dlg = new SingleEntryDialog();

   // OutputBox is a string property of the custom control
   if ((bool)_Dlg.ShowDialog())
      MyListViewBinding.Add(_Dlg.OutputBox.Trim());
}
2
Kevin K