OK, this must be a duplicate question, but I cannot find the answer: I have a listbox that is databound to a Collection. By default Items[0] is selected. How can I prevent this in order to ensure that the SelectionChanged event is raised any time I click a ListBoxItem?
EDIT: I had already dismissed the SelectedIndex=-1 route, but I tried again: Setting the SelectedIndex to -1 in the Listbox's constructor (or as an attribute in XAML) does not work. It seems that the listbox is populated after the initialization and the selectedindex will become 0 after all.Same story for setting the SelectedItem to null;
I tried this:
<ListBox ItemsSource="{Binding Value}"
SelectionChanged="ListBox_SelectionChanged"
IsSynchronizedWithCurrentItem="True"
Loaded="ListBox_Loaded">
</ListBox>
with:
private void ListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if(e.AddedItems.Count==0)return;//Prevents stackoverflow! ;-)
((ListBox)e.OriginalSource).SelectedItem=null;
}
private void ListBox_Loaded(object sender, RoutedEventArgs e)
{
((ListBox) sender).SelectedItem = null;
}
This works, BUT it inserts a blank line on top of the items that the listbox displays, which is very ugly.... In my particular case I could solve the problem by removing the IsSynchronizedWithCurrentItem attribute.
But I can think of many scenarios in which this would not be acceptable.
The above statement is nonsense: either you want to make use of master-detail binding and set the IsSynchronizedWithCurrentItem to true, or you don't. It is rather unlikely that you want to make use of master-detail binding and then have no currently selected item in your listbox all the time
Use CollectionView as an ItemsSource for your list box. A fresh WPF project with no item initially selected:
XAML:
<Window x:Class="ListBoxDataBinding.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300">
<Grid>
<ListBox
ItemsSource="{Binding Path=Value, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Window}}}"
SelectionChanged="ListBox_SelectionChanged"
IsSynchronizedWithCurrentItem="True"
>
</ListBox>
</Grid>
</Window>
cs:
public partial class Window1: Window {
public IEnumerable Value {
get { return (IEnumerable)GetValue(ValueProperty); }
set { SetValue(ValueProperty, value); }
}
public static readonly DependencyProperty ValueProperty =
DependencyProperty.Register("Value", typeof(IEnumerable), typeof(Window1), new UIPropertyMetadata(null));
public Window1() {
InitializeComponent();
var view = new TheCollectionView();
view.MoveCurrentTo(null);
this.Value = view;
}
private void ListBox_SelectionChanged(object sender, SelectionChangedEventArgs e) {
MessageBox.Show("Selection changed");
}
}
public class TheCollectionView: CollectionView {
public TheCollectionView(): base(new TheCollection()) {
}
}
public class TheCollection: List<string> {
public TheCollection() {
Add("string1");
Add("string2");
Add("string3");
}
}