我有一个应用程序,其中有一个ListBox的ListBox。 我想使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。这个ListBox的ItemsSource属性使用ItemsSource={Binding Path=Foos}
进行绑定,在这个ListBox的模板中有一个内部ListBox,它使用ItemsSource="{Binding Path=Bars}"
进行绑定。A、B和C是Foos的描述。它们包含的项目是Bar的名称。
|--------------------------|
| A |--------------------| |
| | Item 1 | |
| | Item 2 | |
| | Item 3 | |
| |--------------------| |
| |
| B |--------------------| |
| | Item X | |
| | Item Y | |
| | Item Z | |
| |--------------------| |
| |
| C |--------------------| |
| | Item l | |
| | Item m | |
| |--------------------| |
|--------------------------|
我需要让用户只能从任何一个“Bars”中选择单个项目。因此,如果用户从Foo A选择Item 1,然后从Foo B选择Item X,则应取消选择Item 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>