How do you bind a ListBox's SelectedItem to an

2019-08-30 12:49发布

问题:

I have a ListBox in my UI that is bound to List<Notification> Notifications { get; set; }:

<ListBox ItemsSource="{Binding Notifications}"
         DisplayMemberPath="ServiceAddress"
         Name="NotificationsList"/>

A Notification has a filter title associated with it:

public class Notification
{
    public string FilterTitle { get; set; }
    public string ServiceAddress { get; set; }
}

My UI has another ListBox that is bound to List<LogFilter> Filters { get; set; }:

<ListBox ItemsSource="{Binding Filters}"
         DisplayMemberPath="Title"
         Name="FiltersList"/>

And as you can guess, a LogFilter contains a Title:

public class LogFilter
{
    public string Title { get; set; }
}

When I select a Notification in my NotificationsList, I would like it to select the corresponding LogFilter in my FiltersList based on the mapping of the Notification's FilterTitle and the LogFilter's Title. How could you do that through a binding?

回答1:

First of all you need to set SelectedValuePath for first listBox to FilterTitle:

<ListBox ItemsSource="{Binding Notifications}"
         DisplayMemberPath="ServiceAddress" 
         Name="NotificationsList"
         SelectedValuePath="FilterTitle"/>

Bind with SelectedValue of first listbox using ElementName. Also you need to set SelectedValuePath to Title here as well:

<ListBox ItemsSource="{Binding Filters}"
         DisplayMemberPath="Title"
         Name="FiltersList"
         SelectedValuePath="Title"
         SelectedValue="{Binding SelectedValue, ElementName=NotificationsList, 
                                 Mode=OneWay}"/>


回答2:

As mentioned in other answers to your previous questions, you should really consider introducing the concept of a "Selected Item" at the ViewModel level:

public class MyViewModel
{
     public List<Notification> Notifications {get;set;}

     //Here!
     public Notification SelectedNotification {get;set;} //INotifyPropertyChanged, etc here
}

Then bind the ListBox.SelectedItem to that:

<ListBox ItemsSource="{Binding Notifications}"
         SelectedItem="{Binding SelectedNotification}"
         DisplayMemberPath="ServiceAddress"/>

Same with the other ListBox:

<ListBox ItemsSource="{Binding Filters}"
         SelectedItem="{Binding SelectedFilter}"
         DisplayMemberPath="Title"/>

Then simply find the appropiate filter At the ViewModel level when changing the SelectedNotification:

 private Notification _selectedNotification;
 public Notification SelectedNotification
 {
     get { return _selectedNotification; }
     set
     {
         _selectedNotification = value;
         NotifyPropertyChange("SelectedNotification");

         //here...
         if (value != null)     
             SelectedFilter = Filters.FirstOrDefault(x => x.Title == value.FilterTitle);
     }
 }