created a new generic collection type for getting updates on property changes for items within a collection

This commit is contained in:
David Sparer
2017-01-20 12:25:18 -07:00
parent d749a13611
commit 172232be48
4 changed files with 158 additions and 0 deletions

View File

@@ -0,0 +1,61 @@
using mRemoteNG.Credential;
using mRemoteNG.Tools;
using NUnit.Framework;
namespace mRemoteNGTests.Tools
{
public class ObservablePropertyCollectionTests
{
private ObservablePropertyCollection<CredentialRecord> _collection;
[SetUp]
public void Setup()
{
_collection = new ObservablePropertyCollection<CredentialRecord>();
}
[Test]
public void WrapsAnExistingList()
{
_collection = new ObservablePropertyCollection<CredentialRecord>(new[] {new CredentialRecord()});
Assert.That(_collection.Count, Is.EqualTo(1));
}
[Test]
public void AddHooksIntoMemberProperty()
{
var wasRaised = false;
_collection.PropertyChanged += (sender, args) => { wasRaised = true; };
var newItem = new CredentialRecord();
_collection.Add(newItem);
newItem.Title = "something";
Assert.That(wasRaised);
}
[Test]
public void CanClearList()
{
var newItem = new CredentialRecord();
_collection.Add(newItem);
_collection.Clear();
Assert.That(_collection.Count, Is.EqualTo(0));
}
[Test]
public void ContainsTrue()
{
var newItem = new CredentialRecord();
_collection.Add(newItem);
Assert.That(_collection.Contains(newItem), Is.True);
}
[Test]
public void ContainsFalse()
{
var newItem = new CredentialRecord();
_collection.Add(newItem);
Assert.That(_collection.Contains(new CredentialRecord()), Is.False);
}
}
}

View File

@@ -137,6 +137,7 @@
<Compile Include="Security\KeyDerivation\Pkcs5S2KeyGeneratorTests.cs" />
<Compile Include="Security\SecureStringExtensionsTests.cs" />
<Compile Include="Tools\ExternalToolsArgumentParserTests.cs" />
<Compile Include="Tools\ObservablePropertyCollectionTests.cs" />
<Compile Include="Tree\ClickHandlers\TreeNodeCompositeClickHandlerTests.cs" />
<Compile Include="Tree\ConnectionTreeDragAndDropHandlerTests.cs" />
<Compile Include="Tree\ConnectionTreeModelTests.cs" />

View File

@@ -0,0 +1,95 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.ComponentModel;
namespace mRemoteNG.Tools
{
public class ObservablePropertyCollection<T> : IList<T>, INotifyCollectionChanged, INotifyPropertyChanged
where T : INotifyPropertyChanged
{
private readonly ObservableCollection<T> _collection = new ObservableCollection<T>();
public int Count => _collection.Count;
public bool IsReadOnly { get; }
public T this[int index]
{
get { return _collection[index]; }
set { _collection[index] = value; }
}
public ObservablePropertyCollection()
{
_collection.CollectionChanged += RaiseCollectionChangedEvent;
}
public ObservablePropertyCollection(IEnumerable<T> list)
{
if (list == null)
throw new ArgumentNullException(nameof(list));
foreach(var item in list)
Add(item);
_collection.CollectionChanged += RaiseCollectionChangedEvent;
}
public void Add(T item)
{
if (_collection.Contains(item)) return;
_collection.Add(item);
item.PropertyChanged += RaisePropertyChangedEvent;
}
public void Insert(int index, T item)
{
if (_collection.Contains(item)) return;
_collection.Insert(index, item);
item.PropertyChanged += RaisePropertyChangedEvent;
}
public bool Remove(T item)
{
if (!_collection.Contains(item)) return false;
item.PropertyChanged -= RaisePropertyChangedEvent;
return _collection.Remove(item);
}
public void RemoveAt(int index)
{
var removalTarget = _collection[index];
if (removalTarget == null) return;
_collection.Remove(removalTarget);
}
public void Clear()
{
foreach (var item in _collection)
item.PropertyChanged -= RaisePropertyChangedEvent;
_collection.Clear();
}
public IEnumerator<T> GetEnumerator() => _collection.GetEnumerator();
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
public bool Contains(T item) => _collection.Contains(item);
public void CopyTo(T[] array, int arrayIndex) => _collection.CopyTo(array, arrayIndex);
public int IndexOf(T item) => _collection.IndexOf(item);
public event NotifyCollectionChangedEventHandler CollectionChanged;
public event PropertyChangedEventHandler PropertyChanged;
private void RaiseCollectionChangedEvent(object sender, NotifyCollectionChangedEventArgs args)
{
CollectionChanged?.Invoke(this, args);
}
private void RaisePropertyChangedEvent(object sender, PropertyChangedEventArgs propertyChangedEventArgs)
{
PropertyChanged?.Invoke(sender, propertyChangedEventArgs);
}
}
}

View File

@@ -224,6 +224,7 @@
<Compile Include="Tools\CmdArgumentsInterpreter.cs" />
<Compile Include="Tools\ConnectionsTreeToMenuItemsConverter.cs" />
<Compile Include="Tools\ExternalToolsTypeConverter.cs" />
<Compile Include="Tools\ObservablePropertyCollection.cs" />
<Compile Include="Tools\ScanHost.cs" />
<Compile Include="Tools\SecureTransfer.cs" />
<Compile Include="Tree\AlwaysConfirmYes.cs" />