mirror of
https://github.com/chibicitiberiu/rainmeter-studio.git
synced 2024-02-24 04:33:31 +00:00
Implemented missing observable dictionary
This commit is contained in:
parent
db366ef396
commit
180e4bb9fd
@ -47,6 +47,7 @@
|
||||
<Reference Include="WindowsBase" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Editor\Features\ToolboxItem.cs" />
|
||||
<Compile Include="Model\IProjectTemplate.cs" />
|
||||
<Compile Include="RainmeterStudioPluginAttribute.cs" />
|
||||
<Compile Include="PluginExportAttribute.cs" />
|
||||
@ -70,9 +71,11 @@
|
||||
<Compile Include="Utils\InputHelper.cs" />
|
||||
<Compile Include="Utils\LinqExtension.cs" />
|
||||
<Compile Include="Utils\BitmapHelper.cs" />
|
||||
<Compile Include="Utils\ObservableDictionary.cs" />
|
||||
<Compile Include="Utils\PathHelper.cs" />
|
||||
<Compile Include="Utils\Version.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup />
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
|
321
RainmeterStudio.Core/Utils/ObservableDictionary.cs
Normal file
321
RainmeterStudio.Core/Utils/ObservableDictionary.cs
Normal file
@ -0,0 +1,321 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Specialized;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace RainmeterStudio.Core.Utils
|
||||
{
|
||||
public class ObservableDictionary<TKey, TValue> : IDictionary<TKey, TValue>, INotifyCollectionChanged, INotifyPropertyChanged
|
||||
{
|
||||
private Dictionary<TKey, TValue> _dict;
|
||||
|
||||
#region Events
|
||||
|
||||
/// <summary>
|
||||
/// Triggered when the items of the collection change
|
||||
/// </summary>
|
||||
public event NotifyCollectionChangedEventHandler CollectionChanged;
|
||||
|
||||
/// <summary>
|
||||
/// Triggered when a property changes
|
||||
/// </summary>
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the System.Collections.Generic.Dictionary<TKey,TValue>
|
||||
/// class that is empty, has the default initial capacity, and uses the default
|
||||
/// equality comparer for the key type.
|
||||
/// </summary>
|
||||
public ObservableDictionary()
|
||||
{
|
||||
_dict = new Dictionary<TKey,TValue>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the System.Collections.Generic.Dictionary<TKey,TValue>
|
||||
/// class that contains elements copied from the specified System.Collections.Generic.IDictionary<TKey,TValue>
|
||||
/// and uses the default equality comparer for the key type.
|
||||
/// </summary>
|
||||
/// <param name="dictionary">
|
||||
/// The System.Collections.Generic.IDictionary<TKey,TValue> whose elements are
|
||||
/// copied to the new System.Collections.Generic.Dictionary<TKey,TValue>.
|
||||
/// </param>
|
||||
/// <exception cref="System.ArgumentNullException">dictionary is null</exception>
|
||||
/// <exception cref="System.ArgumentException">dictionary contains one or more duplicate keys</exception>
|
||||
public ObservableDictionary(IDictionary<TKey, TValue> dictionary)
|
||||
{
|
||||
_dict = new Dictionary<TKey,TValue>(dictionary);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the System.Collections.Generic.Dictionary<TKey,TValue>
|
||||
/// class that is empty, has the default initial capacity, and uses the specified
|
||||
/// System.Collections.Generic.IEqualityComparer<TKey>.
|
||||
/// </summary>
|
||||
/// <param name="comparer">
|
||||
/// The System.Collections.Generic.IEqualityComparer<TKey> implementation to use
|
||||
/// when comparing keys, or null to use the default System.Collections.Generic.EqualityComparer<TKey>
|
||||
/// for the type of the key
|
||||
/// </param>
|
||||
public ObservableDictionary(IEqualityComparer<TKey> comparer)
|
||||
{
|
||||
_dict = new Dictionary<TKey, TValue>(comparer);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the System.Collections.Generic.Dictionary<TKey,TValue>
|
||||
/// class that is empty, has the specified initial capacity, and uses the default
|
||||
/// equality comparer for the key type.
|
||||
/// </summary>
|
||||
/// <param name="capacity">
|
||||
/// The initial number of elements that the System.Collections.Generic.Dictionary<TKey,TValue>
|
||||
/// can contain.
|
||||
/// </param>
|
||||
/// <exception cref="System.ArgumentOutOfRangeException">capacity is less than 0</exception>
|
||||
public ObservableDictionary(int capacity)
|
||||
{
|
||||
_dict = new Dictionary<TKey, TValue>(capacity);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the System.Collections.Generic.Dictionary<TKey,TValue>
|
||||
/// class that contains elements copied from the specified System.Collections.Generic.IDictionary<TKey,TValue>
|
||||
/// and uses the specified System.Collections.Generic.IEqualityComparer<TKey>.
|
||||
/// </summary>
|
||||
/// <param name="dictionary">
|
||||
/// The System.Collections.Generic.IDictionary<TKey,TValue> whose elements are
|
||||
/// copied to the new System.Collections.Generic.Dictionary<TKey,TValue>.
|
||||
/// </param>
|
||||
/// <param name="comparer">
|
||||
/// The System.Collections.Generic.IEqualityComparer<TKey> implementation to use
|
||||
/// when comparing keys, or null to use the default System.Collections.Generic.EqualityComparer<TKey>
|
||||
/// for the type of the key.
|
||||
/// </param>
|
||||
/// <exception cref="System.ArgumentNullException">dictionary is null</exception>
|
||||
/// <exception cref="System.ArgumentException">dictionary contains one or more duplicate keys</exception>
|
||||
public ObservableDictionary(IDictionary<TKey, TValue> dictionary, IEqualityComparer<TKey> comparer)
|
||||
{
|
||||
_dict = new Dictionary<TKey, TValue>(dictionary, comparer);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the System.Collections.Generic.Dictionary<TKey,TValue>
|
||||
/// class that is empty, has the specified initial capacity, and uses the specified
|
||||
/// System.Collections.Generic.IEqualityComparer<TKey>.
|
||||
/// </summary>
|
||||
/// <param name="capacity">
|
||||
/// The initial number of elements that the System.Collections.Generic.Dictionary<TKey,TValue>
|
||||
/// can contain.
|
||||
/// </param>
|
||||
/// <param name="comparer">
|
||||
/// The System.Collections.Generic.IEqualityComparer<TKey> implementation to use
|
||||
/// when comparing keys, or null to use the default System.Collections.Generic.EqualityComparer<TKey>
|
||||
/// for the type of the key.
|
||||
/// </param>
|
||||
/// <exception cref="System.ArgumentOutOfRangeException">capacity is less than 0</exception>
|
||||
public ObservableDictionary(int capacity, IEqualityComparer<TKey> comparer)
|
||||
{
|
||||
_dict = new Dictionary<TKey, TValue>(capacity, comparer);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IDictionary<TKey, TValue>
|
||||
|
||||
/// <summary>
|
||||
/// Gets the number of key/value pairs contained in the dictionary.
|
||||
/// </summary>
|
||||
public int Count
|
||||
{
|
||||
get { return _dict.Count; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a collection containing the keys in the dictionary.
|
||||
/// </summary>
|
||||
public ICollection<TKey> Keys
|
||||
{
|
||||
get { return _dict.Keys; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a collection containing the values in the dictionary.
|
||||
/// </summary>
|
||||
public ICollection<TValue> Values
|
||||
{
|
||||
get { return _dict.Values; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the value associated with the specified key.
|
||||
/// </summary>
|
||||
/// <param name="key">The key of the value to get or set</param>
|
||||
/// <returns>
|
||||
/// The value associated with the specified key. If the specified key is not
|
||||
/// found, a get operation throws a <see cref="System.Collections.Generic.KeyNotFoundException"/>,
|
||||
/// and a set operation creates a new element with the specified key.
|
||||
/// </returns>
|
||||
/// <exception cref="System.ArgumentNullException">key is null</exception>
|
||||
/// <exception cref="System.Collections.Generic.KeyNotFoundException">The property is retrieved and key does not exist in the collection.</exception>
|
||||
public TValue this[TKey key]
|
||||
{
|
||||
get
|
||||
{
|
||||
return _dict[key];
|
||||
}
|
||||
set
|
||||
{
|
||||
TValue oldValue;
|
||||
TryGetValue(key, out oldValue);
|
||||
|
||||
_dict[key] = value;
|
||||
|
||||
if (CollectionChanged != null)
|
||||
CollectionChanged(this, new NotifyCollectionChangedEventArgs(
|
||||
NotifyCollectionChangedAction.Replace,
|
||||
new KeyValuePair<TKey, TValue>(key, oldValue),
|
||||
new KeyValuePair<TKey, TValue>(key, value)));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds the specified key and value to the dictionary.
|
||||
/// </summary>
|
||||
/// <param name="key">The key of the element to add</param>
|
||||
/// <param name="value">The value of the element to add. The value can be null for reference types.</param>
|
||||
/// <exception cref="System.ArgumentNullException">key is null</exception>
|
||||
/// <exception cref="System.ArgumentException">An element with the same key already exists in the dictionary.</exception>
|
||||
public void Add(TKey key, TValue value)
|
||||
{
|
||||
_dict.Add(key, value);
|
||||
|
||||
if (CollectionChanged != null)
|
||||
CollectionChanged(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, new KeyValuePair<TKey, TValue>(key, value), null));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes all keys and values from the dictionary.
|
||||
/// </summary>
|
||||
public void Clear()
|
||||
{
|
||||
_dict.Clear();
|
||||
|
||||
if (CollectionChanged != null)
|
||||
CollectionChanged(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the dictionary contains the specified key.
|
||||
/// </summary>
|
||||
/// <param name="key">The key to locate in the dictionary</param>
|
||||
/// <returns>true if the dictionary contains an element with the specified key; otherwise, false.</returns>
|
||||
/// <exception cref="System.ArgumentNullException">key is null</exception>
|
||||
public bool ContainsKey(TKey key)
|
||||
{
|
||||
return _dict.ContainsKey(key);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes the value with the specified key from the dictionary.
|
||||
/// </summary>
|
||||
/// <param name="key">The key of the element to remove</param>
|
||||
/// <returns>
|
||||
/// true if the element is successfully found and removed; otherwise, false.
|
||||
/// This method returns false if key is not found in the dictionary.
|
||||
/// </returns>
|
||||
/// <exception cref="System.ArgumentNullException">key is null</exception>
|
||||
public bool Remove(TKey key)
|
||||
{
|
||||
TValue oldValue;
|
||||
_dict.TryGetValue(key, out oldValue);
|
||||
|
||||
bool res = _dict.Remove(key);
|
||||
|
||||
if (res && CollectionChanged != null)
|
||||
CollectionChanged(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, new KeyValuePair<TKey, TValue>(key, oldValue)));
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the value associated with the specified key.
|
||||
/// </summary>
|
||||
/// <param name="key">The key of the value to get</param>
|
||||
/// <param name="value">
|
||||
/// When this method returns, contains the value associated with the specified
|
||||
/// key, if the key is found; otherwise, the default value for the type of the
|
||||
/// value parameter. This parameter is passed uninitialized.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// true if the dictionary contains an element with the specified key;
|
||||
/// otherwise, false.
|
||||
/// </returns>
|
||||
/// <exception cref="System.ArgumentNullException">key is null</exception>
|
||||
public bool TryGetValue(TKey key, out TValue value)
|
||||
{
|
||||
return _dict.TryGetValue(key, out value);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ICollection<KeyValuePair<TKey, TValue>>
|
||||
|
||||
void ICollection<KeyValuePair<TKey, TValue>>.Add(KeyValuePair<TKey, TValue> item)
|
||||
{
|
||||
((ICollection<KeyValuePair<TKey, TValue>>)_dict).Add(item);
|
||||
|
||||
if (CollectionChanged != null)
|
||||
CollectionChanged(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, item, null));
|
||||
}
|
||||
|
||||
bool ICollection<KeyValuePair<TKey, TValue>>.Contains(KeyValuePair<TKey, TValue> item)
|
||||
{
|
||||
return ((ICollection<KeyValuePair<TKey, TValue>>)_dict).Contains(item);
|
||||
}
|
||||
|
||||
void ICollection<KeyValuePair<TKey, TValue>>.CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex)
|
||||
{
|
||||
((ICollection<KeyValuePair<TKey, TValue>>)_dict).CopyTo(array, arrayIndex);
|
||||
}
|
||||
|
||||
bool ICollection<KeyValuePair<TKey, TValue>>.IsReadOnly
|
||||
{
|
||||
get { return ((ICollection<KeyValuePair<TKey, TValue>>)_dict).IsReadOnly; }
|
||||
}
|
||||
|
||||
bool ICollection<KeyValuePair<TKey, TValue>>.Remove(KeyValuePair<TKey, TValue> item)
|
||||
{
|
||||
bool res = ((ICollection<KeyValuePair<TKey, TValue>>)_dict).Remove(item);
|
||||
|
||||
if (res && CollectionChanged != null)
|
||||
CollectionChanged(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, item));
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IEnumerable
|
||||
|
||||
public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator()
|
||||
{
|
||||
return _dict.GetEnumerator();
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
{
|
||||
return ((IEnumerable)_dict).GetEnumerator();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
@ -72,14 +72,11 @@ EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RainmeterStudio", "RainmeterStudio\RainmeterStudio.csproj", "{438D0136-4A27-4E4D-A617-FFACE4554236}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{9A644478-2F1B-4145-8B31-6F8DBD42EC38} = {9A644478-2F1B-4145-8B31-6F8DBD42EC38}
|
||||
{E8BD25E9-3055-4688-9E83-ECF684EF30C6} = {E8BD25E9-3055-4688-9E83-ECF684EF30C6}
|
||||
{C641D7F8-DDDC-4EC6-8F5E-233520290642} = {C641D7F8-DDDC-4EC6-8F5E-233520290642}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RainmeterStudio.Tests", "RainmeterStudio.Tests\RainmeterStudio.Tests.csproj", "{845F4BD4-6822-4D92-9DDB-15FD18A47E5A}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RainmeterStudio.SkinDesignerPlugin", "RainmeterStudio.SkinDesigner\RainmeterStudio.SkinDesignerPlugin.csproj", "{E8BD25E9-3055-4688-9E83-ECF684EF30C6}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RainmeterStudio.Core", "RainmeterStudio.Core\RainmeterStudio.Core.csproj", "{1D2A4896-AF31-4E82-A84F-4E218067701F}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RainmeterStudio.TextEditorPlugin", "RainmeterStudio.TextEditor\RainmeterStudio.TextEditorPlugin.csproj", "{9A644478-2F1B-4145-8B31-6F8DBD42EC38}"
|
||||
@ -532,18 +529,6 @@ Global
|
||||
{845F4BD4-6822-4D92-9DDB-15FD18A47E5A}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
||||
{845F4BD4-6822-4D92-9DDB-15FD18A47E5A}.Release|Win32.ActiveCfg = Release|Any CPU
|
||||
{845F4BD4-6822-4D92-9DDB-15FD18A47E5A}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{E8BD25E9-3055-4688-9E83-ECF684EF30C6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{E8BD25E9-3055-4688-9E83-ECF684EF30C6}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{E8BD25E9-3055-4688-9E83-ECF684EF30C6}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
||||
{E8BD25E9-3055-4688-9E83-ECF684EF30C6}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
|
||||
{E8BD25E9-3055-4688-9E83-ECF684EF30C6}.Debug|Win32.ActiveCfg = Debug|Any CPU
|
||||
{E8BD25E9-3055-4688-9E83-ECF684EF30C6}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{E8BD25E9-3055-4688-9E83-ECF684EF30C6}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{E8BD25E9-3055-4688-9E83-ECF684EF30C6}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{E8BD25E9-3055-4688-9E83-ECF684EF30C6}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||
{E8BD25E9-3055-4688-9E83-ECF684EF30C6}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
||||
{E8BD25E9-3055-4688-9E83-ECF684EF30C6}.Release|Win32.ActiveCfg = Release|Any CPU
|
||||
{E8BD25E9-3055-4688-9E83-ECF684EF30C6}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{1D2A4896-AF31-4E82-A84F-4E218067701F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{1D2A4896-AF31-4E82-A84F-4E218067701F}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{1D2A4896-AF31-4E82-A84F-4E218067701F}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
||||
@ -617,6 +602,5 @@ Global
|
||||
{EE8EC522-8430-4B46-86A3-D943D77F9E4B} = {53D952E0-CFD2-4EFF-BAD4-5969E760EFA1}
|
||||
{845F4BD4-6822-4D92-9DDB-15FD18A47E5A} = {8469BE7E-BCDB-4AA8-9541-719E8BFB19A7}
|
||||
{9A644478-2F1B-4145-8B31-6F8DBD42EC38} = {4CCE6052-F43E-4360-B3E2-C046C6C0D86C}
|
||||
{E8BD25E9-3055-4688-9E83-ECF684EF30C6} = {4CCE6052-F43E-4360-B3E2-C046C6C0D86C}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
Loading…
Reference in New Issue
Block a user