Reputation: 3649
I've spent a good couple of days failing at solving this issue myself, which leads me to believe I don't understand something very basic about xaml and the code-behind. I am attempting to display data from an ObservableCollection in a ListView using WPF and c#.
When I start debugging, the window displays the listview, with the grid and the headers. There are clickable rows equivalent to the number of items that should be there, but the items appear blank or empty. I was working off an incomplete tutorial to try and learn my way through this, the code is as follows:
MainWindow.xaml.cs:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
}
NameList.cs:
class NameList : ObservableCollection<PersonName>
{
public NameList()
: base()
{
Add(new PersonName("Willa", "Cather")); //enumerated? (firstName, lastName)
Add(new PersonName("Isak", "Dinesen"));
Add(new PersonName("Victor", "Hugo"));
Add(new PersonName("Jules", "Verne"));
}
}
PersonName.cs:
class PersonName
{
private string firstname;
private string lastname;
public PersonName(string first, string last)
{
this.firstname = first;
this.lastname = last;
}
public string FirstName { get; set; }
public string LastName { get; set; }
}
I would include the xaml, but I haven't figured out how to do that in a question here, so I'll just spell it out as best I can:
ListView ItemsSource=""{Binding Source={StaticResource NameListData}}"
GridViewColumn DisplayMemberBinding="{Binding Path=FirstName}"
GridViewColumn DisplayMemberBinding="{Binding Path=LastName}"
I've only listed the actual bindings, I didn't think the layout info was too important, but let me know if I'm wrong in that assumption.
Upvotes: 0
Views: 4837
Reputation: 3649
So I just figured it out, a flash of understanding sparked by @LPL.
When I declared my property, I didn't set the get and set values to the private strings, so when the binding called for them, it knew that four items existed, but they were empty items. The now functional code looks like this:
public string FirstName
{
get {return firstname; }
set{ firstname=value; }
}
With an equivalent property for LastName. Joy to simple problems becoming massive headaches.
Upvotes: 1
Reputation: 2233
Your MainWindow will need a property with your data so that you can bind to
public partial class MainWindow : Window
{
private NameList _nameList;
public NameList NameList
{
get { return _nameList; }
set
{
if (_nameList != value)
{
_nameList = value;
}
}
}
public MainWindow ()
{
InitializeComponent();
NameList = new NameList();
}
}
Your PersonName class needs to assign the properties (not the members) so that you can bind to them:
public class PersonName
{
public PersonName(string first, string last)
{
FirstName = first;
LastName = last;
}
public string FirstName { get; set; }
public string LastName { get; set; }
}
And in your XAML you can bind like this:
<ListView ItemsSource="{Binding NameList}">
<ListView.ItemTemplate>
<DataTemplate>
<TextBlock>
<Run Text="{Binding LastName}" /><Run Text=", " /><Run Text="{Binding FirstName}" />
</TextBlock>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
So your result will look like this:
Upvotes: 2
Reputation: 17063
You assign a value to private field
this.firstname
but bind to property
public string FirstName { get; set; }
This should work
public PersonName(string first, string last)
{
this.Firstname = first;
this.Lastname = last;
}
Upvotes: 5