我正在尝试将数据绑定和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>
答案 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
且具有Name
和Files
属性的类,您可以这样写:
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"/>