2015-09-23 4 views
0

У меня есть два списка, в которых оба объекта одинакового типа, и у меня есть оба свойства SelectedItem, связанное с тем же свойством в моей модели ViewModel. Я ожидал, что, когда я выберу какой-то элемент в списке A, выбор в списке B исчезнет. Но это не тот случай. Мне нужно уродливое обходное решение, чтобы заставить его работать, как я этого ожидаю. Любые подсказки, как заставить его работать без этого обходного пути?Несколько ListBoxes SelectedItem Связывание с тем же свойством

XAML

<Window x:Class="WpfApplication1.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     Title="MainWindow" Height="350" Width="525" DataContext="{Binding RelativeSource={RelativeSource Self}}"> 
    <Grid> 
     <Grid.ColumnDefinitions> 
      <ColumnDefinition Width="*"></ColumnDefinition> 
      <ColumnDefinition Width="*"></ColumnDefinition> 
     </Grid.ColumnDefinitions> 

     <Grid.RowDefinitions> 
      <RowDefinition Height="*"></RowDefinition> 
      <RowDefinition Height="Auto"></RowDefinition> 
     </Grid.RowDefinitions> 

     <ListBox ItemsSource="{Binding Items1}" SelectedItem="{Binding SelectedItem}" ></ListBox> 

     <ListBox Grid.Column="1" ItemsSource="{Binding Items2}" SelectedItem="{Binding SelectedItem}" ></ListBox> 

     <Button Grid.Row="1" Content="NULL" Grid.ColumnSpan="2" Click="ButtonBase_OnClick"></Button> 
    </Grid> 
</Window> 

C#

public partial class MainWindow : INotifyPropertyChanged 
{ 
    private Item _selectedItem; 
    public ObservableCollection<Item> Items1 { get; private set; } 
    public ObservableCollection<Item> Items2 { get; private set; } 
    public Item SelectedItem 
    { 
     get { return _selectedItem; } 
     set 
     { 
      // Uncomment this to make it work 
      //_selectedItem = null; 
      //OnPropertyChanged(); 
      _selectedItem = value; 
      OnPropertyChanged(); 
     } 
    } 

    public MainWindow() 
    { 
     Items1 = new ObservableCollection<Item>(); 
     Items2 = new ObservableCollection<Item>(); 
     Items1.Add(new Item("A1")); 
     Items1.Add(new Item("A2")); 
     Items2.Add(new Item("B1")); 
     Items2.Add(new Item("B2")); 
     InitializeComponent(); 
    } 

    private void ButtonBase_OnClick(object sender, RoutedEventArgs e) 
    { 
     SelectedItem = null; 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 

    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) 
    { 
     PropertyChangedEventHandler handler = PropertyChanged; 
     if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName)); 
    } 
} 

public class Item 
{ 
    public Item(string name) 
    { 
     Name = name; 
    } 

    string Name { get; set; } 
} 

ответ

0

Почему не связывая их (TwoWay связывание) с двумя различными свойствами (например, SelectedItem1 и SelectedItem2), тогда:

public Item SelectedItem1 
{ 
    get { return _selectedItem1; } 
    set 
    {    
     _selectedItem1 = value; 
     OnPropertyChanged(); 

     if(value!=null) //Here is the trick. 
      SelectedItem2=null; 

     OnPropertyChanged("SelectedItem"); 
    } 
} 

EDIT : Тогда для остальной части вашего кода приложения вы можете иметь свойство SelectedItem, как показано ниже. Также не забудьте добавить OnPropertyChanged("SelectedItem") в инкубаторе обоих SelectedItem1 и SelectedItem2

public Item SelectedItem 
{ 
    get{return SelectedItem1 != null ? SelectedItem1 : SelectedItem2} 
} 
+0

Поскольку для остальной части логики приложения это не имеет значения, код будет проще с только одним связанным свойством. – metacircle

+0

@metacircle Я обновляю свой ответ. –

+0

Спасибо. Тем не менее это свойство 3 свойства vs 1. Я также хочу знать, почему WPF ведет себя таким образом. – metacircle

0

Если это некрасиво обходной путь вы хотите, то нажмите на событие SelectionChanged:

<ListBox x:Name="ListBoxA" ItemsSource="{Binding Items1}" SelectedItem="{Binding SelectedItem}" SelectionChanged="ListBox_SelectionChanged"></ListBox> 
    <ListBox x:Name="ListBoxB" Grid.Column="1" ItemsSource="{Binding Items2}" SelectedItem="{Binding SelectedItem}" SelectionChanged="ListBox_SelectionChanged" ></ListBox> 

    private void ListBox_SelectionChanged(object sender, SelectionChangedEventArgs e) 
    { 
     if (sender == this.ListBoxA) 
      this.ListBoxB.UnselectAll(); 
     else 
      this.ListBoxA.UnselectAll(); 
    } 

еще лучше, использовать прилагаемую поведение в делайте то же самое.

Смежные вопросы