WPF两个ListBox之间的单一选择

12
我有一个问题:我有两个 ListBox,它们有两个不同的 ItemSource,但它们都有相同的绑定 SelectedItem,因为我试图在这两个列表之间执行单一选择。
下面是更好地展示问题的图片:

First list in red. Second list in black.

我想做什么?每次从第一个列表(红色)中选择一个项目,它都应该取消选择第二个列表(黑色)中的SelectedItem,反之亦然。这就是为什么我同时使用相同的binding

我真的不知道这是否是更好的方法,但它应该像这样工作。

你能帮我吗?


我认为你应该使用自定义附加行为。 - Felice Pollano
@FelicePollano 但是我该怎么做呢?你有一些代码可以帮忙吗? - Guilherme Oliveira
1
这与这类问题有点相关 https://dev59.com/H1LTa4cB1Zd3GeqPYTiu - dowhilefor
@dowhilefor 我会检查这个问题并看看它是否有效。 - Guilherme Oliveira
@Clemens 类型是“Version”,它是我的自定义类之一。 - Guilherme Oliveira
2个回答

20
尝试使用 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;
    }
}

这里输入图片描述


我尝试使用SelectedValue,但它没有起作用。我认为这是因为我在属性设置内调用了另一个方法,该方法需要与null不同的值,如果我使用SelectedValue,它会尝试将null设置为我的属性。我不知道我是否清楚地表达了这个评论。 - Guilherme Oliveira
这个可以工作,但现在我开始思考为什么我需要SelectedItem呢?! - mkb

7

我所要做的是首先将null传递给属性并通知更改,然后将实际值传递给属性并通知视图更改。

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

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

我从这个问题中得到了以下答案和示例。


1
这个修复非常有效。简单但是可行。唯一我能想到可能出错的事情是当另一个线程在被设置为null的时候尝试访问SelectedItem。 - Tom Stein

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接