Consider a book shelf, it has shelves and each shelf has a number of books on it. In turn each book has a few properties such as Title and Author and perhaps ISBN.
namespace mySillyExample
{
public class BookShelf
{
public Shelf[] myShelves{get; set;}
}
public class Shelf
{
public Book[] booksOnThisShelf{get; set;}
}
public class Book
{
public string Title {get; set;};
public string Author{get; set;};
public string ISBN {get; set;};
}
}
Now I would like to make a list box in XAML using WPF to list all of the Titles. Right now my solution looks something like this:
<ListBox Height="154" HorizontalAlignment="Left"
ItemsSource="{Binding Path=BookShelf.myShelves}"
Margin="171,475,0,0" VerticalAlignment="Top" Width="333" >
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=booksOnThisShelf.[0].Title}" />
</DataTemplate>
<ListBox.ItemTemplate>
</ListBox>
And I do get a list box with that data. There are three problems that I see with the above solution.
-
The DataTemplate tag seems to be designed to change what kind of control the list box will consist of and NOT to provide additional binding scope as it was used
-
I seem to be referencing the 0th (zeroth/first) element in the array of books for each shelf (“booksOnThisShelf.[0]”) this seems most evil, at it does not seem to be what is happening if I do infact get a list of all of my books (which I do)
-
This seems to work for 2 layers of lists, but what about 3 or 4 or 42?
Please keep in mind that I can’t change the classes directly (they are generated in XSD) though the potential for a helper class is not necessarily out of the question.
The more I thought about this problem, the more I am convinced it must arise for more people, especially when working with data from Complex XML structures (webpages? give me all of the urls for img tags etc)
So in summary here is what I am looking for:
- What is the best way to handle the above issue?
- Most Elegant/Reusable Model that is preferably maintained in XAML
- How can this be abstracted to n-layered lists (object containing a list of objects containing a list of objects . . . ad infinitum/nauseam)?
- Using my example, what if you had a Room class with multiple BookShelves, and a Library class with multiple Rooms and a City class with multiple Libraries.
As always thanks in advance!
NOTE: I used the term “list” and the code shows an array, my apologies for confusion
I’d suggest at looking at the MVVM pattern. You don’t bind to your Models, but you bind to your ViewModels. You’re ViewModel is what will help you get your giant list. You’d probably want to do something like so:
Then you just need to set MyViewModel as your DataContext and bind to Titles. Of course, you don’t have to pass in an IDataProvider, you can pass in the list of BookShelves but it’s always best to have a DataProvider get your Model information for you.