【问题标题】:How can I data bind a list of strings to a ListBox in WPF/WP7?如何将字符串列表数据绑定到 WPF/WP7 中的 ListBox?
【发布时间】:2012-03-12 14:25:12
【问题描述】:

我正在尝试将字符串值列表绑定到列表框,以便逐行列出它们的值。现在我用这个:

<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 中找到 PersonNames 时,它就像 MainPage.PersonNames 一样。

我将数据上下文设置为:

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

我做错了吗?

【问题讨论】:

    标签: c# .net wpf windows-phone-7 data-binding


    【解决方案1】:

    如果项目源可枚举为字符串条目,请使用以下内容:

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

    您可以在任何对象上使用此语法。通常,然后调用 ToString() 方法来获取值。这在许多情况下非常方便。但请注意,不会发生更改通知。

    【讨论】:

    • 谢谢,我会试试这个,但我仍然遇到绑定部分的问题,它抱怨在 xaml 中找不到 PersonNames。
    • @Joan Venge:绑定问题是另一个问题,没有在评论中快速解释。我假设您的 UserControl 或 Window 的 DataContext 未设置为 PersonNames-exposing 实例。如果它在 Window 或 UserControl 中声明,您可以将以下快速解决方案添加到绑定 {Binding PersonNames,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=Window}} 中,您必须通过“UserControl”替换“Window” " 如果您的 ListBox 在用户控件中。查看一些关于 DataContext 和 MVVM 的帖子,这将帮助您了解 DataContext
    【解决方案2】:

    你应该向我们展示 PersonNames 的代码,我不确定,我理解你的问题,但也许你想像这样绑定它:

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

    <TextBlock Text="{Binding"} />
    

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

    【讨论】:

    • 双向绑定需要Path=.
    【解决方案3】:

    如果简单地说你的 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>
    

    希望这会有所帮助! :)

    【讨论】:

    • 谢谢,我对 YourListBox 感到困惑。它是控件的名称吗?您必须在代码的第一行才能使 xaml 工作吗?
    • 打错了,确实是控件的名称。您还可以通过页面上的 DataContext 或通过资源绑定项目。我给的绑定是为了演示目的。 :)
    • 谢谢,能给我一个DataContext的例子吗?我很难理解它。
    • 有用的答案:) 但据我所知,如果您只使用字符串而不是复杂类,则根本不需要使用ListBox.ItemTemplate。默认行为只是打印它。
    • @pt12lol 你说得对,但考虑到扩展(比如使用复杂对象),我使用了模板。
    【解决方案4】:

    您可以执行此操作,而无需将 TextBlock 控件显式定义为 ListBox 的一部分(除非您想要更好的格式)。触发绑定的技巧是使用ObservableCollection&lt;string&gt; 而不是List&lt;string&gt;

    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());
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-08-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-06-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多