Reputation: 49
Hey I need to access items in my listbox I've made in WPF. What I have right now is the user can add a new class object to ObservableCollection which the ListBox.ItemsSource is bound to. This class has data in it where that data is used in things like a combobox, a text box and other simple things like that.
What i've made is really based off of one of the tut videos from windowsclient.net
//Here's What I have so far
<ListBox x:Name="MyList" Width = "300" Height = 300">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Vertical">
<TextBlock x:Name="ItemName"
Text={Binding Path=PersonName}/>
<ComboBox x:Name="NumberOfRes"
SelectedIndex="0"
SelectionChanged="NumberOfRes_SelectionChanged"
ItemsSource={Binding Path=ListOfNums}/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
//ListOfNums
private ObservableCollection<int> _listofNums =
new ObservableCollection<int>()
{ 1,2,3,4,5,6,7,8 };
public ObservableCollection<int> ListOfNums
{
get{return _listOfNums;}
}
//class Resident
public class Resident
{
public string personName {get;set;}
}
So I have that working. I have a button that adds a new class object and each object has it's data set properly through data binding. So I can see my default personName when a new object is added and I have a comboBox filled with integers from ListOfNums.
My propblem though is that I don't know how to access what these 'sub objects' (forgive me I'm new to WPF and don't know the proper term) are selecting. I want to know what my comboBox's SelectedItem is when a selectionChange event is raised or what my new personName is set to when the user types something into the textBox. So a user selects one of these ItemTemplate objects in the listBox and this item has a combobox and other UI controls that the user clicks. When the user clicks on one of these UI controls some data changes.
I've tried ((Resident)MyList.SelectedItem).personName
and a couple other methods just to see if I can access the data and manipulate it. Now the funny thing is that my comboBox in the ItemTemplate has a selection changed event that is called when the selection is changed, but I can't access the data!
Thanks in advance!
Upvotes: 2
Views: 250
Reputation: 9687
Below sample uses a ViewModel (VM). If you add new residents to the Residents collection they will show up in the listbox. Just a tip, if you end up naming your controls a lot you are not doing data binding correctly.
XAML:
<ListBox ItemsSource="{Binding Path=Residents}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding Path=PersonName}" />
<ComboBox
ItemsSource="{Binding Path=DataContext.ListOfNums, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListBox}}}"
SelectionChanged="NumberOfRes_SelectionChanged" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Code behind:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
DataContext = new VM();
}
private void NumberOfRes_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
{
ComboBox comboBox = sender as ComboBox;
Resident resident = comboBox.DataContext as Resident;
int number = (int)comboBox.SelectedItem;
}
}
public class VM
{
public VM()
{
Residents = new ObservableCollection<Resident>() { new Resident() { PersonName = "AAA" }, new Resident() { PersonName = "BBB" } };
}
public ObservableCollection<Resident> Residents { get; private set; }
public IEnumerable<int> ListOfNums
{
get { return new List<int>() { 1, 2, 3, 4, 5, 6, 7, 8 }; }
}
}
public class Resident
{
public string PersonName { get; set; }
}
Upvotes: 0
Reputation: 24723
There are multiple ways to accomlish what you are after. The easiest approach would be to put a SelectedItem
property on your ViewModel.
Your VieWModel would then look like this...
public class MyViewModel : INotifyPropertyChanged
{
ObservableCollection<Resident> Residents { get; }
private Resident _selectedItem;
public Resident SelectedItem
{
get { return _selectedItem; }
set
{
_selectedItem = value;
PropertyChangedEventHandler handler = PropertyChanged;
if(handler != null)
handler(this, new PropertyChangedEventArgs("SelectedItem");
}
}
}
In your View set the DataContext
to an instance of this ViewModel
, where your ListBox.ItemsSource
is bound to Residents
and your ListBox.SelectedItem
is bound to SelectedItem
.
<ListBox ItemsSource="{Binding Path=Residents}"
SelectedItem="{Binding Path=Selectedtem, Mode=TwoWay}" />
If you want to perform manipulation when the selection changes, note the setter of your SelectedItem
property, which will contain the newly selected item.
EDIT:
Just noticed that your Resident
model does not implement INotifyPropertyChanged
, which it will need to do to propagate changes down stream. You can then get the point at which the data will change within the setter of a given property as mentioned with the SelectedItem
property.
Upvotes: 1