WPF: use a ListBox in a template that will template another ListBox
I have a ListBox whose ItemSource is ObjectDataProvider, which is an ObservableCollection instance. ObservableCollection is a collection of ObservableCollections. ItemTemplate ListBox is a DataTemplate that creates a ListBox for each item in the list. To illustrate this better, I am trying to recreate a card game in WPF. Basically, you can create books from the hands of cards. Once you have a valid book, you can select the book to go into the ObservableCollection of Books. The problem I am facing is that every ListBox is a ListBox that has an ItemSource that is a Book, that is, an ObservableCollection of Cards. I don't think I have a problem with the source or template of the outer ListBox, but I am having a hard time figuring outhow am i going to set the source of the ListBox items to the map collection for each book. Basically my question may be confusing and complex, but essentially I'm trying to figure out how to use a ListBox in a template that will become the template for another ListBox. If anyone has any idea on how to approach this, I would be very grateful for that.
source to share
With a map as below:
public class Card
{
private string _name;
public Card(string name)
{
_name = name;
}
public string Name
{
get { return _name; }
set { _name = value; }
}
}
and follow these steps:
public class Book
{
private readonly ObservableCollection<Card> _cards;
public Book(ObservableCollection<Card> cards)
{
_cards = cards;
}
public ObservableCollection<Card> Cards
{
get { return _cards; }
}
}
Then create your ListBox in the window:
<ListBox
ItemsSource="{Binding ElementName=Window, Path=Books}"
ItemTemplate="{StaticResource MainListTemplate}" />
and in resources for the put window:
<Window.Resources>
<ResourceDictionary>
<DataTemplate
x:Key="InsideListTemplate">
<TextBlock
Text="{Binding Name}" />
</DataTemplate>
<DataTemplate
x:Key="MainListTemplate">
<ListBox
ItemsSource="{Binding Cards}"
ItemTemplate="{StaticResource InsideListTemplate}" />
</DataTemplate>
</ResourceDictionary>
</Window.Resources>
The ListBox uses a MainListTemplate which contains the ListBox. The ItemsSource for this ListBox is your list of cards, and the ItemTemplate is the InsideListTemplate. I have it like a simple TextBlock, but you can do whatever you need.
source to share
Don't put the ListBox inside a ListBox, it will create a very confusing interface because you will have multiple "levels" of selected items.
You can put an ItemsControl inside a ListBox if you want a single ListBox with a collection inside each item, or a ListBox inside an ItemsControl if you need multiple lists.
source to share
Thanks for answers. While I agree with both answers and always appreciate being notified of bad coding practice, the first answer did the trick. I have a problem with the ItemsSource ListBox in my DataTemplate. Somewhere along the way of learning WPF, I started connecting to ObjectDataProvider (s) as an ItemsSource. Since the ObjectDataProvider was just a collection instance, and when I update it, the card source for all of my "Books" will be the same. Changing my ItemsSource binding directly to the "Maps" observable collection did the trick.
While this can be confusing about the UI, I'm not sure if I'm even going to allow selection of items in any of the lists. My intentions were simply for the visual presentation of the player books. I may need the outer list items to be selected in order to move the cards out of the book and back to the main hand, but I'm not sure yet.
Thanks again for your help.
Thanks, Brandon
source to share