Взаимоисключающие списки WPF

У меня есть приложение, в котором есть ListBox из ListBoxes. Я хотел бы сделать поля InnerList взаимоисключающими. Моя ViewModel имеет коллекцию Foos, у которой есть описание, свойство IsSelected и коллекции Bars, у которых есть имя и свойство IsSelected.

public class MyViewModel : INotifyPropertyChanged
{
     public ObservableCollection<Foo> Foos { /* code removed for brevity */ }
}

public class Foo : INotifyPropertyChanged
{
     public string Description { /* code removed for brevity */ }
     public ObservableCollection<Bar> Bars { /* code removed for brevity */ }
     public bool IsSelected { /* code removed for brevity */ }
}

public class Bar : INotifyPropertyChanged
{
     public string Name { /* code removed for brevity */ }
     public bool IsSelected { /* code removed for brevity */ }
}

Ниже приведена часть моего окна MainWindow, для которого установлено значение DataContext MyViewModel. Свойство ItemsSource этого ListBox привязано с помощью ItemsSource = {Binding Path = Foos} , а в шаблоне для этого ListBox есть внутренний ListBox, который привязан с помощью ItemsSource = "{Binding Path = Bars}" . A, B и C - описания Фуса. Содержащиеся в них предметы являются именами бара.

|--------------------------|
| A |--------------------| |
|   | Item 1             | |
|   | Item 2             | |
|   | Item 3             | |
|   |--------------------| |
|                          |
| B |--------------------| |
|   | Item X             | |
|   | Item Y             | |
|   | Item Z             | |
|   |--------------------| |
|                          |
| C |--------------------| |
|   | Item l             | |
|   | Item m             | |
|   |--------------------| |
|--------------------------|

Мне нужно сделать так, чтобы пользователь мог выбрать только один элемент из любой панели. Итак, если пользователь выбирает элемент 1 из Foo A, а затем выбирает элемент X из Foo B, то элемент 1 должен быть отменен.

Мне также нужно привязать выбранный элемент к элементу управления TextBox в другом месте окна, но я полагаю, что это нужно делать один раз.

Сделать это в коде и событиях изменения выбора нельзя. Я бы предпочел использовать только XAML.

Заранее спасибо.

ОБНОВЛЕНИЕ
Следуя совету Moonshield, я придумал это, но это все еще не полностью работает.

public class MyViewModel
{
     private Bar _selectedBar;

     public ObservableCollection<Foo> Foos { /* code removed for brevity */ }
     public Bar SelectedBar 
     { 
          get { return _selectedBar; }
          set 
          {
              _selectedBar = null;
              NotifyPropertyChanged("SelectedBar");

              _selectedBar = value;
              NotifyPropertyChanged("SelectedBar");
          }
     }    
}
<ListBox x:Name="lbFoos" ItemsSource="{Binding Path=Foos}" SelectedItem="{Binding Path=SelectedBar}">
    <ListBox.ItemContainerStyle>
        <Style TargetType="{x:Type ListBoxItem}">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type ListBoxItem}">
                        <StackPanel>
                            <TextBlock Text="Foo: " />
                            <TextBlock Text="{Binding Path=Description}" />
                            <ListBox ItemsSource="{Binding Path=Bars}" SelectedItem="{Binding Path=SelectedItem RelativeSource={RelativeSource FindAncestor,AncestorType={x:Type ListBox}}}">
                                <ListBox.ItemContainerStyle>
                                    <Style TargetType="ListBoxItem">
                                        <Setter Property="Template">
                                            <Setter.Value>
                                                <ControlTemplate TargetType="{x:Type ListBoxItem}">
                                                    <TextBlock Text="{Binding Path=Name}" />
                                                </ControlTemplate>
                                            </Setter.Value>
                                        </Setter>
                                        <Setter Property="IsSelected" Value="{Binding Path=IsSelected, Mode=OneWayToSource}" />
                                    </Style>
                                </ListBox.ItemContainerStyle>
                            </ListBox>
                        </StackPanel>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </ListBox.ItemContainerStyle>
</ListBox>
5
задан Adam 27 November 2010 в 21:35
поделиться