Kevin
Kevin

Reputation: 205

WPF Data Binding and Templates

I am working on a project and I want to have a list box with a custom data template populate with user data. My question is, when I click on an item in the list box, how can I tell what item I selected? Basically, if I select "kevin", I want to display his data. If I select Dave, I want to display his data. I do not know how to get the data our after it is bound...

EDIT: I found a really great tutorial that covers this. A very hidden gem.

http://msdn.microsoft.com/en-us/library/aa480224.aspx

Upvotes: 0

Views: 664

Answers (4)

Kishore Kumar
Kishore Kumar

Reputation: 21863

Bind SelectedItem of the ComboBox to any property.

<Window x:Class="ComboBoxSelectedItemBinding.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="500">
<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition></ColumnDefinition>
        <ColumnDefinition></ColumnDefinition>
    </Grid.ColumnDefinitions>
    <ListBox   x:Name="st"
              ItemsSource="{Binding Path=Customers,Mode=TwoWay}" IsSynchronizedWithCurrentItem="True" 
              SelectedItem="{Binding Path=SelectedCustomer,Mode=TwoWay}"
               Margin="0,38,0,80">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <TextBlock Text="{Binding Path=Name}"></TextBlock>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>

    <TextBlock Text="{Binding Path=SelectedCustomer.Name}" Grid.Column="1" VerticalAlignment="Center" Margin="5"></TextBlock>
</Grid>

    public partial class Window1 : Window, INotifyPropertyChanged
{
    private ObservableCollection<Customer> customers;
    public ObservableCollection<Customer> Customers
    {
        get
        {
            return customers; 
        }
        set
        {
            customers = value;
            NotifyPropertyChanged("Customers");
        }
    }

    private Customer selectedCustomer;
    public Customer SelectedCustomer
    {
        get
        {
            return selectedCustomer;
        }
        set
        {
            selectedCustomer = value;
            NotifyPropertyChanged("SelectedCustomer");
        }
    }


    public Window1()
    {
        Customers = new ObservableCollection<Customer>();
        Customers.Add(new Customer() { ID = 1, Name = "Ravi", Salary = 1000 });
        Customers.Add(new Customer() { ID = 99, Name = "Alex", Salary = 3000 });
        Customers.Add(new Customer() { ID = 123, Name = "Steve", Salary = 100 });
        Customers.Add(new Customer() { ID = 31, Name = "Alice", Salary = null });
        InitializeComponent();

        DataContext = this;
    }

    #region INotifyPropertyChanged Members

    public event PropertyChangedEventHandler PropertyChanged;

    private void NotifyPropertyChanged(String info)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(info));
        }
    }

    #endregion
}

public class Customer:INotifyPropertyChanged
{
    private int id;
    public int ID
    {
        get
        {
            return id;
        }
        set
        {
            id = value;
            NotifyPropertyChanged("ID");
        }
    }

    private string name;
    public string Name
    {
        get
        {
            return name;
        }
        set
        {
            name = value;
            NotifyPropertyChanged("Name");
        }
    }

    private decimal? salary;
    public decimal? Salary
    {
        get
        {
            return salary;
        }
        set
        {
            salary = value;
            NotifyPropertyChanged("Salary");
        }
    }

    #region INotifyPropertyChanged Members

    public event PropertyChangedEventHandler PropertyChanged;

    private void NotifyPropertyChanged(String info)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(info));
        }
    }

    #endregion
}

Upvotes: 1

NathanAW
NathanAW

Reputation: 3367

It sounds like you will only have one item selected at a time. If so, then I prefer to bind the ListBox.SelectedItem to a property on my ViewModel. If we assume that you bound the listbox to a collection of Person classes, then the property on the ViewModel would be of type Person. The listbox will set this property to the selected instance of Person.

Then, just bind the other portion of the UI that show's Kevin's data to the property on the ViewModel.

As long as you have INotifyPropertyChanged implemented on the properties, your UI should update automatically as you change the selected item in the listbox.

Upvotes: 0

Patrick Desjardins
Patrick Desjardins

Reputation: 140753

Depending if you let the user select one or many item in your ListBox you can just loop all Item and check if it selected. Here is a little example C# example (could be done in VB.NET):

for (int i = 0; i < MyListBox.Items.Count; i++)
{
      if(MyListBox.Items[i].Selected)
          //Do what you want with the item with : MyListBox.Items[i].Value
}

Upvotes: 0

Paul Wheeler
Paul Wheeler

Reputation: 20140

The SelectedIndex property of the ListBox will correspond to the index of the selected item in the data source. So assuming you have bound to an IList you should be able to just use myDataSource[myListBox.SelectedIndex]. I'm assuming you aren't trying to support multiselect, in which case you can use the same concept, but the implementation is more complicated.

Upvotes: 1

Related Questions