两个ListBox之间的WPF单选

时间:2013-01-11 11:11:39

标签: c# wpf visual-studio-2010 mvvm listbox

我遇到了以下问题:我有两个ListBox,有两个不同的ItemSource,但它们对binding都有相同的SelectedItem,因为我试图在这两个列表之间进行单一选择。

这是一张更能说明问题的图片:

First list in red. Second list in black.

我想做什么?每当我从第一个列表中选择一个项目(红色)时,它应取消选择第二个列表中的SelectedItem(黑色),反之亦然。这就是为什么我对它们使用相同的binding。 我真的不知道这是否是更好的方法,但它应该是那样的。

你能帮帮我吗?

2 个答案:

答案 0 :(得分:13)

尝试使用SelectedValue,这将使您看到的行为变得轻松

 <ListBox SelectedValue="{Binding MySelectedItem}" />

似乎SelectedItem未取消选择是否在列表中找不到所选项目,但SelectedValue似乎确实取消选择它,不确定原因

您可以在此示例应用中看到差异:

XAML:

<Window x:Class="WpfApplication11.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="184" Width="208" x:Name="UI">
    <StackPanel DataContext="{Binding ElementName=UI}">
        <TextBlock Text="SelectedValue" />
        <StackPanel Orientation="Horizontal" Height="60" >
            <ListBox ItemsSource="{Binding MyItemSource1}" SelectedValue="{Binding MySelectedValue}" Width="100" />
            <ListBox ItemsSource="{Binding MyItemSource2}" SelectedValue="{Binding MySelectedValue}" Width="100" />
        </StackPanel>
        <TextBlock Text="SelectedItem" />
        <StackPanel Orientation="Horizontal" Height="60"  >
            <ListBox ItemsSource="{Binding MyItemSource1}" SelectedItem="{Binding MySelectedItem}" Width="100" />
            <ListBox ItemsSource="{Binding MyItemSource2}" SelectedItem="{Binding MySelectedItem}" Width="100" />
        </StackPanel>
    </StackPanel>
</Window>

代码:

public partial class MainWindow : Window , INotifyPropertyChanged
{
    private CustomObject _mySelectedItem;
    private CustomObject _mySelectedValue;
    private ObservableCollection<CustomObject> _items = new ObservableCollection<CustomObject>();
    private ObservableCollection<CustomObject> _items2 = new ObservableCollection<CustomObject>();

    public MainWindow()
    {
        InitializeComponent();
        MyItemSource1.Add(new CustomObject { Name = "Stack" });
        MyItemSource1.Add(new CustomObject { Name = "Overflow" });
        MyItemSource2.Add(new CustomObject { Name = "Stack" });
        MyItemSource2.Add(new CustomObject { Name = "Overflow" });
    }

    public ObservableCollection<CustomObject> MyItemSource1
    {
        get { return _items; }
        set { _items = value; }
    }

    public ObservableCollection<CustomObject> MyItemSource2
    {
        get { return _items2; }
        set { _items2 = value; }
    }

    public CustomObject MySelectedItem
    {
        get { return _mySelectedItem; }
        set { _mySelectedItem = value; NotifyPropertyChanged("MySelectedItem"); }
    }

    public CustomObject MySelectedValue
    {
        get { return _mySelectedValue; }
        set { _mySelectedValue = value; NotifyPropertyChanged("MySelectedValue"); }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    private void NotifyPropertyChanged(string property)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(property));
        }
    }
}

public class CustomObject
{
    public string Name { get; set; }
    public override string ToString()
    {
        return Name;
    }
}

enter image description here

答案 1 :(得分:4)

我必须要做的是首先将null传递给属性并通知更改,然后我将实际值传递给属性并通知更改为视图。 像那样:

protected Bar selectedItem;
public Bar SelectedItem{
    get
    {
        return selectedItem;
    }
    set
    {
        selectedItem = null;
        NotifyPropertyChanged("SelectedItem");

        selectedItem = value;
        NotifyPropertyChanged("SelectedItem");
    }

我从this question获得了这个答案和示例。