using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.ComponentModel; using System.Windows; using System.Windows.Threading; namespace eSuite.WorkBench.WpfHelper { public class SelectableObservableCollection : ObservableCollection { private int _selectedIndex = -1; public T SelectedItem { get { if ((_selectedIndex > -1) && (this.Count > 0)) { return this[_selectedIndex]; } return default(T); } set { if (((_selectedIndex == -1) && (value != null)) || ((this.Count > 0) && !EqualityComparer.Default.Equals(this[_selectedIndex], value))) { int index = IndexOf(value); //if (index == -1) //{ // throw new InvalidOperationException("SelectedItem must be part of the collection"); //} SetSelectedIndex(index); } } } public int SelectedIndex { get { return _selectedIndex; } set { if (_selectedIndex != value) { if (value < -1 || value >= Count) { throw new ArgumentOutOfRangeException(string.Format("Selected index {0} can be in the range of -1 to {1}", _selectedIndex, Count - 1)); } SetSelectedIndex(value); } } } private void SetSelectedIndex(int index) { if (_selectedIndex == index) return; int originalValue = _selectedIndex; bool cancelChange = OnSelectedItemChanging(); _selectedIndex = index; if (cancelChange == false) { Application.Current.Dispatcher.BeginInvoke( new Action(() => { _selectedIndex = originalValue; OnPropertyChanged(new PropertyChangedEventArgs("SelectedItem")); OnPropertyChanged(new PropertyChangedEventArgs("SelectedIndex")); } ), DispatcherPriority.ContextIdle, null ); } else { OnSelectedItemChanged(); OnPropertyChanged(new PropertyChangedEventArgs("SelectedItem")); OnPropertyChanged(new PropertyChangedEventArgs("SelectedIndex")); } } public event CanChangeEventHandler SelectedItemChanging; public event EventHandler SelectedItemChanged; private bool OnSelectedItemChanging() { if (SelectedItemChanging != null) { CanChangeEventArgs canChangeEventArgs = new CanChangeEventArgs(); SelectedItemChanging(this, canChangeEventArgs); return canChangeEventArgs.CanChange; } return true; } private void OnSelectedItemChanged() { if (SelectedItemChanged != null) { SelectedItemChanged(this, EventArgs.Empty); } } public new void Clear() { base.Clear(); SelectedIndex = -1; } } }