Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WPF Single selection between two ListBoxes

I'm having the following problem: I have two ListBox, with two different ItemSource, but both of them have the same binding for the SelectedItem, because I was trying to perform a single selection between these two lists.

Here's an image that better shows the problem:

First list in red. Second list in black.

What would I like to do? Every time I select one item from the first list (in red), it should deselect the SelectedItem from the second list (in black), and vice versa. That's why I'm using the same binding for both of them. I really don't know if it's the better way to do it, but it should work like that.

Could you help me?

like image 983
Guilherme Oliveira Avatar asked Jan 11 '13 11:01

Guilherme Oliveira


2 Answers

Try using SelectedValue instead, this will sop the behaviour you are seeing

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

It seems that SelectedItem does not deselect is the selected item is not found in the list, But SelectedValue does seem to deselect it, not sure why

You can see the diffence in this sample app:

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>

code:

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

like image 72
sa_ddam213 Avatar answered Oct 18 '22 03:10

sa_ddam213


What I had to do was at first pass null to the property and notify the changing, and then I passed the real value to the property and notified the changing to the view. Like that:

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

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

I got this answer and example from this question.

like image 7
Guilherme Oliveira Avatar answered Oct 18 '22 01:10

Guilherme Oliveira