How to ensure that no item is selected in databound ListBox?
.net, listbox, selecteditem, wpf
Solution
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");
}
}
Problem
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