WPF ListBox绑定每行产生一个字符

时间:2014-01-23 17:10:50

标签: c# wpf xaml

我正在尝试将数据绑定和wpf写入我的(显然很厚)头部。我有一个非常简单的程序,我有一个包含单个属性的对象的ObservableCollection - 一个字符串。当我运行它时,它将列表框显示为每行一个字符,并且仅显示第一个项目。

这一定很简单,但我很难过。如果我删除'binding.Path = ...',那么它将在每一行显示“expOne.FNode”(三次)。

谢谢!

以下代码: MainWindow.xaml.cs:

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace expOne
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
    ObservableCollection<FNode> MyFileList = new ObservableCollection<FNode>();
    public MainWindow()
    {
        MyFileList.Add ( new FNode ( "alpha" ) );
        MyFileList.Add ( new FNode ( "bravo" ) );
        MyFileList.Add ( new FNode ( "charlie" ) );
        InitializeComponent();
        Binding binding = new Binding();
        binding.Source = MyFileList;
        binding.Path = new PropertyPath ( "Name" );
        mylistbox.SetBinding ( ListBox.ItemsSourceProperty, binding );
    }
}
}

FNode.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace expOne
{
public class FNode
{
    private string m_name;

    public string Name
    {
        get { return ( m_name ); }
        set { m_name = value; }
    }

    public FNode ( string n )
    {
        m_name = n;
    }

    public FNode()
    {
        m_name = "Bob";
    }
}
}

MainWindow.xaml:

<Window x:Class="expOne.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <ListBox Name="mylistbox" HorizontalAlignment="Stretch" FontSize="15" >
            <!--<ListBoxItem Content="First or Last" />-->
        </ListBox> 
    </Grid>
</Window>

2 个答案:

答案 0 :(得分:4)

那是因为你将'Name'属性绑定到Listbox的ItemsSource,实质上是告诉列表框绑定到字符串中的字符。列表框绑定到Source和Path属性的组合。

要将列表框绑定到列表,只需设置源。要显示名称,请将ListBox的DisplayMemberPath属性设置为“Name”

实际上,以声明方式绑定要容易得多。您可以将列表设置为列表框的DataContext,例如。

ObservableCollection<FNode> MyFileList = new ObservableCollection<FNode>();
public MainWindow()
{
    MyFileList.Add ( new FNode ( "alpha" ) );
    MyFileList.Add ( new FNode ( "bravo" ) );
    MyFileList.Add ( new FNode ( "charlie" ) );
    InitializeComponent();
    mylistbox.DataContext=MyFileList;
}

然后在XAML中设置绑定:

<ListBox Name="mylistbox" ItemsSource="{Binding}" DisplayMemberPath="Name" />

数据绑定允许您将数据与窗口完全分开。实际上,MVVM样式规定您的演示数据(ViewModel)应该是与窗口(您的View)不同的类。这样,您可以将不同的数据类绑定到同一视图,或将不同的视图绑定到同一对象。

假设您创建了一个名为MyProjectViewModel且具有NameFiles属性的类,您可以这样写:

public MyProjectViewModel TheProject {get;set;}
public MainWindow()
{
    TheProject=new MyProject();

    InitializeComponent();
    this.DataContext=TheProject;
}

然后将您需要的任何元素绑定到此ViewModel的属性,例如:

<TextBox Name="projectName" Text="{Binding Name}" />
<ListBox Name="projectFiles" ItemsSource="{Binding Files}" 
                             DisplayMemberPath="Name" />

答案 1 :(得分:1)

无需在绑定时设置路径,只需为绑定设置Source。删除它:

binding.Path = new PropertyPath ( "Name" );

OR

只需省略绑定并直接在listBox上设置ItemsSource:

MyFileList.Add(new FNode("alpha"));
MyFileList.Add(new FNode("bravo"));
MyFileList.Add(new FNode("charlie"));
InitializeComponent();
mylistbox.ItemsSource = MyFileList;

并将ListBox上的DisplayMemberPath设置为Name,否则会在您的班级FNode上调用ToString()并打印您的班级的完全限定名称,这就是您看到expOne.FNode的原因打印三次。

<ListBox Name="mylistbox" HorizontalAlignment="Stretch"
         FontSize="15" DisplayMemberPath="Name"/>