Jasper
Jasper

Reputation: 127

WPF fill in textbox based on selected item combobox

I've made a WPF project about movies and actors (new to programming).

For now I can create a new actor (linked to a movie) manually by entering his name, country, bday etc. Since I'm adding more and more data, I would like the possibility to select an existing actor from a combobox, and then his name, country, bday etc would automatically fill in in the textboxes I've provided where you'd normally add new information manually.

My Actor has an ActorID, FirstName, LastName, Country and Birthdate. If I want to create a new actor, I just fill these things in and click save, and it creates a new actor. The save thing is not really important right now.

In Actor.cs I declared these:

public class Actor
{
    public int ActorID { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    //Etc.
}

And then these are called act.FirstName etc

My combobox is called: comboBoxExistingActors and it's Itemsource is:

        comboBoxExistingActors.ItemsSource = ActorRepository.ActorList();

This ActorList is defined in my ActorRepository:

    public static List<Actor> ActorList()
    {
        string command = "SELECT DISTINCT FirstName, LastName FROM tblActors ORDER BY tblActors.LastName";
        OleDbDataAdapter adapter = new OleDbDataAdapter(command, connectionString);
        DataTable datatable = new DataTable();
        adapter.Fill(datatable);

        List<Actor> lijst = new List<Actor>();

        for (int i = 0; i < datatable.Rows.Count; i++)
        {
            Actor act = new Actor();

            act.FirstName = datatable.Rows[i].Field<string>("FirstName");
            act.LastName = datatable.Rows[i].Field<string>("LastName");

            lijst.Add(act);
        }
        return lijst;
    }

Now I'd like that my textboxes would fill in the actor's details when I select an actor from this combobox:

    private void comboBoxExistingActors_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        textBoxFirstName.Text = ???
        //textBoxLastname etc.
    }

I'm not sure if it's this simple, but I need a way to get my act.Firstname from the selected actor into the textBoxFirstName. I hope I have provided enough information to understand my problem, if not please say so and I'll provide you with it.

Thanks in advance!

Upvotes: 1

Views: 4214

Answers (4)

ZadiusC
ZadiusC

Reputation: 31

This is what worked for me if you have a complex item with multiple properties. Add these two lines (changing 'Content' for 'Text' as applicable) to your label/textbox:

DataContext="{Binding ElementName=ComboboxName, Path=SelectedItem}"
Content="{Binding ElementName=ComboboxName, Path=SelectedItem.PropertyName}"

Replacing ComboboxName with your combobox name & PropertyName with the desired display value id (ex. SelectedItem.DeviceID)

Upvotes: 0

mm8
mm8

Reputation: 169200

The recommended way to implement this would be to use the MVVM design pattern: https://msdn.microsoft.com/en-us/library/hh848246.aspx

Create a view model class:

public class ActorViewModel : INotifyPropertyChanged
{
    public ActorViewModel()
    {
        Actors = ActorRepository.ActorList();
    }

    public List<Actor> Actors { get; private set; }

    private Actor _selectedActor;
    public Actor SelectedActor
    {
        get { return _selectedActor; }
        set { _selectedActor = value; NotifyPropertyChanged(); }
    }


    public event PropertyChangedEventHandler PropertyChanged;
    private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

...and set the DataContext of the window to an instance of this one:

public MainWindow()
{
    InitializeComponent();
    DataContext = new ActorViewModel();
}

You can then bind to any property of it:

<ComboBox ItemsSource="{Binding Actors}" DisplayMemberPath="FirstName"
                  SelectedItem="{Binding SelectedActor}" />

<TextBox Text="{Binding SelectedActor.FirstName}" />
<TextBox Text="{Binding SelectedActor.LastName}" />

The SelectedActor property of the view model will be the set to the Actor object that you select in the ComboBox and the databound TextBoxes will be automaically refreshed provided that the view model class implements the INotifyPropertyChanged interface and raise the PropertyChanged event in the setter of the SelectedActor source property.

You could also bind the TextBoxes directly to the ComboBox:

<ComboBox x:Name="cmb" ItemsSource="{Binding Actors}" DisplayMemberPath="FirstName"/>

<TextBox Text="{Binding SelectedItem.FirstName, ElementName=cmb}" />

Upvotes: 0

mohsen mousavi
mohsen mousavi

Reputation: 372

use following codes:

private ListCollectionView view; 
ICollection<Actor> actors= GetActors();
this.DataContext = actors;
view = (ListCollectionView)CollectionViewSource.GetDefaultView(this.DataContext);

in xaml:

<ComboBox Name="lstActors" DisplayMemberPath="FirstName"
Text="{Binding Path=FirstName}"
SelectionChanged="lstActors_SelectionChanged"></ComboBox>

<TextBox Text="{Binding Path=FistName}"/>
<TextBox Text="{Binding Path=LastName}"/>
<TextBox Text="{Binding Path=ActorID}"/>

and in SelectionChanged event:

private void lstActors_SelectionChanged(object sender, RoutedEventArgs e)
{
view.MoveCurrentTo(lstActors.SelectedItem);
}

A simpler solution is to set the ItemsControl.IsSynchronizedWithCurrentItem to true. That way, the currently selected item is automatically synchronized to match the current position of the view with no code required.

Upvotes: 0

sujith karivelil
sujith karivelil

Reputation: 29026

I think you are looking for something like this:

private void comboBoxExistingActors_SelectionChanged(object sender, SelectionChangedEventArgs e)
 {
    textBoxFirstName.Text = ((Actor)comboBoxExistingActors.SelectedItem).FirstName;
 }

Upvotes: 2

Related Questions