KateMak
KateMak

Reputation: 1649

Get content from the labels in a NESTED listbox bound to an observable collection?

I have a listbox inside a listbox, and both are binded to an observable collection. I have overloaded the SelectionChanged event for both. For the nested listbox, I have a few labels in its data template. I want to be able to get the content of those labels. It's just difficult because I cannot refer to any of them in the code behind, even with the x:name property defined. Anyone have any ideas?

<ListBox Grid.Row="5" x:Name="lb1" ItemsSource="{Binding}" DataContext="{Binding}" ScrollViewer.HorizontalScrollBarVisibility="Disabled" SelectionChanged="lb1_SelectionChanged">

        <ListBox.ItemsPanel>
            <ItemsPanelTemplate>
                 <WrapPanel/>
            </ItemsPanelTemplate>
        </ListBox.ItemsPanel>

        <ListBox.ItemTemplate>
            <DataTemplate>
                 <Label x:Name="txtEnclosure" Content="{Binding Path=EnclosureID}"/>
                 <......other labels bound to other properties...>
                 <ListBox x:Name="lbserver" ItemsSource="{Binding Path=Slist}">
                        <ListBox.ItemsPanel>
                            <ItemsPanelTemplate>
                                <WrapPanel/>
                            </ItemsPanelTemplate>
                        </ListBox.ItemsPanel>

                        <ListBox.ItemTemplate>
                            <DataTemplate>
                                 <Label x:Name="txtSlot" Content="{Binding Path=Slot}" />
                                 <Label x:Name="txtServer" Content="{Binding Path=HostnameID}" />
                            </DataTemplate>
                        </ListBox.ItemTemplate>
                    </ListBox>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>

The parent listbox binds to an observable collection called Elist (an observable collection of Enclosures, a class I defined)

this.DataContext = Settings.Elist;

And the child listbox binds to an observable collection inside of the Enclosure class.

public class Enclosure
{
    public ObservableCollection<Server> Slist { get; set; }
    ...contains other variables as well....
}

In the application, it lists enclosures, and each enclosure has a list of servers. The user can select an Enclosure, and I can get the Enclosure from Elist based on the SelectedIndex (I use ElementAt(SelectedIndex)). Things just get much more tricky when I try to get one of the Servers from the nested listbox. I want to be able to select one of the servers in the list and get the Server from the observable collection Slist. The problem is that when the user selects the server directly, I don't know which Enclosure from Elist the server is from, aaand I can't get the SelectedIndex because I can't refer to anything from the nested listbox in the code behind >.< A very frustrating problem indeed...does anyone have any ideas?

If I can get at the items in the nested listbox in code that would be helpful as well.

Upvotes: 0

Views: 529

Answers (1)

Wallstreet Programmer
Wallstreet Programmer

Reputation: 9677

Below sample shows how to get selected parent and child when user selects a child, see OnSelectedModelChanged method.

XAML:

<Window x:Class="WpfApplication1.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">

    <StackPanel>
        <ListBox ItemsSource="{Binding .}">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <StackPanel>
                        <TextBlock Text="{Binding Path=Name}" FontWeight="Bold"/>
                        <ListBox ItemsSource="{Binding Path=Models}" SelectionChanged="OnSelectedModelChanged">
                            <ListBox.ItemTemplate>
                                <DataTemplate>
                                    <TextBlock Text="{Binding Path=Name}" />
                                </DataTemplate>
                            </ListBox.ItemTemplate>
                        </ListBox>
                    </StackPanel>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
    </StackPanel>
</Window>

Code behind:

using System.Windows;
using System.Windows.Controls;
using System.ComponentModel;
using System.Collections.Generic;
using System.Windows.Controls.Primitives;

namespace WpfApplication1
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            List<Make> cars = new List<Make>();
            cars.Add(new Make("Ford") { Models = new List<Model>() { new Model("F150"), new Model("Taurus"), new Model("Explorer") } });
            cars.Add(new Make("Honda") { Models = new List<Model>() { new Model("Accord"), new Model("Pilot"), new Model("Element") } });
            DataContext = cars; 
        }

        private void OnSelectedModelChanged(object sender, SelectionChangedEventArgs e)
        {
            Selector modelSelector = sender as Selector;
            Model selectedModel = modelSelector.SelectedItem as Model;
            Make selectedMake = modelSelector.DataContext as Make;
        }
    }

    public class Make
    {
        public Make(string name)
        {
            Name = name;
        }

        public string Name { get; private set; }
        public IEnumerable<Model> Models { get; set; }
    }

    public class Model
    {
        public Model(string name)
        {
            Name = name;
        }
        public string Name { get; private set; }
    }
}

Upvotes: 1

Related Questions