using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Collections.Specialized; using System.ComponentModel; using System.Linq; using System.Runtime.CompilerServices; using System.Xml.Serialization; using Windows.Annotations; namespace Windows { [XmlRoot(Namespace = "urn:widow-windows-schema", ElementName = "Windows")] public class Windows : INotifyPropertyChanged, IDisposable { #region Public Enums, Properties and Fields [XmlElement(ElementName = "Window")] public ObservableCollection Window { get => _window; set { if (Equals(value, _window)) { return; } _window.CollectionChanged -= Window_CollectionChanged; _window.Clear(); _windows.Clear(); foreach (var window in value) { _window.Add(window); var windowHash = new WindowHash(window.Title, window.Class); if (_windows.ContainsKey(windowHash)) { continue; } _windows.Add(windowHash, window); } _window.CollectionChanged += Window_CollectionChanged; OnPropertyChanged(); } } #endregion #region Private Delegates, Events, Enums, Properties, Indexers and Fields private readonly ObservableCollection _window = new ObservableCollection(); private readonly Dictionary _windows = new Dictionary(); #endregion #region Constructors, Destructors and Finalizers [UsedImplicitly] public Windows() { _window.CollectionChanged += Window_CollectionChanged; } public void Dispose() { Window.CollectionChanged -= Window_CollectionChanged; } #endregion #region Interface public event PropertyChangedEventHandler PropertyChanged; #endregion #region Event Handlers private void Window_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e) { if (e.OldItems != null) { foreach (var window in e.OldItems.OfType()) { var windowHash = new WindowHash(window.Title, window.Class); if (_windows.ContainsKey(windowHash)) { _windows.Remove(windowHash); } } } if (e.NewItems != null) { foreach (var window in e.NewItems.OfType()) { var windowHash = new WindowHash(window.Title, window.Class); if (!_windows.ContainsKey(windowHash)) { _windows.Add(windowHash, window); } } } } #endregion #region Public Methods public bool TryGetWindow(WindowHash hash, out Window window) { return _windows.TryGetValue(hash, out window); } #endregion #region Private Methods [NotifyPropertyChangedInvocator] protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } #endregion } }