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:
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?
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;
}
}
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.