2012-02-22 18 views
50

我想将一个字符串值列表绑定到一个列表框,以便它们的值逐行列出。现在我用这个:我怎样才能将一个字符串列表绑定到WPF/WP7中的列表框?

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

但我不知道我应该投入的文字块,而不是Id,因为它们都是字符串值,而不是自定义类。

另外它抱怨没有找到人名,当我把它放在MainPage中时,作为MainPage.PersonNames。

我设置为数据上下文:

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

我做错了?

回答

111

请参阅类的名称。如果简单地把你的ItemsSource绑定这样的:

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

你的XAML应该是这样的:

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

更新:

这是使用DataContext时的解决方案。下面的代码是你将被传递到页面的DataContext和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(); 

你的XAML现在看起来是这样的:

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

这种方法的好处是,您可以在MyViewModel类中放置更多的属性或复杂对象,并将它们提取到XAML中。例如通过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; } 
} 

而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> 

希望这有助于!:)

+1

谢谢,我很困惑YourListBox。它是控制的名称吗?你是否必须在代码中使用xaml工作的第一行? – 2012-02-22 09:07:12

+1

这是一个错字,它确实是控件的名称。您还可以通过页面上的DataContext或通过资源来绑定项目。我给的绑定是为了演示目的。 :) – Abbas 2012-02-22 09:09:47

+0

谢谢,你能给我一个DataContext的例子吗?我很难理解它。 – 2012-02-22 09:13:43

8

如果项目源是枚举作为字符串项,使用以下命令:

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

可以在任何物体上使用此语法。通常,ToString()方法将被调用来获取值。这在很多情况下非常方便。但请注意,不会发生更改通知。

+0

谢谢,我会尝试这个但我仍然遇到绑定部分的问题,它在xaml中找不到PersonName。 – 2012-02-22 09:10:11

+0

+1用于编辑和提供-toString信息 – mindandmedia 2012-02-22 09:17:21

+0

@Joan Venge:绑定问题是另一个问题,在评论中没有很快解释。我假设您的UserControl或Window的DataContext未设置为PersonNames暴露实例。如果它是在Window或UserControl中声明的,你可以在绑定{Binding PersonNames,RelativeSource = {RelativeSource Mode = FindAncestor,AncestorType = Window}}中添加一个快速解决方案,你必须通过“UserControl “如果你的ListBox在一个UserControl中。查看一些关于DataContext和MVVM的文章,这将有助于你理解DataContext – HCL 2012-02-22 09:21:54

10

你应该向我们展示了PersonNames的代码,我不知道,我明白你的问题,但也许你要绑定这样的:

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

<TextBlock Text="{Binding"} /> 

这将绑定到列表中的当前元素。 (假设PersonNames是一个字符串列表)。否则,你会在列表中

+3

双向绑定需要'Path = .' – Dani 2013-11-04 10:52:57

1

你可以做到这一点,而不必显式定义TextBlock控件作为你的ListBox的一部分(除非你想要更好的格式)。诀窍得到结合触发使用的ObservableCollection<string>代替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()); 
} 
相关问题