简体   繁体   中英

WPF Combobox binding selected item

I have the following problem. I have this Models:

public class A
{
    public A(string id)
    {
        ID = id;
        
    }

    public string ID { get; }
    public string Name { get ; set; }
    public B objectB { get; set; }

}

public class B
{
    public B(string id)
    {
        ID = id;
    }

    public string ID { get; }
    public string Name { get; set; }
}

public class ViewModel
{
    public ObservableCollection<A> ListOne = new ObservableCollection<A>();
    public ObservableCollection<B> ListTwo = new ObservableCollection<B>();

    public ViewModel()
    {
        B objectB = new B("1");
        objectB.Name = "ObjectB";

        B listElement2 = new B("2");
        listElement2.Name = "ListElement2";

        ListTwo.Add(objectB);
        ListTwo.Add(listElement2);

        A objectA = new A("A1");
        objectA.Name = "objectA1";
        objectA.objectB = objectB;

        ListOne.Add(objectA);
    }
}

<ListBox ItemsSource="{Binding ListOne}" Name="MyListBox">
  <ListBox.ItemTemplate>
    <DataTemplate>
      <Grid>
        <ComboBox ItemsSource="{Binding ElementName=MyListBox, Path=DataContext.ListTwo}" 
                  DisplayMemberPath="Name" 
                  SelectedItem="{Binding objectB}"/>
      </Grid>
    </DataTemplate>
  </ListBox.ItemTemplate>
</ListBox>

Class A contains a object ob Class B . My ViewModel contains two lists. One list (ListOne) of class A objects and second list (ListTwo) contains objects of class B.

Now I want to bind listTwo to combobox which is embedded into a listbox . The listbox displays all objects in the listOne of the viewmodels. If I change the selection of combobox I want to update the property objectB of the selected item of listbox. I also want that the combobox select the value of objectB during initialization.

Please note: I simplified the model and the viewmodel to focus on the problem. NotifyProperties and so on works. I am interested in the binding of the combobox.

I have no idea to do this. I hope you can help me.

You can do the following:

<ComboBox
    ItemsSource="{Binding ListB}"
    SelectedItem="{Binding SelectedB}"
    DisplayMemberPath="Name" Width="100"
/>

Also, you may add the following code in your ViewModel:

private ObservableCollection<B> listB = new ObservableCollection<B>();
public ObservableCollection<B> ListB
{
    get { return this.listB; }
    set { this.listB = value; NotifyPropertyChanged("ListB"); }
}

private B selectedB;
public B SelectedB
{
    get { return this.selectedB; }
    set { this.selectedB = value; NotifyPropertyChanged("SelectedB"); }
}
ViewModel()
{
    //Fill your ListB with all possible values
    this.SelectedB=ListB.FirstOrDefault(x=>x.ID==A.ObjectB.ID)
}

Then your classes may be INotifyPropertyChanged:

public class A : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    public void NotifyPropertyChanged(string propName)
    {
        if (this.PropertyChanged != null)
        this.PropertyChanged(this, new PropertyChangedEventArgs(propName));
    }
    public long ID=-1;
    private string name = "";
    public string Name
    {
        get { return this.name; }
        set
        {
            this.name = value;
            this.NotifyPropertyChanged("Name");
        }
    }
    private B objectB;
    public B ObjectB
    {
        get{return this.objectB;}
        set
        {
            this.objectB=value;
            this.NotifyPropertyChanged("B");
        }
    }

}

Iam almost sure you could also replace SelectedB by A.ObjectB for binding, but would need to make some tests to check it. Advantage (or inconvenient it depends), is that if you Bind on A.ObjectB, the changes will be effective as soon as you change the selected item in ComboBox. Making so you can change your ComboBox value without modifying directly your A object, then on closing Window, you can ask to save or not, and if yes, just do A.ObjectB=SelectedB.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM